We have a requirement where we want to build api calls based on query param array for (contentId[]=1&contentId[]=2....and so on ), and then make async calls appending id to the api end point e.g http://xxxx/content/contentId.
Based on the response we need to aggregate and wrap the content with fields contentId, responsecode that we receive when we hit the individual api endpoints
{
{ "contentd": "1",
"responsecode": 200,
"messsage": "",
content{
}
}
{ "contentd": "2",
"responsecode": 200,
"messsage": "",
content{
}
...
}
We are using promise to do the same. I used promise all as below.
Promise.all(req.query.contentId
.map(function (contentId) {
console.log('processing the content id'+contentId);
return getContent(contentId);
}))
.then(function (all_content) {
//convert each resolved promised into JSON and convert it into an array.
res.json(all_content.map(function (content) {
return JSON.parse(content)
}));
})
.catch(function(rej) {
//here when you reject the promise
console.log("404 received"+rej);
}) ;
} catch (e) {
res.send(e.message);
}
});
// this is the function that makes the call to the backend. Note usage of request promise
function getContent(contentId) {
console.log('content id received to fetch the content'+contentId);
var options = {
uri: 'http://xxxxx/api/content/'+contentId,
headers: {
'Authorization': 'Basic YWRtaW46YWRtaW4='
},
qs: {
_format: 'json'
}
};
return rp(options);
}
Problems -The problem we are facing is that for the calls when we get http status code as 200 the result comes fine. However, for http status code 404(not found) the processing is not done. It seems to fail fast.
Also, how do I insert own fields for response, status while processing the content response as above in JSON.parse. thanks
If you read about Promise.all(), that's what it does. If any promise you pass it rejects, it immediately rejects the overall Promise.all() promise and you don't get the other results.
If you want all the other results, you have to either catch any rejections earlier so that Promise.all() never sees them or use a different way of tracking all the promises that is designed to get all respones, whether any reject or not.
You can catch the rejection earlier to "hide" it form Promise.all() by doing something like this and you also have to skip the JSON.parse() of any error objects that are passed through.
Promise.all(req.query.contentId
.map(function (contentId) {
console.log('processing the content id'+contentId);
// catch errors here and make the resolved value be the error object
// so Promise.all() processing continues on the other requests
return getContent(contentId).catch(e => e);
}))
.then(function (all_content) {
//convert each resolved promised into JSON and convert it into an array.
res.json(all_content.map(function (content) {
// make sure we don't try to parse things that are already objects
// like error objects
if (typeof content !== "string") {
return content;
} else {
return JSON.parse(content);
}
}));
}).then(function(results) {
// remove any error objects
// and probably log them to so they aren't just silently eaten
return results.filter(item => !(item instanceof Error));
})
Then, later down stream while using this array of results, you need to skip any error objects in the results.
Alternatively, you could make the results into some sort of no-op result that wouldn't affect your downstream processing or you can build a different array that had all error results filtered out of it.
And, if you want some prewritten code that just gets all the responses (including error results), that is often called Promise.settle(). There are several implementations of a Promise.settle() that you can use here:
ES6 Promise.all() error handle - Is .settle() needed?
Also, how do I insert own fields for response, status while processing the content response as above in JSON.parse.
You can change this:
return JSON.parse(content);
to something like this:
let obj = JSON.parse(content);
obj.someOtherProp = 'myvalue';
return obj;
return getContent(contentId);
Here you return the promise to Promise.all. so if the promise fails, it will trigger the Promise.all catch and all routes fail. So we need to catch earlier, so right there:
return getContent(contentId).catch( e => e);
That means in case of an error, proceed with the error as result. As the JSON.parse would fail then, you could return a json string instead:
return getContent(contentId).catch( e => '{"error":500}');
For the second question:
You may want to assign additional properties to the returned result:
return Object.assign( JSON.parse(content), {
what: "ever"
});
Related
I am using the following function which is supposed to have a callback input:
https://mongoosejs.com/docs/api.html#model_Model.findOneAndRemove
I have the following Mutation object that is supposed to delete a particular medicine from the database, and then remove all of the instances of its medicineId from the arrays of all of the Day entries that contain the id.
deleteMedicine: {
type: MedicineType,
args: {
id: { type: new GraphQLNonNull(GraphQLID) }
},
async resolve (parent, args) {
let res = Medicine.findOneAndRemove({ _id: args.id }, async (err, doc) => {
if (err === null && doc === null || doc === null) {
return;
} else if (err) {
console.error(err);
return;
} else {
return await Promise.all(doc.dayNames.map(dayName => {
return DayOfWeek.findByIdAndUpdate(dayName, { $pull: { medicineIds: doc._id }})
.catch((error1) => console.error(error1));
})).catch((error2) => console.error(error2));
}
});
await res;
return res;
}
}
findOneAndRemove successfully deletes the document that has args.id in the Medicine collection, but when It calls the callback function, sometimes it passes null to doc and so the callback function doesn't consistently execute properly.
Also I am getting an unhandled error warning even though I am catching all errors. \
I added logic to handle when err and doc are both null according to this post:
https://github.com/Automattic/mongoose/issues/5022
You should only uses Promises, not callbacks, with GraphQL.js. If the library you're using doesn't support Promises, then you'll need to wrap each callback in a Promise. However, mongoose has great Promise support -- you just omit the callback from your method call and the call will return a Promise.
To avoid "callback hell" when using Promises and issues with properly chaining your Promises, it's generally preferable to utilize async/await syntax. Your cleaned up resolver would look something like:
async resolve (parent, args) {
// Omit the callback to get a Promise and then await the result
const medicine = await Medicine.findOneAndRemove({ _id: args.id })
// If a medicine with that ID couldn't be found, we'll get a null
if (medicine) {
// Make sure we await the Promise returned by Promise.all
await Promise.all(doc.dayNames.map(dayName => DayOfWeek.findByIdAndUpdate(
dayName,
{ $pull: { medicineIds: doc._id } }
))
}
// Make sure we return the appropriate result depending on the field's type
return medicine
}
Typically when dealing with Promises, we use the catch method (or try/catch with async/await) in order to handle errors. However, this is only necessary inside a resolver if you want to mask or otherwise format your error -- otherwise, GraphQL will happily catch any errors for you and return them in the response. However, this only works if your Promises are correctly chained and the resolver returns a Promise. If you end up with an "orphan" Promise that's not awaited, you'll see unhandled error warnings.
I'm using Promises to automatically fill up my dropdowns on page load (I have multiple dropdowns on the page).
Here is the code I use to return the following:
$(document).ready(function(){
var urls = ['getBrands', 'getTags'];
Promise.all(urls.map(u=>fetch(u))).then(
responses => Promise.all(responses.map(res => res.json()))
).then(
texts=>console.log(texts)
).then(
result => console.log(result[0]) //This is where the error is
)
});
This prints the response to the console correctly, but throws an error when I try to read the individual result. The error is Uncaught(in promise) TypeError: cannot read property '0' of undefined
The problem is your first fulfillment handler returns undefined, which becomes the fulfillment value of the promise it returns.
If you just remove it, your second fulfillment handler will see the values.
$(document).ready(function(){
var urls = ['getBrands', 'getTags'];
Promise.all(urls.map(u=>fetch(u))).then(
responses => Promise.all(responses.map(res => res.json()))
).then(
result => console.log(result[0])
)
});
Alternatively, have it return what it receives:
$(document).ready(function(){
var urls = ['getBrands', 'getTags'];
Promise.all(urls.map(u=>fetch(u))).then(
responses => Promise.all(responses.map(res => res.json()))
).then(texts => {
console.log(texts);
return texts;
}).then(
result => console.log(result[0])
)
});
Side note: That code breaks one of the Rules of Promises, which is:
Handle rejection, or pass the promise chain to something that will.
You probably want to add a rejection handler via .catch.
Side note 2: Assuming fetch is the standard fetch, your code is missing a check for success. This is a footgun in the fetch API (I write about it here). Fixing it:
Promise.all(
urls.map(u=>fetch(u).then(response => {
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return res.json();
}))
).then(texts => {
Note that that eliminates the need for the second Promise.all as well, but handling each fetch individually earlier.
I'm trying to build a backend webhook for the Google Assistant that reads records from DynamoDB.
This is my code:
// Handle the Dialogflow intent named 'trip name'.
// The intent collects a parameter named 'tripName'.
app.intent('trip name', (conv, {tripName}) => {
const dynamoDb = IS_OFFLINE === true ?
new AWS.DynamoDB.DocumentClient({
region: 'ap-south-1',
// endpoint: 'http://127.0.0.1:8080',
}) :
new AWS.DynamoDB.DocumentClient({
region: 'ap-south-1',
// endpoint: 'http://127.0.0.1:8080',
});
const params = {
TableName: ACTIVITIES_TABLE
Key: {
'name':tripName
}
};
// conv.close('error retrieving!'); THIS WORKS
dynamoDb.get(params, (error, result) => {
// conv.close('error retrieving!'); THIS DOES NOT
if (error) {
conv.close('error retrieving!');
}
else {
conv.close(JSON.stringify(result, null, 2));
}
});
});
If I were to use conv from outside the DynamoDB function it works, but from inside it does not and return this error:
2019-08-03T03:56:22.521Z ** ERROR Error: No response has been set. Is this being used in an async call that was
not returned as a promise to the intent handler?
It made me conclude that maybe I'm not allowed to access an arrow function argument from another nested arrow function?
I'm using Actions on Google Client Library.
The problem has nothing to do with accessing parameters from one arrow function in another - that is perfectly allowed.
The issue is, as the error message suggests, that you are using an asynchronous function (a function that requires a callback0, but not returning a Promise object. The actions-on-google library requires you to return a Promise from your Intent Handler if you're doing any asynchronous operations so it knows to wait for those operations to complete.
You'll need to switch from using a callback in your call to dynamoDb.get() to using a Promise instead. To do this, you need to not include the callback function, so get() returns an AWS.Request object. This object has a promise() method, so you would use this to return the results from the Promise and then() chain. (And you must return this Promise.)
In your case, it might look something like this
return dynamoDb.get(params).promise()
.then( result => {
conv.close(JSON.stringify(result, null, 2));
})
.catch( error => {
conv.close('error retrieving!');
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 months ago.
I am trying to use a Node.JS application to make and receive API requests. It does a get request to another server using Axios with data it receives from an API call it receives. The second snippet is when the script returns the data from the call in. It will actually take it and write to the console, but it won't send it back in the second API.
function axiosTest() {
axios.get(url)
.then(function (response) {
console.log(response.data);
// I need this data here ^^
return response.data;
})
.catch(function (error) {
console.log(error);
});
}
...
axiosTestResult = axiosTest();
response.json({message: "Request received!", data: axiosTestResult});
I'm aware this is wrong, I'm just trying to find a way to make it work. The only way I can seem to get data out of it is through console.log, which isn't helpful in my situation.
The issue is that the original axiosTest() function isn't returning the promise. Here's an extended explanation for clarity:
function axiosTest() {
// create a promise for the axios request
const promise = axios.get(url)
// using .then, create a new promise which extracts the data
const dataPromise = promise.then((response) => response.data)
// return it
return dataPromise
}
// now we can use that data from the outside!
axiosTest()
.then(data => {
response.json({ message: 'Request received!', data })
})
.catch(err => console.log(err))
The function can be written more succinctly:
function axiosTest() {
return axios.get(url).then(response => response.data)
}
Or with async/await:
async function axiosTest() {
const response = await axios.get(url)
return response.data
}
Guide on using promises
Info on async functions
I know this post is old. But i have seen several attempts of guys trying to answer using async and await but getting it wrong. This should clear it up for any new references
UPDATE: May 2022
This answer is still having lots of interest and have updated it to use arrow functions
const axiosTest = async () {
try {
const {data:response} = await axios.get(url) //use data destructuring to get data from the promise object
return response
}
catch (error) {
console.log(error);
}
}
you can populate the data you want with a simple callback function,
let's say we have a list named lst that we want to populate,
we have a function that pupulates pupulates list,
const lst = [];
const populateData = (data) => {lst.push(data)}
now we can pass the callback function to the function which is making the axios call and we can pupulate the list when we get data from response.
now we make our function that makes the request and pass populateData as a callback function.
function axiosTest (populateData) {
axios.get(url)
.then(function(response){
populateData(response.data);
})
.catch(function(error){
console.log(error);
});
}
The axios library creates a Promise() object. Promise is a built-in object in JavaScript ES6. When this object is instantiated using the new keyword, it takes a function as an argument. This single function in turn takes two arguments, each of which are also functions — resolve and reject.
Promises execute the client side code and, due to cool Javascript asynchronous flow, could eventually resolve one or two things, that resolution (generally considered to be a semantically equivalent to a Promise's success), or that rejection (widely considered to be an erroneous resolution). For instance, we can hold a reference to some Promise object which comprises a function that will eventually return a response object (that would be contained in the Promise object). So one way we could use such a promise is wait for the promise to resolve to some kind of response.
You might raise we don't want to be waiting seconds or so for our API to return a call! We want our UI to be able to do things while waiting for the API response. Failing that we would have a very slow user interface. So how do we handle this problem?
Well a Promise is asynchronous. In a standard implementation of engines responsible for executing Javascript code (such as Node, or the common browser) it will resolve in another process while we don't know in advance what the result of the promise will be. A usual strategy is to then send our functions (i.e. a React setState function for a class) to the promise, resolved depending on some kind of condition (dependent on our choice of library). This will result in our local Javascript objects being updated based on promise resolution. So instead of getters and setters (in traditional OOP) you can think of functions that you might send to your asynchronous methods.
I'll use Fetch in this example so you can try to understand what's going on in the promise and see if you can replicate my ideas within your axios code. Fetch is basically similar to axios without the innate JSON conversion, and has a different flow for resolving promises (which you should refer to the axios documentation to learn).
GetCache.js
const base_endpoint = BaseEndpoint + "cache/";
// Default function is going to take a selection, date, and a callback to execute.
// We're going to call the base endpoint and selection string passed to the original function.
// This will make our endpoint.
export default (selection, date, callback) => {
fetch(base_endpoint + selection + "/" + date)
// If the response is not within a 500 (according to Fetch docs) our promise object
// will _eventually_ resolve to a response.
.then(res => {
// Lets check the status of the response to make sure it's good.
if (res.status >= 400 && res.status < 600) {
throw new Error("Bad response");
}
// Let's also check the headers to make sure that the server "reckons" its serving
//up json
if (!res.headers.get("content-type").includes("application/json")) {
throw new TypeError("Response not JSON");
}
return res.json();
})
// Fulfilling these conditions lets return the data. But how do we get it out of the promise?
.then(data => {
// Using the function we passed to our original function silly! Since we've error
// handled above, we're ready to pass the response data as a callback.
callback(data);
})
// Fetch's promise will throw an error by default if the webserver returns a 500
// response (as notified by the response code in the HTTP header).
.catch(err => console.error(err));
};
Now we've written our GetCache method, lets see what it looks like to update a React component's state as an example...
Some React Component.jsx
// Make sure you import GetCache from GetCache.js!
resolveData() {
const { mySelection, date } = this.state; // We could also use props or pass to the function to acquire our selection and date.
const setData = data => {
this.setState({
data: data,
loading: false
// We could set loading to true and display a wee spinner
// while waiting for our response data,
// or rely on the local state of data being null.
});
};
GetCache("mySelelection", date, setData);
}
Ultimately, you don't "return" data as such, I mean you can but it's more idiomatic to change your way of thinking... Now we are sending data to asynchronous methods.
Happy Coding!
axiosTest() needs to return axios.get, which in turn returns a Promise.
From there, then can be used to execute a function when said Promise resolves.
See Promise for more info.
Alternatively, await can be used from within the scope of some async function.
// Dummy Url.
const url = 'https://jsonplaceholder.typicode.com/posts/1'
// Axios Test.
const axiosTest = axios.get
// Axios Test Data.
axiosTest(url).then(function(axiosTestResult) {
console.log('response.JSON:', {
message: 'Request received',
data: axiosTestResult.data
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
IMO extremely important rule of thumb for your client side js code is to keep separated the data handling and ui building logic into different funcs, which is also valid for axios data fetching ... in this way your control flow and error handlings will be much more simple and easier to manage, as it could be seen from this
ok fetch
and this
NOK fetch
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function getUrlParams (){
var url_params = new URLSearchParams();
if( window.location.toString().indexOf("?") != -1) {
var href_part = window.location.search.split('?')[1]
href_part.replace(/([^=&]+)=([^&]*)/g,
function(m, key, value) {
var attr = decodeURIComponent(key)
var val = decodeURIComponent(value)
url_params.append(attr,val);
});
}
// for(var pair of url_params.entries()) { consolas.log(pair[0]+ '->'+ pair[1]); }
return url_params ;
}
function getServerData (url, urlParams ){
if ( typeof url_params == "undefined" ) { urlParams = getUrlParams() }
return axios.get(url , { params: urlParams } )
.then(response => {
return response ;
})
.catch(function(error) {
console.error ( error )
return error.response;
})
}
// Action !!!
getServerData(url , url_params)
.then( response => {
if ( response.status === 204 ) {
var warningMsg = response.statusText
console.warn ( warningMsg )
return
} else if ( response.status === 404 || response.status === 400) {
var errorMsg = response.statusText // + ": " + response.data.msg // this is my api
console.error( errorMsg )
return ;
} else {
var data = response.data
var dataType = (typeof data)
if ( dataType === 'undefined' ) {
var msg = 'unexpected error occurred while fetching data !!!'
// pass here to the ui change method the msg aka
// showMyMsg ( msg , "error")
} else {
var items = data.dat // obs this is my api aka "dat" attribute - that is whatever happens to be your json key to get the data from
// call here the ui building method
// BuildList ( items )
}
return
}
})
</script>
After 6 hours of fluttering, I realized it was a one-line problem. If you are interfering with the axios life-cycle, you may have forgotten this line:
componentDidMount() {
this.requestInterceptor = axios.interceptors.request.use((request) => {
this.updateApiCallFor(request.url, true);
return request;
});
this.responseInterceptor = axios.interceptors.response.use((response) => {
this.updateApiCallFor(response.config.url, false);
return response; // THIS LINE IS IMPORTANT !
}, (error) => {
this.updateApiCallFor(error.config.url, false);
throw error;
});
async makes a function return a Promise
await makes a function wait for a Promise
code async/await
// https://www.npmjs.com/package/axios
const axios = require('axios')
/* --- */
async function axiosTest() {
let promiseAxios = axios.get( 'https://example.com' )
/* --- */
console.log( await promiseAxios )
}
/* --- */
axiosTest()
replit.com Stackoverflow - Returning data from Axios API
replit.com Stackoverflow - How to return values from async
code async/await with return
// https://www.npmjs.com/package/axios
const axios = require('axios')
/* --- */
async function axiosTest() {
console.log( await promiseAxios() )
}
/* --- */
axiosTest()
/* --- */
// create function for promise axios and return it
function promiseAxios() {
return axios.get( 'https://example.com' )
}
replit.com Stackoverflow - Returning data from Axios API - return
replit.com Stackoverflow - How to return values from async - return
Try this,
function axiosTest() {
axios.get(url)
.then(response => response.data)
.catch(error => error);
}
async function getResponse () {
const response = await axiosTest();
console.log(response);
}
getResponse()
It works, but each function where you want to get the response needs to be an async function or use an additional .then() callback.
function axiosTest() {
axios.get(url)
.then(response => response.data)
.catch(error => error);
}
async function getResponse () {
axiosTest().then(response => {
console.log(response)
});
}
getResponse()
If anyone knows a way to avoid this please do tell.
Also checkout Katsiaryna (Kate) Lupachova's article on Dev.to. I think it will help.
async handleResponse(){
const result = await this.axiosTest();
}
async axiosTest () {
return await axios.get(url)
.then(function (response) {
console.log(response.data);
return response.data;})
.catch(function (error) {
console.log(error);
});
}
You can find check https://flaviocopes.com/axios/#post-requests url and find some relevant information in the GET section of this post.
You can use Async - Await:
async function axiosTest() {
const response = await axios.get(url);
const data = await response.json();
}
My code:
let AuthUser = data => {
return google.login(data.username, data.password).then(token => { return token } )
}
And when i try to run something like this:
let userToken = AuthUser(data)
console.log(userToken)
I'm getting:
Promise { <pending> }
But why?
My main goal is to get token from google.login(data.username, data.password) which returns a promise, into a variable. And only then preform some actions.
The promise will always log pending as long as its results are not resolved yet. You must call .then on the promise to capture the results regardless of the promise state (resolved or still pending):
let AuthUser = function(data) {
return google.login(data.username, data.password).then(token => { return token } )
}
let userToken = AuthUser(data)
console.log(userToken) // Promise { <pending> }
userToken.then(function(result) {
console.log(result) // "Some User token"
})
Why is that?
Promises are forward direction only; You can only resolve them once. The resolved value of a Promise is passed to its .then or .catch methods.
Details
According to the Promises/A+ spec:
The promise resolution procedure is an abstract operation taking as
input a promise and a value, which we denote as [[Resolve]](promise,
x). If x is a thenable, it attempts to make promise adopt the state of
x, under the assumption that x behaves at least somewhat like a
promise. Otherwise, it fulfills promise with the value x.
This treatment of thenables allows promise implementations to
interoperate, as long as they expose a Promises/A+-compliant then
method. It also allows Promises/A+ implementations to “assimilate”
nonconformant implementations with reasonable then methods.
This spec is a little hard to parse, so let's break it down. The rule is:
If the function in the .then handler returns a value, then the Promise resolves with that value. If the handler returns another Promise, then the original Promise resolves with the resolved value of the chained Promise. The next .then handler will always contain the resolved value of the chained promise returned in the preceding .then.
The way it actually works is described below in more detail:
1. The return of the .then function will be the resolved value of the promise.
function initPromise() {
return new Promise(function(res, rej) {
res("initResolve");
})
}
initPromise()
.then(function(result) {
console.log(result); // "initResolve"
return "normalReturn";
})
.then(function(result) {
console.log(result); // "normalReturn"
});
2. If the .then function returns a Promise, then the resolved value of that chained promise is passed to the following .then.
function initPromise() {
return new Promise(function(res, rej) {
res("initResolve");
})
}
initPromise()
.then(function(result) {
console.log(result); // "initResolve"
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("secondPromise");
}, 1000)
})
})
.then(function(result) {
console.log(result); // "secondPromise"
});
I know this question was asked 2 years ago, but I run into the same issue and the answer for the problem is since ES2017, that you can simply await the functions return value (as of now, only works in async functions), like:
let AuthUser = function(data) {
return google.login(data.username, data.password)
}
let userToken = await AuthUser(data)
console.log(userToken) // your data
The then method returns a pending promise which can be resolved asynchronously by the return value of a result handler registered in the call to then, or rejected by throwing an error inside the handler called.
So calling AuthUser will not suddenly log the user in synchronously, but returns a promise whose then registered handlers will be called after the login succeeds ( or fails). I would suggest triggering all login processing by a then clause of the login promise. E.G. using named functions to highlight the sequence of flow:
let AuthUser = data => { // just the login promise
return google.login(data.username, data.password);
};
AuthUser(data).then( processLogin).catch(loginFail);
function processLogin( token) {
// do logged in stuff:
// enable, initiate, or do things after login
}
function loginFail( err) {
console.log("login failed: " + err);
}
If that situation happens for a multiple values like an array.
[
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> }
]
You can use Promise.all() this will resolve all promises.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
See the MDN section on Promises. In particular, look at the return type of then().
To log in, the user-agent has to submit a request to the server and wait to receive a response. Since making your application totally stop execution during a request round-trip usually makes for a bad user experience, practically every JS function that logs you in (or performs any other form of server interaction) will use a Promise, or something very much like it, to deliver results asynchronously.
Now, also notice that return statements are always evaluated in the context of the function they appear in. So when you wrote:
let AuthUser = data => {
return google
.login(data.username, data.password)
.then( token => {
return token;
});
};
the statement return token; meant that the anonymous function being passed into then() should return the token, not that the AuthUser function should. What AuthUser returns is the result of calling google.login(username, password).then(callback);, which happens to be a Promise.
Ultimately your callback token => { return token; } does nothing; instead, your input to then() needs to be a function that actually handles the token in some way.
Your Promise is pending, complete it by
userToken.then(function(result){
console.log(result)
})
after your remaining code.
All this code does is that .then() completes your promise & captures the end result in result variable & print result in console.
Keep in mind, you cannot store the result in global variable.
Hope that explanation might help you.
I had the same issue earlier, but my situation was a bit different in the front-end. I'll share my scenario anyway, maybe someone might find it useful.
I had an api call to /api/user/register in the frontend with email, password and username as request body. On submitting the form(register form), a handler function is called which initiates the fetch call to /api/user/register. I used the event.preventDefault() in the beginning line of this handler function, all other lines,like forming the request body as well the fetch call was written after the event.preventDefault(). This returned a pending promise.
But when I put the request body formation code above the event.preventDefault(), it returned the real promise. Like this:
event.preventDefault();
const data = {
'email': email,
'password': password
}
fetch(...)
...
instead of :
const data = {
'email': email,
'password': password
}
event.preventDefault();
fetch(...)
...
Try this
var number1 = document.getElementById("number1");
var number2 = document.getElementById("number2");
startAsync.addEventListener("click", function() {
if (number1.value > 0 && number2.value > 0) {
asyncTest(parseInt(number1.value), parseInt(number2.value)).then(function(result) {
document.getElementById("promiseResolved").textContent = "promiseResolved: " + result
});
} else {
asyncTest(1, 2).then(function(result) {
document.getElementById("promiseResolved").textContent = "promiseResolved: " + result
});
}
});
async function asyncTest(a, b) {
return await (a + b);
};
<button id="startAsync">start Async function</button><br />
<input type="number" id="number1" /><br />
<input type="number" id="number2" /><br />
<span id="promiseResolved"></span><br />
Im my case (JS) I forgot to add await