Reputation: 93
I try to update some data in my mounted part, in my Vue.js component. Here is my code :
methods: {
initData() {
const self = this;
axios
.get("/checkAuthentification")
.then((response) => {
(self.userFields.userAuthenticated = response.data),
console.log("method"),
console.log(self.userFields.userAuthenticated),
console.log("reponse"),
console.log(response.data);
})
.catch((error) => {
(self.errors = error.response.data.errors || {}),
console.log(self.errors);
});
console.log("between");
console.log(self.userFields.userAuthenticated);
if (self.userFields.userAuthenticated == "true") {
axios
.get("/getAuthenticatedUserData")
.then((response) => {
(self.userId = String(response.data.id)),
(self.userFields = response.data),
console.log("user data"),
console.log(response.data);
})
.catch((error) => {
(self.errors = error.response.data.errors || {}),
console.log(self.errors);
});
}
},
},
mounted() {
this.initData();
},
In the first axios call, it works perfectly, the two console log give the expected value "true". But on the next console.log after between, it says 'undefined'. Thue userFields doesn't update after the firt axios call. I don't understand because i did the same thing on a submit button on a form, and it worked perfectly. I ask here because I looked other posts and the answer is always to use const=this, which I did. Thank you for your help !
Upvotes: 4
Views: 1775
Reputation: 11
state: {
userFields: {
userAuthenticated: false,
...
}
},
methods: {
initData() {
const self = this;
axios
.get("/checkAuthentification")
.then((response) => {
(self.userFields.userAuthenticated = response.data),
console.log("method"),
console.log(self.userFields.userAuthenticated),
console.log("reponse"),
console.log(response.data);
})
.catch((error) => {
(self.errors = error.response.data.errors || {}),
console.log(self.errors);
});
},
getUserData() {
if (this.userFields.userAuthenticated) {
axios
.get("/getAuthenticatedUserData")
.then((response) => {
(self.userId = String(response.data.id)),
(self.userFields = response.data),
console.log("user data"),
console.log(response.data);
})
.catch((error) => {
(self.errors = error.response.data.errors || {}),
console.log(self.errors);
});
}
}
},
watch: {
'userFields.userAuthenticated': function() {
this.getUserData()
}
},
mounted() {
this.initData();
},
Upvotes: 1
Reputation: 4240
To answer your questions first you would have to understand the nature of asynchronous operations in Javascript. I will try my best to explain but will leave this link in case you would like to read more about it
On your example you have:
axios.get('/checkAuthentification').then(response =>{
console.log('CHecked authentication')
...
})
console.log('between');
console.log(self.userFields.userAuthenticated);
When you do the axios.get
what happens is that an asynchornous operation will be called (asynchornous = won't wait for the answer for the code to continue execution). You will contact your backend server and ONLY when you receive an answer the console.log('checked authentication')
will run but in the meantime (remember axios.get
is asynchronous) the console.log('between'); AND console.log(self.userFields.userAuthenticated);
will execute before you receive an answer from the backend server.
How can we solve this
We can solve this with two approaches. The first one would be the more old approach - waiting for promises to resolve by the then
keyword
axios
.get('/checkAuthentification')
.then(response =>{
console.log('CHecked authentication')
console.log('between');
console.log(self.userFields.userAuthenticated);
return response;
})
.then(() => {
// do more operations after promise was resolved
})
Or we can do a more modern way - we can use async/await.
async initData() {
const response = await axios.get('/checkAuthentification');
console.log('CHecked authentication')
console.log('between');
console.log(self.userFields.userAuthenticated);
}
Upvotes: 2