my object is modified inside a function that has a promise even if function returned [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
console.log() async or sync?
(3 answers)
Closed 8 months ago.
i have the following function that should return a result object
function checkRegisteredStatus(addr)
{
let result ={status:"",registrationType:""};
instance.methods.isRegistered(session.id,addr).call().then((receipt)=>
{
let {status,registrationType}= receipt;
result["status"] = status;
result["registrationType"]= registrationType;
});
return result;
}
i want to use this function like this:
let result = checkRegisteredStatus(addr)
i have three problems :
1- when i used async/await pattern on isRegistered() method like this:
let result = await instance.methods.isRegistered(session.id,addr).call();
return result;
result object would be a promise with unfulfilled status, which is wired since the purpose of await is to return the result of the resolve callback, and this is the first time that happens to me, i did async/await before and it always returns the final result not a promise. why is this happening?
2- due to the first problem i had to re-write my function the old way which is using.then() method (as i pasted above) and it works, however i dont understand how come the checkRegisteredStatus function should finish execution and is popped off from the call stack then how is it being able to modify the result object?
Example:
let result = checkRegisteredStatus(addr)
console.log(result)
the output would be:
> {status:"",registration:""}
when i click the expand sign > it outputs the following:
> {status:"",registration:""}
registrationType: "NotRegistered"
status: false
as far as i understand the value was caught be console.log() when the result object still had empty properties that's why i could expand the object and see its props have different values,i think JS is adding elements from inside that promise that registered before, but the function result obj should be cleaned from the stack (since it returns immediately), how is it adding values to it even though the function is popped from the call-stack?
3- how should i rewrite my function such that it blocks execution until it returns the final result not a promise and not adding up values later.

Related

returning a value from async/await promise [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I am trying to find a simple example of how to return a value from async/await where the value is easily accessed outside the async function.
Would the following two examples be considered the optimum way to return a value from an async/await function?
In other words, if the value returned from an async/await needs to be saved and used in other parts of the code, what would be the best way to save the value?
this is the easiest example i could find:
async function f() {
return 1;
}
var returnedValue = null; // variable to hold promise result
f().then( (result) => returnedValue = result );
console.log(returnedValue); // 1
or perhaps would it be better to use an object?
async function f(varInput) {
varInput.value = 1;
}
myObject = {} ; myObject.value=null;
f(myObject);
console.log(myObject.value); // 1
thank you.
My answer addresses two subjects here:
1) Async function returns a promise that resolves to a value. So, for instance your first function can be used as per your example. It can also be used like this:
async function() {
const x = await f();
}
2) Immutability - the second solution will work but it makes your funciton "impure". It is not bad in itself, but beware of side effects this might cause (for instance, if you change an app-wide singleton value without other components being notified about it, some part of your app might go out of sync with the data).
Hope this answers your question.

NodeJS Function return statement [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have this if function,
if (shorturl) {
...
link.shorten({longUrl:"http://google.com"}, function(err, results) {
return results;
});
return results;
}
Now, I want the second return statement to receive the value of "results". Rather, I get "ReferenceError: results is not defined".
Help me nest the return/callback.
Reference:
I am trying to use http://github.com/nkirby/node-bitlyapi inside a function to get a shorturl
I assume you get the error with the second return results; line.
This looks like asynchronous code (using callbacks to execute some part of the code later in time), so you cannot just return a value from it and expect it to be available in the same execution frame.
The best way to handle your case is probably to execute the rest of the code inside the callback itself.
You cannot so this since link.shorten is asynchronous and that is why you provided a callback function to it. At the time the second return is evaluated results is undefined since the call to the link.shorten function has not returned yet.
You should wait for the callback and only then return the result or you can use promises and return a promise for the result. (There are a couple of different promise libraries for node).
https://howtonode.org/promises

JavaScript Array result disappear [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 6 years ago.
I'm writing a function that pass in a string called "term" to search in my MongoDB, then add its results to an existed empty array of results called "result[]":
var searchAndAddToResults = (result, term)=> {
Place.find({ $or: [
{name: term}, {category: term}
] }, places=> {
for (let i in places) {
if (!itemExists(result, places[i].toObject())) {
result.push(places[i].toObject())
}
}
console.log(result) // result isn't empty, which is good
})
console.log(result) // result is empty, which is bad and weird
return result // this returned result is also empty, THIS is the real problem
}
Can anyone help me with restructuring this code to get it work? Thanks
These calls are asynchronous - which is why you are getting results in succcess callback of Place.find() and finding one outside of the method. Because as soon as Place.find() is called the next line is executed. So it'll be great if you learn to work with these asynchronous calls of javascript.

Scope access - Javascript [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I am encountering an issue with javascript scope.
function myFunc(){
var tmpTab = []; // I have an issue with this variable
for (var i=0; i > 72; i++){
fs.readFile(filename, 'utf8', function(err, data) {
// Here I'm doing some basic manipulations with my tmpTab
console.log(tmpTab); // -> it works
});
console.log(tmpTab); // -> it works
}
return tmpTab;
console.log(tmpTab); // -> it does not work. It doesn't return the content of my tmpTab
}
I tried different ways (with var, without, with this) but none worked.
So how am I supposed to correctly get the content of my tmpTab that was modified inside the readFile function ?
return tmpTab;
console.log(tmpTab);
you can't call code after returning from function. reverse the statements
Try readFileSync, which is synchronous. Otherwise tmpTab in the last console will be [].
If you use readFile, the content is only available in the callback. readFileSync will "feel" slower, but the content is synchronously available throughout the block.
var tmpTab = fs.readFileSync(filename, 'utf8')
console.log(tmpTab);
Edit :
And of course, like the previous answers have rightly included, any statement which occurs after the return statement will not execute, so that is the other change you should make. Swapping the two statements will do.
Code after return statements will not run. (Some modern browsers warn you about this in the console.) Put it before the return:
console.log(tmpTab);
return tmpTab;

return value after a promise [duplicate]

This question already has answers here:
setting a variable to get return from call back function using promise
(2 answers)
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
Closed 8 years ago.
I have a javascript function where I want to return the value that I get after the return method.
Easier to see than explain
function getValue(file){
var val;
lookupValue(file).then(function(res){
val = res.val;
}
return val;
}
What is the best way to do this with a promise. As I understand it, the return val will return before the lookupValue has done it's then, but the I can't return res.val as that is only returning from the inner function.
Use a pattern along these lines:
function getValue(file) {
return lookupValue(file);
}
getValue('myFile.txt').then(function(res) {
// do whatever with res here
});
(although this is a bit redundant, I'm sure your actual code is more complicated)
The best way to do this would be to use the promise returning function as it is, like this
lookupValue(file).then(function(res) {
// Write the code which depends on the `res.val`, here
});
The function which invokes an asynchronous function cannot wait till the async function returns a value. Because, it just invokes the async function and executes the rest of the code in it. So, when an async function returns a value, it will not be received by the same function which invoked it.
So, the general idea is to write the code which depends on the return value of an async function, in the async function itself.

Categories