how to make sure all promises are resolved in javascript? [duplicate] - javascript

This question already has answers here:
Wait for all promises to resolve
(5 answers)
Closed 8 years ago.
Suppose I have 2 or more async calls:
$scope.obja = {};
$scope.objb = {};
ref1.on('value', function (value) {
$scope.obja= value.val();
});
ref2.on('value', function (value) {
$scope.objb= value.val();
});
Later within the script I want to make sure that both of the $scope variables are set before I use them.
This example code follows the firebase examples in angularjs.
Any ideas?

Surely you can just check with an if statement?
if (($scope.obja != {}) && ($scope.objb != {})) {
// they have been set
}
Or, if they stand a chance of getting set to an empty object, just have a second variable that gets set with them:
var setn = 0;
// ...
ref1.on('value', function (value) {
$scope.obja= value.val();
setn++;
});
ref2.on('value', function (value) {
$scope.objb= value.val();
setn++;
});
// ...
// later in code, check if they have both been set
if (setn == 2) {
// they have both been set
}

Related

Variable changed inside arrow function not changed when consoled outside the arrow function [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)
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I am working with angular and typescript and want to change the value of the variable inside the function. I am using a service to get the data. The code is shown below:
isValue:boolean = false;
onChangeValue(list: List) {
this.someServive.getData(list).subscribe(
item => {
if(item.value === 1) {
this.isValue = true;
}
});
console.log(this.isValue); //the value is still false here
}
Good day!
It happens due to the fact, that your service call is an async operation. And browser doesn't wait when your service emits some value, which you handle in subscription block.
isValue = false;
onChangeValue(list: List) {
this.someServive.getData(list).subscribe(item => {
if (item.value === 1) {
this.isValue = true;
this.executeOnUpdateCallback();
}
});
}
executeOnUpdateCallback() {
console.log(this.isValue); // true
}
Something like this you should do to handle it. I hope, you got it (please google about js event loop)
Since javascript is asynchronous, the value won't change until the getData service call actually happens.
In your case console executes before the getData happens.
You can either try it with promise or callback
Try below:
isValue:boolean = false;
onChangeValue(list: List) {
onDataRecieved((res)=>{
console.log(this.isValue);
});
}
onDataRecieved(cb){
this.someServive.getData(list).subscribe(
item => {
if(item.value === 1) {
this.isValue = true;
cb(true);
}
});
}

Return Value Happens Before forEach [duplicate]

This question already has answers here:
Using async/await with a forEach loop
(33 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I am trying to sort names in two different array. but when I need to return the final result, it will just return the values first then do the forEach.
const available = [];
const taken = [];
const names = data.split('\n');
names.forEach(async (name, i) => {
(data.success !== undefined) ? (availabe.push(name)) : (taken.push(name));
});
return { //This returns 0 for both
available: available.length,
taken: taken.length
}
The issue is that forEach doesn't wait for async code. Check here: https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404
Try this instead:
async function f() {
const available = [];
const taken = [];
const names = data.split('\n');
for (const name of names) {
// await request...
(data.success !== undefined) ? (availabe.push(name)) : (taken.push(name));
}
return { //This returns 0 for both
available: available.length,
taken: taken.length
}
}
Then, when you call f(), make sure you await f().
Side note: if you have very many names, this could get very slow. You're waiting for each request to complete before beginning the next one. You'll want to look into requesting all the data at once, either with a different http endpoint, or using something like Promise.all() or the async library.
The variable name "available" is misspelled as "availabe" in line 8. Other syntax errors may exist; you might try using something link jslint.com.

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.

Assign to variable after then catch [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
How to use $http promise response outside success handler
(3 answers)
Closed 5 years ago.
I have a $watchCollection in angularJS that calls the function getBalance(addr) in the listener.
$scope.$watchCollection('settings',
function() {
for (i = 0; i < $scope.settings['accounts'].length; i++) {
var bal = $scope.getBalance($scope.settings['accounts'][i]);
console.log(bal);
}
}
);
The function getBalance is defined as follows:
$scope.getBalance = function(addr) {
var balance;
if ($scope.settings.contract !== null) {
$scope.settings.contract.deployed().then(function(deployed) {
return deployed.balanceOf(addr);
}).then(function(res) {
balance = res.toNumber();
console.log(balance);
return balance;
}).catch(function(err) {
console.log(err.message);
});
}
return balance;
};
The problem is that in then, the balance variable is printed correctly however, in $watchCollection, return is undefined.
The problem should be because JS keeps executing without waiting for a result therefore the variable is read as undefined however, how do I have to change these two snippets of code in order to get the result when ready and append it to $scope.balance.
It looks like you're trying to change async code to sync code, which you can't really do. You need to carry the promise all the way through, in both.
Instead of setting balance to a variable and returning that variable, return the promise itself, then use then in your $watchCollection to get the value.
$scope.$watchCollection('settings',
function() {
for (i = 0; i < $scope.settings['accounts'].length; i++) {
$scope.getBalance($scope.settings['accounts'][i])
.then(bal => console.log(bal));
}
}
);
$scope.getBalance = function(addr) {
if ($scope.settings.contract !== null) {
return $scope.settings.contract.deployed().then(function(deployed) {
return deployed.balanceOf(addr);
}).then(function(res) {
balance = res.toNumber();
console.log(balance);
return balance;
}).catch(function(err) {
console.log(err.message);
});
}
return Promise.resolve(null);
};
Note, in functions that return Promises, make sure all pathways return a Promise or bad things will happen (hence the Promise.resolve(null)).

How to make this line of code work? [duplicate]

This question already has answers here:
How do I return the response from an Observable/http/async call in angular?
(10 answers)
Closed 5 years ago.
var relative = af.database.object('users/user75ECZOiNtxZwYoezaXmYA9YwPm53', { preserveSnapshot: true });
relative.subscribe(
snapshot => {
this.usedBasicProfile = snapshot;
}
);
console.log(this.usedBasicProfile); //the value is undefined, how to make this work?
what I want to do is get the data from the firebase, anyone could help me?
It appears you're using an async method which means the value is not available until execution gets inside the callback handler. Have you tried this?
var relative = af.database.object('users/user75ECZOiNtxZwYoezaXmYA9YwPm53', { preserveSnapshot: true });
relative.subscribe(snapshot => {
this.usedBasicProfile = snapshot;
console.log(this.usedBasicProfile);
});

Categories

Resources