not able to update the UI from setTimeout() in vuejs [duplicate] - javascript

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 1 year ago.
i want to update name of person after every second in ui after feching name from lifeSpanObj object in .vue file (vuejs).
<div> {{personName}}</div> // in template using this this(its example not exactly this)
this.lifeSpanObj.forEach((element, i) => {
setTimeout(function () {
this.personName = element.name;
console.log(this.personName);
}, 1000);
});
using the above example i am able to print updated values in console but UI does not get updated. what could fix for this?

Make sure always use arrow function to not shadow this keyword:
this.lifeSpanObj.forEach((element, i) => {
setTimeout(() => { // arrow function instead of anonymous function
this.personName = element.name; // now this refers to the vue component
console.log(this.personName);
}, 1000);
});
for primitive function (in ES5) you can still follow the below approach
this.lifeSpanObj.forEach((element, i) => {
var self = this;
setTimeout(function () {
self.personName = element.name;
console.log(self.personName);
}, 1000);
});

Related

Unable to access "this" inside promise in Angular [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 2 years ago.
The following function is used to find the country-code of the user and store it in the local Storage. However, I am unable to access this inside the promise and the console log returns "null".
successfulLookup(position) {
const { latitude, longitude } = position.coords;
fetch(`https://api.opencagedata.com/geocode/v1/json?q=${latitude}+${longitude}&key=d2c9d6477126472fbe51b721a2d34399`)
.then((response) => { return response.json() })
.then((jsonRes) => {
console.log(jsonRes.results[0].components.country_code);
console.log(this);
this.dataSharingService.universalLocalStorageSetter(jsonRes.results[0].components.country_code,"countryCode");
})
}
I am calling the function findCountry inside NgOnInit
findCountry() {
if (window.navigator.geolocation) {
window.navigator.geolocation
.getCurrentPosition(this.successfulLookup);
}
}
The following question has been asked a couple of times and the solution is to use Arrow function but I am already using an Arrow function. Any help is appreciated.
UPDATE
successfulLookup(position) {
const { latitude, longitude } = position.coords;
const self = this;
fetch(`https://api.opencagedata.com/geocode/v1/json?q=${latitude}+${longitude}&key=d2c9d6477126472fbe51b721a2d34399`)
.then((response) => { return response.json() })
.then((jsonRes) => {
console.log(jsonRes.results[0].components.country_code);
console.log(self);
self.dataSharingService.universalLocalStorageSetter(jsonRes.results[0].components.country_code,"countryCode");
})
}
tried defining const self=this
You need to change the code like
window.navigator.geolocation
.getCurrentPosition(this.successfulLookup.bind(this));
We need to use bind(this) to the successfulLookup method because that method is calling by the getCurrentPosition. In that case, this refers to the getCurrentPosition.
I posted the concept of a bind in my youtube videos. If you are interested you can check the link. I also posted an angular course that has about 100 videos covering all the concepts. Here is the link below.
Leela Web Dev

Can not use this inside a setInterval that is inside a promise [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
I am developing an application with vuejs. I want to use this inside a promise, I want to be able to call a function or data inside the .then scope, and for that I use the this. But if I do this inside the .then I get an error, it seems this to be lost even though I bind the scope with and arrow function. What can I do?
javascript
methods: {
...mapActions(['setCredentials']),
doLogin() {
console.log('credentials ' + this.username, this.password);
this.$store.dispatch('connect', {
username: this.username,
password: this.password,
});
this.checkResult().then((interval) => {
vm.$f7router.navigate('/favorites');
})
},
checkResult() {
return new Promise(function(resolve) {
var id = setInterval( () => {
let condition = this.$store.state.isConnected
if (condition) {
clearInterval(id);
resolve(id);
}
setTimeout(() => {
clearInterval(id);
reject(id);
}, 20000);
}, 10);
});
}
Use arrow function when instanciating your promise:
return new Promise((resolve) => { /* ... */ });
The error is due to the context binding. You can use Arrow function as they have no this property of their own (They rely on their parent function's this property).
Change return new Promise(function(resolve) {..
to return new Promise((resolve) => {..
Try to create a var before the promise like:
var self = this;
then use self instead of this inside the promise

How to run database queries synchronously in javascript [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 4 years ago.
let positionSettings = require('setting');
function getSetting(element) {
let setting;
positionSettings.find({element: element}, function (err,docs) {
console.log(docs[0].current); // output the value
setting = docs[0].current;
});
return setting;
}
$(document).on("click", "#save" , function(e) {
console.log(getSetting("abc")); // Output undefined
});
Why is the getSetting() function returning undefined. How can I achieve it.
Because it's an async function, you can't mix async and sync functions this way, try something like this:
let positionSettings = require('setting');
function getSetting(element, callback) {
positionSettings.find({element: element}, (err,docs) => {
let setting;
console.log(docs[0].current); // output the value
setting = docs[0].current;
callback(setting);
});
}
$(document).on("click", "#save" , (e) => {
getSetting("abc", (setting) => {
console.log(setting);
});
});
The fact is that you can't be sure that the data will be avaible after the function call, the only place that you have this sure is inside the callback.
And just a hint, use arrow functions to declare anonymous functions.

Undefined 'this' in Promise + array. reduce() [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I'm facing a problem since this morning.
WHAT I HAVE
Basically, I have a simple class, with an array of files to register:
function MyClass() {
this.filesToRegister = [
{
"fileName": "http://tny.im/azk"
},
{
"fileName": "http://tny.im/azk"
}
];
}
I have also a simple function, _contextFunction() which takes a single fileToRegister entry:
MyClass.prototype._contextFunction = function(fileToRegister) {
return new Promise((resolve, reject) => {
logger.info(typeof this.filesToRegister);
logger.info('current file: ' + fileToRegister);
return resolve();
});
};
Note that this function MUST access to the context (the this), it's mandatory, and I can't change that.
Finally, I have a utility method, processArray(), that can apply a function on each item of an array, all done synchronously:
MyClass.prototype.processArray = function(array, fn) {
let results = [];
return array.reduce((p, item) => {
return p.then(() => {
return fn(item).then((data) => {
results.push(data);
return results;
}).catch(err => console.log(err));
});
}, Promise.resolve());
};
WHAT I TRY TO DO
I use this utility method to apply _contextFunction() on each item of the filesToRegister array:
this.processArray(this.filesToRegister, this._contextFunction);
It works without problem and execute this._contextFunction() on each item of this.filesToRegister.
WHAT THE PROBLEM IS
BUT, when I try to log typeof this.filesToRegister in _contextFunction(), the result is undefined... After several tests, I concluded that nothing in the context is accessible (neither context attributes nor context methods).
However, if I execute this._contextFunction() without the processArray() method, I can access to the context (both context attributes and context methods).
WHAT I THINK
My guess is that the problem comes from the processArray() method, but I don't see where... I tried to log typeof this.filesToRegister right in the processArray() method, and it works...
To conclude:
processArray() IS able to access to the context.
this._contextFunction() launched 'standalone' IS able to access to the context.
this._contextFunction() launched by processArray() IS NOT able to access to the context.
Can anyone help me? Thanks
fn(item)
Calls the function without the context. Use:
fn.call(this, item)
Alternatively pass the method name:
this.processArray(this.filesToRegister,"_contextFunction");
And then do:
this[fn](item);
How i would do that:
class MyClass {
constructor(){
this.files = [];
}
async add(file){
await "whatever";
this.files.push(file);
}
multiple(name, array){
return Promise.all( array.map(el => this[name](el)));
}
}
And then:
const instance = new MyClass;
instance.add("whatever");
instance.multiple("add",[1,2,3]);

JavaScript recursive setTimeout [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I defined this class in JavaScript:
function Signal(lbl, ho, tag) {
this.lbl = lbl;
this.ho = ho;
this.tag = tag;
this.getstatus = function () {
if (this.ho) {
$.get('/get.cgi?' + this.tag + '=?0', function (data) {
console.log(data);
setTimeout(this.getstatus, 1000);
});
}
};
}
Once getstatus is called, it should start calling itself with setTimout, but it doesn't! It only works one time.
If I use a function without a class, it works!
Please help me out.
Thanks!
The problem is when getStatus is invoked by the timer, this inside the method does not refer to the object, you can pass a custom value for this using bind(). Also note that in the ajax callback this refers to the ajax settings object.
function Signal(lbl, ho, tag) {
this.lbl = lbl;
this.ho = ho;
this.tag = tag;
this.getstatus = function () {
if (this.ho) {
var signal = this;
$.get('/get.cgi?' + this.tag + '=?0', function (data) {
console.log(data);
setTimeout(signal.getstatus.bind(signal), 1000);
});
}
};
}

Categories

Resources