How to update component data after calling mounted function? [duplicate] - vue.js

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I'm trying to update my component's data after calling an API (calling method from mounted function)
axios.get("getInfo")
.then(function(res){
this.result = res.data.result
}).catch(function(err){
console.log(err)
})
however the "this.result = res.data.result" doesn't get executed but when i paste the same line before the call, I get result updated (like this.data.result = 20). Also when I try the console.log(res.data) I get no response
I also get the message on the console that the request was completed
XHR finished loading: GET "http://app/getInfo".
My mounted function is like this
mounted:function(){
this.setData()
},
methods:{
setData:function(){
console.log(this.pullData())
},
}
What am I doing wrong? Thanks in advance

You need to store the reference to the component in a variable firstly, then refer to it in the function with the variable instead of this keyword; The reason is that you created a new function in then, this thus refers to the function instead of the Vue component:
var ref = this;
axios.get("getInfo")
.then(function(res){
ref.result = res.data.result
// ^^^ ref instead of this
}).catch(function(err){
console.log(err)
})
And another more straight forward way to do this is to use arrow function which doesn't have a this context:
axios.get("getInfo").then(res => { // arrow function instead of anonymous function
this.result = res.data.result
}).catch(err => {
console.log(err)
})

Related

Vue 2 / Nuxt 2 Emit From Axios With Dialog Confirm

i am using Vue 2 / nuxt to emit from a axios post* call which itself is called from a Buefy dialog confirm. The emit from this component will close the window / panel and then re-load the users.
If I call the axios request from the button, this works without any issues, but once being called from the dialog, it just don't work?
*most likely this will be updated to a delete request, just not gotten to that let
See code below:
removeUser() {
this.$buefy.dialog.confirm({
message: 'Continue on this task?',
onConfirm: () => {
this.removeUserFunc()
}
})
},
removeUserFunc() {
// console.log(that)
const that = this
// Build URL
const EndPoint = '/remove_user/' + this.id
this.$axios.post(EndPoint).then((res) => {
// User Remove Message
UserRemoved(this.$swal)
that.$parent.$emit('completed')
// console.log(this.$emit('complete'))
// // Emit 'completed' Message
console.log(that.$emit('completed'))
console.log(that)
}).catch((res) => {
console.log(res)
// Check For Errors
GeneralError(this.$swal)
})
}
I was thinking it was losing access to the correct this, so i was trying to pass that back in, but not sure that is the case?
I have also tried with await, while that sort of works? I think is firing the emit too fast, as it re-loads the users but it still includes the user that as just been deleted?
removeUser() {
this.$buefy.dialog.confirm({
message: 'Continue on this task?',
onConfirm: async() => {
this.removeUserFunc()
await this.$emit('completed')
}
})
},
The this keyword refers to the object the function belongs to, or the window object if the function belongs to no object.
Try to use .bind and use a ES5 function
removeUser() {
this.$buefy.dialog.confirm({
message: 'Continue on this task?',
onConfirm: function() {
this.removeUserFunc()
}.bind(this)
})
},

Vue localforage no update

I'm using localforage, but I can't figure out why this.emails is not updated outside the localforage. I get no errors in console.
localforage.getItem("emails").then(function (value) {
this.emails = value
console.log(value) // shows correct value
console.log(this.emails) // shows correct value
}).catch(function (err) {
console.log(err); // no error is thrown
});
Functions have a this scope. So when you're setting this.emails, you're setting the function's this.emails instead of your Vue component.
You could use bind to deal with this, but the easier way would be to just use an anonymous function in your then, like this:
localforage.getItem("emails").then((value) => {
this.emails = value
})

Can't access this.setState inside 2nd API call in nested calls (AWS Amplify Storage API) (React Native)

The first call (Storage.list('s3 bucket path')) returns a list of keys.
For each key, I make a second call (Storage.get('key')) that returns a url
Inside the first AND second API call I console.log and get the correct data I need for each.
this.setState works perfectly inside the first API call, but it doesn't inside the second one.
My code is:
state = { keyItems: [], urlItems: [] }
componentDidMount() {
Storage.list('')
.then(keyItems => {
console.log("keyItems: ", keyItems)
this.setState({ keyItems: keyItems })
/*for each photo key in the folder..*/
keyItems.forEach(function(keyItem) {
/*get the URL*/
Storage.get(keyItem.key)
.then(urlItem => {
console.log("urlItem: ", urlItem)
/*add URL item to state*/
/*ANY CALL TO this.setState HERE DOESN'T WORK, i've tried
even simple tests*/
this.setState(prevState => ({ urlItems:[...prevState.urlItems, { key: keyItem.key, source: urlItem } ]}))
})
.catch(err => {
console.log("error fetching photo URL", err)
})
})
})
.catch(err => {
console.log("error fetching photos keys", err)
})
}
Console:
I've tried making the calls from arrow functions outside the componentDidMount but still can't access the this.setState
Thanks!
The value of this is getting lost inside the .then
You could try this
Set this to a variable
Use that variable instead of this
Here it in code
componentDidMount () {
const that = this;
// now call setState like this
that.setState(...)
}
You can read more about it at the link below, but I’ve put the general gist of it here.
this is always the object the method is called on. However, when
passing the method to then(), you are not calling it! The method
will be stored somewhere and called from there later.
Why is 'this' undefined inside class method when using promises?

Vue redirecting. My code is note redirecting to the page i want to

it is not redirecting to the page. What am I doing wrong here?
this method is getting all the data from the form and adding dynamic values to date and token.
methods:{
addToApi() {
console.log(this.data);
crypto.randomBytes(20,(err,buff)=>{
let token = buff.toString('hex');
let sub = this.data.sub;
let date = Date.now() + 3600000;
let newData = {
sub: this.data.sub,
token: token,
date: date
}
axios.post("http://localhost:3000/api/qrData",newData)
.then((res)=>{
//after sending the data to back end it should redirect to this route but it doesn't redirect
router.go('/');
})
.catch((err)=>{
console.log(err);
})
})
}
}
}
check Vue Router: Programing Navigation,
As the tutorial said:
router.go(n)
This method takes a single integer as parameter that indicates by
how many steps to go forwards or go backwards in the history stack,
similar to window.history.go(n).
For your use case, you should use router.push
The main problem is that you refer to this variable which in this certain case has different values over the scopes. The common solution is to create a new variable storing this as I did it in the first line of addToApi() method.
Getting to the point, variable router is undefined in the method's scope. You should use this.$router which refers to the global router object. And as this variable loses its value in then function (change of scope), you want to use vm variable I defined. So your code should finally look like this below:
As pointed in the comment, arrow functions do not carry this variable.
If you want to redirect to a particular route you should use $router.push method instead. (go method was used in Vue Router's older versions and renamed to push in 2.x)
methods: {
addToApi() {
crypto.randomBytes(20, (err, buff) => {
let token = buff.toString('hex');
let sub = this.data.sub;
let date = Date.now() + 3600000;
let newData = {
sub: this.data.sub,
token: token,
date: date
}
axios.post("http://localhost:3000/api/qrData", newData)
.then((res) => {
//after sending the data to back end it should redirect to this route but it doesn't redirect
this.$router.push('/');
})
.catch((err) => {
console.log(err);
})
})
}
}
}

VueJS - Access to Store data from mounted method? [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I'm trying to get access to my store data from a mounted method of my component. It works fine if I try it with a not mounted method. After I read a bit it makes sense that I've no access, but is there any other way I didn't find yet?
methods: {
testEvent() {
// works
let players = this.$store.state.players;
console.log(players);
},
socketEvent() {
// Uncaught TypeError: Cannot read property 'state' of undefined
socket.on('dice_data', function(data) {
let players = this.$store.state.players;
console.log(players);
});
}
},
mounted() {
this.socketEvent()
}
Thank you
Issue is with this inside function
You can solve like this:
socketEvent() {
socket.on('dice_data', (data) => {
let players = this.$store.state.players;
console.log(players);
});
}
or if you prefer to write function, instead of arrow function you can also do like this:
socketEvent() {
let self = this
socket.on('dice_data', function(data) {
let players = self.$store.state.players;
console.log(players);
});
}