Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Code Block 1
export async function sendToDatabase(order, ownProps) {
const url = `api_url`
await axios.post(url, order).then(
(response) => {
if (response.status == 200){
console.log("response 200")
console.log(response)
return response
}
}
).catch(error => (error))
}
Code Block 2
sendToDatabase(order, ownProps).then(
value => console.log(value)
)
Console Output
response 200
{data: "Order Uploaded", status: 200, statusText: "", headers: {…}, config: {…}, …}
undefined
The function in code block 1 is called in code block 2. I don't really understand why the value returned is undefined, especially since the sendToDatabase() function returns a promise, and the promise should already be resolved in the then block
Also, due to certain constraints of my project, the 2 code blocks cannot be merged, and have to exist separately, hence I am not able to put code block 2 into the .then() block of code block 1
Any form of advice or help will be greatly appreciated!
Normally a comment would be enough for such a question but i would like to post an answer as there are multiple problems in your code.
sendToDatabase function doesn't explicitly returns any value, so the promise returned by it is implicitly fulfilled with the value of undefined.
To fix this problem, you need to explicitly return some value from sendToDatabase function.
Don't mix promise-chaining with async-await syntax. Your sendToDatabase function can be simplified as shown below:
export async function sendToDatabase(order, ownProps) {
const url = `api_url`;
try {
return await axios.post(url, order);
} (error) {
// handle the error
}
}
I have omitted the check for response.status, you could check the status code in the calling code.
Inside the callback function of the catch method, you are returning the error object that was passed to the callback function as an argument; this will implicitly convert promise rejection into promise fulfilment.
To solve the problem, you need to throw the error object instead of returning it.
.catch(error => { throw error });
I suggest that you allow the calling code to catch and handle the error. This means that you should remove the catch block from the sendToDatabase function and add it in the code where you call the sendToDatabase function.
If you add the catch handler in the calling code, then your function could be simplified as shown below:
export async function sendToDatabase(order, ownProps) {
const url = `api_url`;
return axios.post(url, order);
}
(if you are wondering why there is no await keyword before axios.post(...), see this answer which contains an answer to this question.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I'm getting some mock data from a mock endpoint, using JQuery and promises.
Just for the sake of it, I want to try and make it work with async/await.
I think I managed to find some code that works, although, I don't get the same output ( in chrome browser) in the console.
Here are the two pieces of code :
import $ from 'jquery';
let myPromise = $.get("http://5e2f41529c29c900145db22d.mockapi.io/test/users");
myPromise
.then(
(data) => {
console.log('Success promises: ', data);
}
)
.catch(
(error) => {
console.log('Error : ', error.responseText);
}
);
and
// same as above but with async/await
import $ from 'jquery';
let getUsersFromEndPoint = async function (){
try {
let users = await $.get("http://5e2f41529c29c900145db22d.mockapi.io/test/users");
console.log('Success Async: ' + users);
} catch (error) {
console.log('Error : ', error.responseText);
}
};
getUsersFromEndPoint();
And they output :
I'm not sure what the difference is.
Does anyone know why i get a different output ? and what they both "mean" ?
Thank you !
Both the promise-based code and the async/await are correct, and do the same thing, except a small (and therefore hard-to-spot) difference.
The promise-based version's logger code:
console.log('Success promises: ', data);
...logs the result as you expect.
However, in the async function, the console.log contains a + operator, that casts its second operand (the data) into a string, so all objects get transformed into "[object Object]":
console.log('Success Async: ' + users);
Pass data as the second argument of console.log (as you've done with the promise version), and you'll get the expected result.
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 3 years ago.
I have some code that authenticates by posting an object using npm request.
After posting the JSON object, a JSON response is returned which contains an authn token I can use in future GET/POST request headers.
I have some async code that returns the correct authn token but I can only access it via the .then function code block.
I have read through the usual linked thread here: How do I return the response from an asynchronous call? but even though the return result is in the .then function I still get undefined when trying to do anything other than console.log().
const postData = {
"auth": {
"username": "username",
"password":"password"
}
};
var returnRequest = () => {
var options = {
method: 'POST',
url: 'https://api.appnexus.com/auth',
body: postData,
json: true
};
return new Promise(async (resolve, reject) => {
await requestAPI(options, function (error, response, body) {
if (error) {
reject(error);
}
resolve(body);
});
})
}
var returnedResult
returnRequest()
.then((result) => {
returnedResult = result.response.token
})
.catch((error) => {
console.log(error);
})
console.log(returnedResult)
I would expect to see the returnedResult store the token as I understand it, the .then promise only runs one the request has happened?
A developer said I have to build all subsequent code inside the .then block but that sounds crazy, that I have to have my whole program inside this returnRequest function rather than be able to pass the returned token back outside to a global variable?
Is that the correct way to do it, and am I supposed to just build all subsequent requests using the result.response.token inside the
returnRequest()
.then((result) => {
returnedResult = result.response.token
})
function?
.then is the mechanism that promises use to let you know when the value is available. The "when" part is important: only the promise object knows what time your code should run at. So even if you try to write some extra code to store values in variables, the question of when it's safe to try to get those variables can only be answered by the promise's .then method.
So yes, any code that needs the values to be available needs to be put in the .then of the promise. Maybe you have some separate part of the codebase that needs to interact with the result, and so it feels clumsy to try to have to copy that code over to here. Well you don't need to: you just need to pass that other code the promise, and then that other code can call .then on the promise itself. For example:
const tokenPromise = returnRequest()
.then(result => result.response.token);
// Anywhere else that tokenPromise in scope can write whatever code it needs to:
tokenPromise.then(token => {
// Do anything with the token
});
// And a completely different piece of code can write its own stuff with the token
tokenPromise.then(token => {
// Do other stuff with the token
});
No you don't need to use result.response.token everywhere to use the authn token.
The thing here to understand is the flow of code. Your console.log statement may be returning you undefined .
Why ? Haven't you updated the global variable inside the then block of promise ?
Yes you have ! But the problem is that it is not reflected to you in the console log statement because this very statement is executed before any updation in the global variable.
So, it gets updated but it takes time to do so.
This is what is known as asynchronous code .
Now what about the suggestion of wrapping the code inside the .then block.
If you will add a console log statement beneath the updation (inside the then block) it will print you the exact token you are looking for.
But actually you don't need that , you can use aysnc/ await syntax to make it look like synchronus code, and then it will don't confuse you.
For example you can do something like this.
let result = await returnRequest();
let returnedToken =result.response.token;
// Now it will print you the token
console.log(returnedToken)
Make sure to add the async keyword infront of the function using await.
there are several ways to do what you ask, one way would be to wrap your entire code in async iife (immediately invoked function expression) so that you can use await.
!async function(){
....
....
....
var returnedResult = await returnRequest()
.then((result) => {
return result.response.token;
})
.catch((error) => {
console.log(error);
})
//continue
}()
I’ll try and answer parts of this question.
The setting of value for global variable inside of the .then callback is correct and you’ll have the value inside the “then” block. You can console.log inside of it and check.
The console.log outside in the “global” scope runs even before the the promise is resolved. Remember that java script is even driven. It registers the api call and continues executing the next line of it can. Which is why you’ll see an undefined value of token.
If all your subsequent requests depend on the auth token and you need to call some other API in the same call, you’ll have to do it in the .then call or create a promise chain with multiple .then which is essentially the main benefit of Promises. Previous result is passed on to the next promise.
I am writing a library in nodejs, that is wrapping another library. my code is something like this:
function wrapper(functionToWrap) {
return function(param1, param2) {
try {
return functionToWrap(param1, param2);
} catch(err) {
console.log(err);
throw err;
} finally {
finalizeWrapping();
}
}
}
the problem is that my finalizeWrapping function is a function that waits for promises that i collect (by placing some hooks before calling functionToWrap on some of the async apis it uses) to resolve, and only then acts, something like this:
function finalizeWrapping() {
Promise.all(pendingPromises).then(function(values) {
//finalize the wrapping
console.log('all promises fulfilled!');
});
}
the issue is that the error is thrown and node exits (this error should not be handled, since the wrapped function doesn't handle it) before all the promises are resolved and the then block is executed.
my question is: is there anything i can do to work around this, meaning throwing the error to the user appropriately and finish executing the then block, or do i have to change the way i hook the apis to be synchronous and not use a promise?
Thanks in advance to all the helpers :)
EDIT: an attempt to make my question clearer - functionToWrap is not my function, it is a function of a different library (and it can change - meaning i want my code to be able to wrap as many functions as possible). this function is allowed to use async apis (which i may be trying to monkeypatch), and basically it should have as least restrictions as possible - i want the user to be able to write any function and me being able to wrap it.
Not sure if the following can help, you may not have enough reputation to comment although I think you can comment on your own question and it's answers.
const wrapper = functionToWrap =>
function() {
//special type to indicate failed call to functionToWrap
const Fail = function(reason){this.reason=reason;};
//does not matter how many argument. Assuming functionToWrap
// does not rely on "this". If it does then also pass the
// object that functionToWrap is on and replace null with that object
return Promise.resolve(Array.from(arguments))
.then(
//if functionToWrap is on an object pass it to wrapper
// and replace null with that object
args=>functionToWrap.apply(null,args)
)
.catch(
//if functionToWrap throws an error or rejects we will catch it here
// and resolve with a special Fail type value
err=>{
console.log(err);
return new Fail(err)
}
).then(
//since promise cannot fail (its rejection is caught and resolves with Fail)
// this will always be called
//finalize should return Promise.all... and maybe not use a shared
// variable called pendingPromises, global shared mutable variables in async
// functions is asking for trouble
result=>finalizeWrapping().then(
()=>
//if functionToWrap rejected or thew the result will be a Fail type
(result && result.constructor === Fail)
? Promise.reject(result.reason)//reject with the original error
: result//resolve with the functionToWrap result
)
);
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 6 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I have Node.js application. Why these two code fragments do not work in the same way?
1)
function myFn1() {
return new Promise(function(resolve, reject) {
myFn2().then(function(url) {
resolve(url);
});
});
}
2)
function myFn1() {
return new Promise(function(resolve, reject) {
myFn2().then(resolve);
});
}
Common:
function myFn2() {
return new Promise(function(resolve, reject) {
var url = 'example.com';
resolve(url);
});
}
I call it with
myFn1().then(function(url) {
console.log(url);
});
With code 1) url is passed properly, but with code 2) url is undefined.
Do I not pass one-argument function in both cases? What is the difference?
First off, avoid the promise anti-pattern. When you already have a promise, just use it and return it. Don't wrap it in a new promise. Besides being inefficient, it's real easy to make mistakes, particularly with error handling (which you have).
So, what you should be doing is this:
function myFn1() {
return myFn2().then(function(url) {
// do some modification to url and then return that
// or some other processing here
return url;
});
}
There is simply no need to wrap the returned promise from myFn2() in another promise. In your specific case when doing so, you silently ate any errors from that inner promise and they were not propagated to the caller of myFn1() which is nearly always a bug, sometimes a very serious bug.
And, if you really have nothing to do inside the .then() handler, then you don't even need it either:
function myFn1() {
// some code here
return myFn2();
}
As to the original question, your two code fragments 1) and 2) work the same way and have no meaningful behavior differences other than one makes an extra function call and uses a little more stack to do so.
When you do this:
myFn2().then(resolve);
You're telling .then() to call resolve with whatever argument would normally be passed to the .then() handler. Since that argument in your case is url, then:
.then(resolve);
is exactly the same as:
.then(function(url) {
resolve(url);
});
They both call resolve with exactly the same argument. The first is a shorthand and should be used when the argument that .then() will use for it's callback is exactly the argument you want to your function. The second should be used if the arguments for your function are not exactly the same or, obviously, if you have more than a single function call to do in the .then() handler. So, if you wanted to add a ".jpg" extension to the URL before calling resolve, then you'd have to do:
.then(function(url) {
resolve(url + ".jpg");
});
With code 1) url is passed properly, but with code 2) url is
undefined. Do I not pass one-argument function in both cases? What is
the difference?
Assuming the promise returned by myFn2() resolves to url, then there should be no difference between your scenario #1 and #2. The promise returned by myFn1() should resolve to the same value either way.
Now, if you put some code in a .then() handler and forget to return the desired value from that .then() handler, then the resolved value of the promise becomes undefined which may be what is happening in your real code. So, if you do this:
function myFn1() {
return myFn2().then(function(url) {
console.log(url);
});
}
myFn1().then(function(url) {
console.log(url); // will be undefined
})
Because you didn't return anything from the .then() handler inside of myFn1. That means the return value is undefined so the promise took on that return value. Just remember, if you want your promise to have a specific resolved value, you have to return it from any .then() handlers in the chain.
function myFn1() {
return myFn2().then(function(url) {
console.log(url);
return url; // make sure the promise retains this resolved value
});
}
This question already has an answer here:
catch reject from promise
(1 answer)
Closed 6 years ago.
I am using csv-parse for stream parsing. For each record, I need to call some function mapper.process(). Since the latter function returns a promise, a wrapped it with co and prefixed yield.
parser.on('readable', function() {
var record;
while (record = parser.read()) {
return co(function*() {
yield mapper.process(record);
});
}
});
Without the addition (removing lines 4, 6 and yield), everything works fine. However, using the parser as shown above, thrown errors are swallowed.
How to fix this?
The problem here is that any thrown error will disappear because there is no catch handler after the co function.
But more importantly, the return statement inside the while loop will cause the whole function to return, so if you have multiple records in the buffer, you won't reach them.
You can write the following code to make it work:
parser.on('readable', function() {
return co(function* () {
var record;
while (record = parser.read()) {
const result = yield mapper.process(record);
// do something with the result..
console.log('result is ', result);
}
})
.catch((err) => console.error(err));
});
BUT, please be aware that because you're dealing with asynchronous code inside the "readable" callback, you'll cause the function to return immediately. This behaviour will cause the "finish" event to be called by the parser at the end of the stream and probably before you've actually finished processing the data.