link411 link412 link413 link414 link415 link416 link417 link418 link419 link420 link421 link422 link423 link424 link425 link426 link427 link428 link429 link430 link431 link432 link433 link434 link435 link436 link437 link438 link439 link440 link441 link442 link443 link444 link445 link446 link447 link448 link449 link450 link451 link452 link453 link454 link455 link456 link457 link458 link459 link460 link461 link462 link463 link464 link465 link466 link467 link468 link469 link470 link471 link472 link473 link474 link475 link476 link477 link478 link479 link480 link481 link482 link483 link484 link485 link486 link487 link488 link489 link490 link491 link492 link493 link494 link495 link496 link497 link498 link499 link500 link501 link502 link503 link504 link505 link506 link507 link508 link509 link510 link511 link512 link513 link514 link515 link516 link517 link518 link519 link520 link521 link522 link523 link524 link525 link526 link527 link528 link529 link530 link531 link532 link533 link534 link535 link536 link537 link538 link539 link540 link541 link542 link543 link544 link545 link546 link547

[Vue.js] Multiple Vue components inside Main component Subscribe to RSS

What is the correct way to dynamically insert any number of sub components inside the main ‘wrapper’ component?

Something like this:

Main Parent component:

<template>
<div id=”app”>
<GridContainer v-for=”item in items”>
<GridItem />
</GridContainer>
</div>
</template>

<script>
import { GridContainer, GridItem } from ‘Grid’;

export default {
name: ‘app’,
components: {
GridContainer,
GridItem
},
data() {
return {
items: […array if items that are dynamic]
};
};
}
</script>

Solution :

do v-for on the component, not the wrapper. Like this

the IDE may also warn you that you’re missing a key, easiest way to add key is to use index (but it comes with some caveats). Also, you probably want to pass the items into the component. If you have a prop called item, you’d pass it with :item=”item”

<template>
<div id=”app”>
<GridContainer>
<GridItem v-for=”(item, k) in items” :key=”k” :item=”item”/>
</GridContainer>
</div>
</template>

<script>
import { GridContainer, GridItem } from ‘Grid’;

export default {
name: ‘app’,
components: {
GridContainer,
GridItem
},
data() {
return {
items: […array if items that are dynamic]
};
};
}
</script>

[Vue.js] v-toolbar not behaving responsively Subscribe to RSS

when trying to implement vuetify in my project. when newbie in VueJs & vuetify too.

when trying to use a toolbar which contains a rounded image on the right corner. But, It is not responsive. When i open developer option and decrease the screen size to that of mobile. The rounded image does not render.

I tried using plain tags but it is actually disrupting the layout.

Here is the code
VuetifyTest.vue:

<template lang=”html”>
<v-toolbar>
<v-toolbar-side-icon>
<!– <v-img src=”../assets/mad_logo.png” aspect-ratio=”1.7”></v-img> –>
</v-toolbar-side-icon>
<v-toolbar-title>Title</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items class=”hidden-sm-and-down”>
<v-layout
align-center
justify-space-around
wrap
\>
<v-avatar
:tile= false
size=”36”
color=”grey lighten-4”
\>
<img src=”../assets/static.jpeg” alt=”avatar”>
</v-avatar>
</v-layout>
</v-toolbar-items>
</v-toolbar>

</template>

<script lang=”js”>
export default {
name: ‘VuetifyTest’,
props: [],
mounted() {

},
data() {
return {

}
},
methods: {

},
computed: {

}
}
</script>

<style scoped >

</style>

This is how it looks like in laptop screen

This is how it looks like in mobile screen

How do i change the code to make it responsive

PS: I also tried reducing the screen size while viewing here in reduced screen size.
Even though it showed like this..

Even though the official documentation have this problem?
How do i make it responsive..

thanks!

Solution :

You do not have to specify v-layout within the v-toolbar - if you remove the v-layout and replace it with just the v-avatar, it works.. Examples are below:

[CodePen Mirror]

Snippet:

new Vue({ el: “#app” })
<script src=”https://unpkg.com/vue/dist/vue.js"></script>
<script src=”https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href=”https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons" rel=”stylesheet” />
<link href=”https://unpkg.com/vuetify/dist/vuetify.min.css" rel=”stylesheet” />

<div id=”app”>
<v-app>
<v-toolbar>
<v-toolbar-side-icon>
</v-toolbar-side-icon>
<v-toolbar-title>Title</v-toolbar-title>
<v-spacer></v-spacer>
<v-avatar :tile=false size=”36” color=”grey lighten-4”>
<img src=”https://i.pravatar.cc/300?img=3" alt=”avatar”>
</v-avatar>
</v-toolbar>
</v-app>
</div>

[Vue.js] How to deploy my VueCLI application on a Noje.js Server (Express)? Subscribe to RSS

there is build my project website with VueCLI so now to deploy my app on my server Node.js.
The problem is :
- When I run the command build to get the dist folder and place it into my nodejs server i cant use my vue.js router because when for example :http://server.com/page1 it make a request to the server but i only want to get access to the page in the app with vue.js router.

‘This is a single page website using vue.js router’

My node.js server example :

const express = require(‘express’);
const path = require(‘path’);
const app = express();

app.use(‘/static’, express.static(path.join(__dirname, ‘/dist’)))

app.get(‘/‘,(req,res)=>{
res.sendFile(__dirname+’/static/index.html’)
})

app.listen(‘3000’,()=>{
console.log(“listen on port 3000”);
})

/site.com
/site.com/dist
/site.com/dist/css
/site.com/dist/js
/site.com/dist/index.html
/site.com/index.js //server nodejs

to be able to get access to the internal pages of my vue.js router website.
For the moment when im asking in the url for a page it ask the server.

Solution :

This is a project organization issue. I would advice you generate the dist outside the app. and have

app.use(‘/static’, express.static(path.join(__dirname, ‘/static’)))

Point to dist instead of static i.e.

app.use(‘/static’, express.static(path.join(__dirname, ‘/path/to/dist’)))

Solution 2:

So apparently to solve my problem there is to install and configure a
Middleware call “connect-history-api-fallback” from github
https://github.com/bripkens/connect-history-api-fallback'. This API
is only for a server running on Node.js and using express (this is my
case).

But if you want to configure the server nginx,apache … All you
need to do is found the conf on the official web page
https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations'.

Hope this will help you =)

[Vue.js] How to access the correct `this` inside a callback?1. Use bind() function2 Store reference to context/this inside another variable3 Arrow function Subscribe to RSS

there is a constructor function which registers an event handler:

function MyConstructor(data, transport) {
this.data = data;
transport.on(‘data’, function () {
alert(this.data);
});
}

// Mock transport object
var transport = {
on: function(event, callback) {
setTimeout(callback, 1000);
}
};

// called as
var obj = new MyConstructor(‘foo’, transport);

However, I’m not able to access the data property of the created object inside the callback. It looks like this does not refer to the object that was created but to an other one.

I also tried to use an object method instead of an anonymous function:

function MyConstructor(data, transport) {
this.data = data;
transport.on(‘data’, this.alert);
}

MyConstructor.prototype.alert = function() {
alert(this.name);
};

but it exhibits the same problems.

How can I access the correct object?

Solution :

What you should know about this

this (aka “the context”) is a special keyword inside each function and its value only depends on how the function was called, not how/when/where it was defined. It is not affected by lexical scopes like other variables (except for arrow functions, see below). Here are some examples:

function foo() {
console.log(this);
}

// normal function call
foo(); // `this` will refer to `window`

// as object method
var obj = {bar: foo};
obj.bar(); // `this` will refer to `obj`

// as constructor function
new foo(); // `this` will refer to an object that inherits from `foo.prototype`

To learn more about this, have a look at the MDN documentation.

How to refer to the correct this

Don’t use this

You actually don’t want to access this in particular, but the object it refers to. That’s why an easy solution is to simply create a new variable that also refers to that object. The variable can have any name, but common ones are self and that.

function MyConstructor(data, transport) {
this.data = data;
var self = this;
transport.on(‘data’, function() {
alert(self.data);
});
}

Since self is a normal variable, it obeys lexical scope rules and is accessible inside the callback. This also has the advantage that you can access the this value of the callback itself.

Explicitly set this of the callback - part 1

It might look like you have no control over the value of this because its value is set automatically, but that is actually not the case.

Every function has the method .bind [docs], which returns a new function with this bound to a value. The function has exactly the same behaviour as the one you called .bind on, only that this was set by you. No matter how or when that function is called, this will always refer to the passed value.

function MyConstructor(data, transport) {
this.data = data;
var boundFunction = (function() { // parenthesis are not necessary
alert(this.data); // but might improve readability
}).bind(this); // <- here we are calling `.bind()`
transport.on(‘data’, boundFunction);
}

In this case, we are binding the callback’s this to the value of MyConstructor’s this.

Note: When binding context for jQuery, use jQuery.proxy [docs] instead. The reason to do this is so that you don’t need to store the reference to the function when unbinding an event callback. jQuery handles that internally.

ECMAScript 6: Use arrow functions

ECMAScript 6 introduces arrow functions, which can be thought of as lambda functions. They don’t have their own this binding. Instead, this is looked up in scope just like a normal variable. That means you don’t have to call .bind. That’s not the only special behaviour they have, please refer to the MDN documentation for more information.

function MyConstructor(data, transport) {
this.data = data;
transport.on(‘data’, () => alert(this.data));
}

Set this of the callback - part 2

Some functions/methods which accept callbacks also accept a value to which the callback’s this should refer to. This is basically the same as binding it yourself, but the function/method does it for you. Array#map [docs] is such a method. Its signature is:

array.map(callback[, thisArg])

The first argument is the callback and the second argument is the value this should refer to. Here is a contrived example:

var arr = [1, 2, 3];
var obj = {multiplier: 42};

var new_arr = arr.map(function(v) {
return v * this.multiplier;
}, obj); // <- here we are passing `obj` as second argument

Note: Whether or not you can pass a value for this is usually mentioned in the documentation of that function/method. For example, jQuery’s $.ajax method [docs] describes an option called context:

This object will be made the context of all Ajax-related callbacks.

Common problem: Using object methods as callbacks/event handlers

Another common manifestation of this problem is when an object method is used as callback/event handler. Functions are first-class citizens in JavaScript and the term “method” is just a colloquial term for a function that is a value of an object property. But that function doesn’t have a specific link to its “containing” object.

Consider the following example:

function Foo() {
this.data = 42,
document.body.onclick = this.method;
}

Foo.prototype.method = function() {
console.log(this.data);
};

The function this.method is assigned as click event handler, but if the document.body is clicked, the value logged will be undefined, because inside the event handler, this refers to the document.body, not the instance of Foo.
As already mentioned at the beginning, what this refers to depends on how the function is called, not how it is defined.
If the code was like the following, it might be more obvious that the function doesn’t have an implicit reference to the object:

function method() {
console.log(this.data);
}

function Foo() {
this.data = 42,
document.body.onclick = this.method;
}

Foo.prototype.method = method;

The solution is the same as mentioned above: If available, use .bind to explicitly bind this to a specific value

document.body.onclick = this.method.bind(this);

or explicitly call the function as a “method” of the object, by using an anonymous function as callback / event handler and assign the object (this) to another variable:

var self = this;
document.body.onclick = function() {
self.method();
};

or use an arrow function:

document.body.onclick = () => this.method();

Solution 2:

Here are several ways to access parent context inside child context -

You can use bind() function.
Store reference to context/this inside another variable(see below example).
Use ES6 Arrow functions.
Alter code/function design/architecture - for this you should have command over design patterns in javascript.

1. Use bind() function

function MyConstructor(data, transport) {
this.data = data;
transport.on(‘data’, ( function () {
alert(this.data);
}).bind(this) );
}
// Mock transport object
var transport = {
on: function(event, callback) {
setTimeout(callback, 1000);
}
};
// called as
var obj = new MyConstructor(‘foo’, transport);

If you are using underscore.js - http://underscorejs.org/#bind

transport.on(‘data’, _.bind(function () {
alert(this.data);
}, this));

2 Store reference to context/this inside another variable

function MyConstructor(data, transport) {
var self = this;
this.data = data;
transport.on(‘data’, function() {
alert(self.data);
});
}

3 Arrow function

function MyConstructor(data, transport) {
this.data = data;
transport.on(‘data’, () => {
alert(this.data);
});
}

Solution 3:

It’s all in the “magic” syntax of calling a method:

object.property();

When you get the property from the object and call it in one go, the object will be the context for the method. If you call the same method, but in separate steps, the context is the global scope (window) instead:

var f = object.property;
f();

When you get the reference of a method, it’s no longer attached to the object, it’s just a reference to a plain function. The same happens when you get the reference to use as a callback:

this.saveNextLevelData(this.setAll);

That’s where you would bind the context to the function:

this.saveNextLevelData(this.setAll.bind(this));

If you are using jQuery you should use the $.proxy method instead, as bind is not supported in all browsers:

this.saveNextLevelData($.proxy(this.setAll, this));

Solution 4:

The trouble with “context”

The term “context” is sometimes used to refer to the object referenced by this. Its use is inappropriate because it doesn’t fit either semantically or technically with ECMAScript’s this.

“Context” means the circumstances surrounding something that adds meaning, or some preceding and following information that gives extra meaning. The term “context” is used in ECMAScript to refer to execution context, which is all the parameters, scope and this within the scope of some executing code.

This is shown in ECMA-262 section 10.4.2:

Set the ThisBinding to the same value as the ThisBinding of the
calling execution context

which clearly indicates that this is part of an execution context.

An execution context provides the surrounding information that adds meaning to code that is being executed. It includes much more information than just the thisBinding.

So the value of this isn’t “context”, it’s just one part of an execution context. It’s essentially a local variable that can be set by the call to any object and in strict mode, to any value at all.

Solution 5:

First, you need to have a clear understanding of scope and behaviour of this keyword in the context of scope.

this & scope :

there are two types of scope in javascript. They are :

1) Global Scope

2) Function Scope

in short, global scope refers to the window object.Variables declared in a global scope are accessible from anywhere.On the other hand function scope resides inside of a function.variable declared inside a function cannot be accessed from outside world normally.this keyword in global scope refers to the window object.this inside function also refers to the window object.So this will always refer to the window until we find a way to manipulate this to indicate a context of our own choosing.

-——————————————————————————-
- -
- Global Scope -
- ( globally “this” refers to window object) -
- -
- function outer_function(callback){ -
- -
- // outer function scope -
- // inside outer function”this” keyword refers to window object - -
- callback() // “this” inside callback also refers window object -

- } -
- -
- function callback_function(){ -
- -
- // function to be passed as callback -
- -
- // here “THIS” refers to window object also -
- -
- } -
- -
- outer_function(callback_function) -
- // invoke with callback -
-——————————————————————————-

Different ways to manipulate this inside callback functions:

Here there is a constructor function called Person. It has a property called name and four method called sayNameVersion1,sayNameVersion2,sayNameVersion3,sayNameVersion4. All four of them has one specific task.Accept a callback and invoke it.The callback has a specific task which is to log the name property of an instance of Person constructor function.

function Person(name){

this.name = name

this.sayNameVersion1 = function(callback){
callback.bind(this)()
}
this.sayNameVersion2 = function(callback){
callback()
}

this.sayNameVersion3 = function(callback){
callback.call(this)
}

this.sayNameVersion4 = function(callback){
callback.apply(this)
}

}

function niceCallback(){

// function to be used as callback

var parentObject = this

console.log(parentObject)

}

Now let’s create an instance from person constructor and invoke different versions of sayNameVersionX ( X refers to 1,2,3,4 ) method with niceCallback to see how many ways we can manipulate the this inside callback to refer to the person instance.

var p1 = new Person(‘zami’) // create an instance of Person constructor

bind :

What bind do is to create a new function with the this keyword set to the provided value.

sayNameVersion1 and sayNameVersion2 use bind to manipulate this of the callback function.

this.sayNameVersion1 = function(callback){
callback.bind(this)()
}
this.sayNameVersion2 = function(callback){
callback()
}

first one bind this with callback inside the method itself.And for the second one callback is passed with the object bound to it.

p1.sayNameVersion1(niceCallback) // pass simply the callback and bind happens inside the sayNameVersion1 method

p1.sayNameVersion2(niceCallback.bind(p1)) // uses bind before passing callback

call :

The first argument of the call method is used as this inside the function that is invoked with call attached to it.

sayNameVersion3 uses call to manipulate the this to refer to the person object that we created, instead of the window object.

this.sayNameVersion3 = function(callback){
callback.call(this)
}

and it is called like the following :

p1.sayNameVersion3(niceCallback)

apply :

Similar to call, first argument of apply refers to the object that will be indicated by this keyword.

sayNameVersion4 uses apply to manipulate this to refer to person object

this.sayNameVersion4 = function(callback){
callback.apply(this)
}

and it is called like the following.Simply the callback is passed,

p1.sayNameVersion4(niceCallback)

Solution 6:

We can not bind this to setTimeout(), as it always execute with global object (Window), if you want to access this context in the callback function then by using bind() to the callback function we can achieve as:

setTimeout(function(){
this.methodName();
}.bind(this), 2000);

Solution 7:

You Should know about “this” Keyword.

As per my view you can implement “this” in three ways
(Self/Arrow function/Bind Method)

A function’s this keyword behaves a little differently in JavaScript compared to other languages.

It also has some differences between strict mode and non-strict mode.

In most cases, the value of this is determined by how a function is called.

It can’t be set by assignment during execution, and it may be different each time the function is called.

ES5 introduced the bind() method to set the value of a function’s this regardless of how it’s called,

and ES2015 introduced arrow functions which don’t provide their own this binding (it retains the this value of the enclosing lexical context).

Method1: Self - Self is being used to maintain a reference to the original this even as the context is changing. It’s a technique often used in event handlers (especially in closures).

Reference : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

function MyConstructor(data, transport) {
this.data = data;
var self = this;
transport.on(‘data’, function () {
alert(self.data);
});
}

Method2: Arrow function - An arrow function expression is a syntactically compact alternative to a regular function expression,

although without its own bindings to the this, arguments, super, or new.target keywords.

Arrow function expressions are ill suited as methods, and they cannot be used as constructors.

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow\_functions

function MyConstructor(data, transport) {
this.data = data;
transport.on(‘data’,()=> {
alert(this.data);
});
}

Method3:Bind- The bind() method creates a new function that,

when called, has its this keyword set to the provided value,

with a given sequence of arguments preceding any provided when the new function is called.

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_objects/Function/bind

function MyConstructor(data, transport) {
this.data = data;
transport.on(‘data’,(function() {
alert(this.data);
}).bind(this);

Solution 8:

Currently there is another approach possible if classes are used in code.

With support of class fields it’s possible to make it next way:

class someView {
onSomeInputKeyUp = (event) => {
console.log(this); // this refers to correct value
// ….
someInitMethod() {
//…
someInput.addEventListener(‘input’, this.onSomeInputKeyUp)

For sure under the hood it’s all old good arrow function that bind context but in this form it looks much more clear that explicit binding.

Since it’s Stage 3 Proposal you will need babel and appropriate babel plugin to process it as for now(08/2018).

Solution 9:

Another approach, which is the standard way since DOM2 to bind this within the event listener, that let you always remove the listener (among other benefits), is the handleEvent(evt)method from the EventListener interface:

var obj = {
handleEvent(e) {
// always true
console.log(this === obj);
}
};

document.body.addEventListener(‘click’, obj);

Detailed information about using handleEvent can be found here: https://medium.com/@WebReflection/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38

Solution 10:

The question revolves around how this keyword behaves in javascript. this behaves differently as below,

The value of this is usually determined by a functions execution context.
In the global scope, this refers to the global object (the window object).
If strict mode is enabled for any function then the value of this will be undefined as in strict mode, global object refers to undefined in place of the window object.
The object that is standing before the dot is what the this keyword will be bound to.
We can set the value of this explicitly with call(), bind(), and apply()
When the new keyword is used (a constructor), this is bound to the new object being created.
Arrow Functions dont bind thisinstead, this is bound lexically (i.e. based on the original context)

As most of the answers suggest, we can use Arrow function or bind() Method or Self var. I would quote a point about lambdas (Arrow function) from Google JavaScript Style Guide

Prefer using arrow functions over f.bind(this), and especially over
goog.bind(f, this). Avoid writing const self = this. Arrow functions
are particularly useful for callbacks, which sometimes pass unexpected
additional arguments.

Google clearly recommends to use lambdas rather than bind or const self = this

So the best solution would be to use lambdas as below,

function MyConstructor(data, transport) {
this.data = data;
transport.on(‘data’, () => {
alert(this.data);
});
}

References:

https://medium.com/tech-tajawal/javascript-this-4-rules-7354abdb274c
arrow-functions-vs-bind

[Vue.js] Vue.js - Calling an asynchronous method inline Subscribe to RSS

I would like to use a method to make an API call in a v-for loop, the purpose is to load an object based on a UID.

My method looks like this:

methods: {
async getTodo(uid) {
const data = await axios.get(
https://jsonplaceholder.typicode.com/todos/" + uid
);
return data;
}

}

From my understanding you can include methods inline as such:

{ getTodo(2) }

However this always returns [object Promise]

I must have misunderstand the use of methods for this purpose, or the async call in the method itself is incorrect if anyone can clarify what is wrong here.

Solution :

You can store the asynchronous response in a reactive array when the promise returns. Since it’s reactive, the promise response will automatically be displayed once each promise return.

Do something like:

export default {
data: {
asyncDataHolder: []
},
methods: {
async getTodo(uid) {
const data = await axios.get(
https://jsonplaceholder.typicode.com/todos/" + uid
);
let index = asyncDataHolder.length + 1;
asyncDataHolder.$set(index, data);
}

And inside the v-for loop:

{asyncDataHolder[i]}

[Vue.js] Why am I receiving invalid expression in my vue.js template? Subscribe to RSS

when receiving this error in my vue.js single file component:

Errors compiling template:

invalid expression: Unexpected token { in

{ jobs[0].build_link }

Raw expression: v-bind:href=”{ jobs[0].build_link }”

The full line is:

<td :style=tdStyle><a v-bind:href=”{ jobs[0].build_link }”>{ jobs[0].build_link }</a></td>

jobs is defined in the data method of my component and i can console.log this data without issue.

Also not sure why, but this line works fine with an inline-template vue.js script but throws this error after converting over to a single page component.

Solution :

I think you have a syntax problem. Please try without curly braces.
for ex:

<td :style=tdStyle><a v-bind:href=”obs[0].build_link”>{ jobs[0].build_link }</a></td>

Hope it works..

[Vue.js] Ideal way to chain asynchronous calls with axios Subscribe to RSS

I would like to make an API call with axios based on the response of an initial API call - is this possible with asynchronous functions?

there is tried something along the following lines with await/promise:

function get_user(value){
return axios.get( “https://apicall/" + value )
}

function get_user_posts(username){
return axios.get(“https://apicall/" + username)
}

var UsersOutput = async function () {
const userProfile = await get_user(2928928);
const userPosts = await get_user_posts(userProfile.data.username);
return { userProfile, userPosts }
}

But this appears to return nothing, from either calls. Any pointers appreciated.

Solution :

You first two functions return promices, not actual data. You should try something like this:

async function get_user(value){
return (await axios.get( “https://apicall/" + value )).data;
}

async function get_user_posts(username){
return (await axios.get(“https://apicall/" + username)).data;
}

Or, if you keep first two functions unchanged:

var UsersOutput = async function () {
const userProfile = (await get_user(2928928)).data;
const userPosts = (await get_user_posts(userProfile.data.username)).data;
return { userProfile, userPosts }
}

I, personally, find the first option better, because the getter functions return objects not promices, so you don’t clutter the code with (await ).data;. But it’s a matter of taste.

Solution 2:

I think you need to look on this link.
https://javascript.info/async-await

In the case you can use the .then() but I still prefer to use async await

By using await in async function you can chain some different actions and use the last call in the current

[Vue.js] Why does Vue.js allow pushing to prop array?Here is a code-fiddle demonstrating the issues Subscribe to RSS

vue.js.js displays warning when we try to change the prop value directly, like this:

Vue.component(‘Games’, {
template: `
<div>
<ol>
<li v-for=”game in games”>{ game }</li>
</ol>
<button @click=”clear”>Clear games</button>
</div>
`,
props: [‘games’],
methods: {
clear: function () {
this.games = [];
}
}
});

The warning being displayed is:

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value.

I know why that happens, but what I find surprising is that it doesn’t happen with .push(). If I change the method to add a value to the array instead of rewriting it, there’s no warning:

methods: {
add: function () {
this.games.push(‘Whatever’);
}
}

Why is there no warning? How is pushing directly to the prop fine and rewriting is not?

Solution :

It’s just because Array is kind of reference memory. When you have Array or Object stored in any variable it’s a reference variable.

Memory management in such case, The reference variable will points to a memory address in heap so you can add more n more value to address. However you cannot just replace that address with any new value even with the new address.

Solution 2:

The prop being pushed to is an array. After pushing a new value, it is still an array. I believe vue.js doesn’t do a deep watch on props out of the box (i.e, it doesn’t care about what’s inside the array).

To quote this article;

const array = [1, 2, 3, 4];
// array = [1, 2, 3, 4]

Now you update the array by pushing some more values into it:

array.push(5);
array.push(6);
array.push(7);
// array = [1, 2, 3, 4, 5, 6, 7]

Here’s the question: has array changed?

Well, it’s not that simple.

The contents of array have changed, but the variable array still
points to the same Array object. The array container hasn’t changed,
but what is inside of the array has changed.

So when you watch an array or an object, vue.js has no idea that you’ve
changed what’s inside that prop. You have to tell vue.js that you want it
to inspect inside of the prop when watching for changes.

Article By Michael Thiessen,
Posted Oct 2018 - All credit to them.

In response to the comment about this still being an anti-pattern, I’d say this;

If we think about why mutating props on a component directly is an anti-pattern in the first place, the reasoning still stands. To quote Michael again (I keep stumbling across his stuff by accident, I promise);

“We do this because it ensures that each component is isolated from
each other. From this we can guarantee a few things that help us in
thinking about our components: Only the component can change it’s own
state. Only the parent of the component can change the props.”

Solution 3:

As the warning says, one results in unexpected behaviour

When a component is updated/rendered, the props are written as values to the underlying component model. This can happen again at “any” time. This will often happen with components rendered in v-if or v-for conditions. In this case the prop value is written again from the parent to the child.

If the child increases the counter it will only increase it’s local copy of the prop, the original value parent.data.counter will still remain at the value 5. If the parent is updated (for example by setting counter=counter-1) then vue.js will override the value in the child with the new value from the parent. So all changes of the child are lost - and this can lead to unexpected behaviour.

This problem will not happen, if the prop is a reference, which is mutated

If the prop is an array, there exists only a single copy of this array in memory. Any mutation of the array will change the original array in parent as well as in child. This will only work for mutations of the array itself, if you would e.g. try child.propArray = child.propArray.slice(3) you will have the same problems as before. Since slice does not change the original array, but creates a copy the child will have a different reference than the parent and unexpected behaviour will likely manifest.

Here is a code-fiddle demonstrating the issues:

Vue.component(‘child-comp’, {
// camelCase in JavaScript
props: [‘counter’, ‘arr’],
template: `<h3>Child Counter: { counter } <button @click=”inc”>+</button>
-- Array: {arr} <button @click=”push”>push</button></h3></h3>`,
methods: { inc() { this.counter++ }, push() { this.arr.push(this.arr.length+1) } }
})

new Vue({
el: ‘#main’,
data: { counter: 1, arr: [] },
methods: { inc() { this.counter++ }, push() { this.arr.push(this.arr.length+1) } }
})
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<main id=”main”>
<h3>Main Counter: {counter} <button @click=”inc”>+</button>
-- Array: {arr} <button @click=”push”>push</button></h3>
<child-comp :counter=”counter” :arr=”arr”></child-comp>
<child-comp :counter=”counter” :arr=”arr”></child-comp>
</main>

[Vue.js] Mounted only trigger once in dynamic component Subscribe to RSS

In my App.vue

I’m using dynamic component to render dynamic component coming from Vuex

<component :is=”$store.getters.getDynamicComponent”></component>

then in my Home.vue

<v-card @click=”showDetails”>
<v-card-title primary-title>
<div class=”mb-0 text-truncate”> {name} </div>
</v-card-title>
</v-card>

import Details from ‘@/components/UI/Details’;

export default {
name: ‘Home’,
methods: {
showDetails() {
console.log(‘Mount Dynamic Component’);
this.$store.commit(‘SET_DYNAMIC_COMPONENT’, Details);
}
}
}

then on the Details component

export default {
name: ‘Details’,
mounted: {
console.log(‘This component has been mounted’);
}
}

The mounted lifecycle trigger only once when I click the card in Home.vue
I’m expecting that everytime I click the card it should print

Mount Dynamic Component

and

This component has been mounted

Solution :

You can define in the vuex state a numeric variable (i.e. dynamicComponentKey) that will work as key for the dynamic component, and increment it in the SET_DYNAMIC_COMPONENT mutation.

This should force the remount of component when the key will change.

Then, in the App.vue:

<component :is=”$store.getters.getDynamicComponent” :key=”$store.getters.getDynamicComponentKey”></component>

Solution 2:

I manage to solve this by using updated lifecycle instead of mounted.

In Details component

export default {
updated() {
if (this.$store.getters.dynamicComponent) {
console.log(‘This component has been mounted’);
}
}
}

@fabruex solution also works but in my case I’d rather don’t define another state in my vuex just for the key.

[Vue.js] authorization token for user performing auth needed operation - Laravel Passport Subscribe to RSS

First, when not sure authorization token is the real problem or not. when using passport and giving token for the auth. There is no problem with that part. User can register, login or logout. Also logged in user seeing pages only auth user can see. But when it comes to like or dislike an article. This error popping up. Route [login] not defined. it seems like in my controller below. this part is not working properly. Auth::user()->id

public function postLikeArticle( $id ){
$article = Article::where(‘id’, ‘=’, $id)->first();

if( !$article->likes->contains( Auth::user()->id ) ){

$article->likes()->attach( Auth::user()->id, [
‘created_at’ => date(‘Y-m-d H:i:s’),
‘updated_at’ => date(‘Y-m-d H:i:s’)
] );
}

return response()->json( [‘article_liked’ => true], 201 );
}

When I like the post when having 401 (Unauthorized) and my request header is looks like below.

No authorization token in the request header. And this makes me think that when doing something wrong at login part in my vuex. Which is like below.

export const articles = {

state: {
token: localStorage.getItem(‘access_token’) || null,
},
getters: {
loggedIn(state){
return state.token !== null;
}
},
mutations: {

fetchToken(state, token) {
state.token = token
},

},

actions: {
fetchToken(context, credentials){

return new Promise((resolve, reject) => {
axios.post(“/api/v1/login”, {
username:credentials.username,
password:credentials.password,
})
.then(response => {
const token = response.data.access_token
localStorage.setItem(‘access_token’, token)
context.commit(“fetchToken”, token)

resolve(response)

axios.defaults.headers.common[‘Authorization’] = ‘Bearer ‘ + context.state.token

})
.catch(error => {
console.log(error)
reject(error)
})
})
},
},
}

when not sure what when doing wrong. but it seems Auth:: is doesn’t know user logged in… When I logged in at first authorization token is there. But when I refresh the page it’s gone.

Solution :

Also logged in user seeing pages only auth user can see.

How are you doing this? If the user can see what auth user can see, which means you are making GET request with auth token right? If you’re using a passport, you should put the token into the Authorization header.

axios.defaults.headers.common.Authorization = `Bearer ${token}`;

Use this to put the token into the all axios request after you have login, then you should be good to go.