I'm not sure but i cant get the life of me to get this to resolve. its always pending. I'm not the best with promises so please help me out.
export async function getQuotes() {
const options = {
headers: {
"x-rapidapi-host": API_URL,
"x-rapidapi-key": API_KEY,
"content-type": "application/x-www-form-urlencoded",
},
};
let res = await axios
.post(API_URL, {}, options)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
return res;
}
and this is how i'm calling it:
const new_data = dataApi.getQuotes();
console.log(new_data);
with the new_data variable, i'd like to access the data that was returned. I keep getting back pending promises instead.
In javascript, async functions return a promise that resolves to their return value. In order to access the data, you have to wrap it in another async function and call await or use .then:
// Either:
async function main() {
const new_data = await dataApi.getQuotes();
console.log(new_data);
}
// or
dataApi.getQuotes().then(new_data => console.log(new_data));
Read more here.
You can wait until the promise has been fulfilled and then process the data as follows:
dataApi.getQuotes()
.then(function(new_data) {
console.log(new_data);
})
.catch(function (error) {
// error handling
});
You should use async/await or promises (.then and .catch) - but not both at the same time. You should also know that an async function always returns a Promise, so you can use it with the then/catch syntax if you want.
// Call with the then/catch syntax
dataApi.getQuotes()
.then((data) => console.log(data))
.catch((err) => console.error(err))
// Is the same that this call with async await
async function main() {
try {
const data = await dataApi.getQuotes();
console.log(data)
} catch (err) {
console.error(err)
}
}
About your function, you're using async/await here. So you may not use then/catch but await in its body.
export async function getQuotes() {
const options = {
headers: {
"x-rapidapi-host": API_URL,
"x-rapidapi-key": API_KEY,
"content-type": "application/x-www-form-urlencoded",
},
};
try {
let res = await axios.post(API_URL, {}, options);
console.log(response);
catch (error) {
console.log(error);
}
return res;
}
Related
currently, my code is returning a promise I need it to return the object that It is getting from the API call, how would do that?
import axios from 'axios';
const baseUrl = 'http://api.openweathermap.org/data/2.5/weather?';
const getWeatherData = async (city,country) => {
// const result=await axios.get(`http://api.openweathermap.org/data/2.5/weather?q=${city},${country}&APPID=180941f68139fba12f166dc35d9b688b`)
// return result;
axios({
method: "GET",
url: `http://api.openweathermap.org/data/2.5/weather?q=${city},${country}&APPID=180941f68139fba12f166dc35d9b688b`,
})
.then((response) => {
return response.data;
})
.catch((error) => {
console.log(error);
});
}
export default getWeatherData;
try {
const response = await axios({
method: "GET",
url: `http://api.openweathermap.org/data/2.5/weather?q=${city},${country}&APPID=180941f68139fba12f166dc35d9b688b`,
});
return response.data;
} catch (err) {
console.error(err);
}
You can rewrite your axios call this way since your function is flagged as async.
async functions always return promises. Within async functions, you can use await infront of other async functions or functions that return promises.
I'm trying to make a fetch call and it works but when I try to get the result from another function I always get undefined.
This is my code:
const fetch_output = async (data) => {
await fetch("execute_command", {
method: "POST",
credentials: "same-origin",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}).then(function(response) {
return response.json()
}).then(function(response) {
console.log(response)
//I get the correct response here
return response
}).catch(function(ex) {
console.log("Ha habido algĂșn error: ", ex)
})
}
const write_outputs = async () => {
for (const platform_id of platforms_ids) {
const data = {
platform_id:platform_id,
command:command
}
await fetch_output(data).then((resp)=>{
console.log(resp)
//I get undefined
})
}
}
write_outputs()
I've tried everything but I just don't know what am i doing wrong.
it is because an async function returns a promise that resolves to the returned value from the function
(async () => {})().then(value => console.log("value = ", value)); // undefined
(async () => {return 1})().then(value => console.log("value =" , value)); // 1
as you are not returning anything from fetch_output, it resolves to undefined
You should return from the fetch_output function instead of using await.
Also, because fetch is already a promise you can use a normal function instead of an async one
Because you call await fetch_output() you should not use .then() to retrieve its result. Drop the await.
Why? await replaces function().then().catch() with result = await function() in the way it handles a Promise or an async function. Use await or .then() but not both.
I am trying to get the value of asset:
const asset = getAssetInformation(11002);
function getAssetInformation(id) {
return axios({
method: 'GET',
url: "/asset-information",
params: {assetId: id}
});
}
console.log(asset);
The result is:
[object Promise]
How do I get the returned value from the request?
Using async and await is a practical way -
function axios(query) { // fake axios, for demo
return new Promise (r =>
setTimeout(r, 1000, { asset: query.params.assetId })
)
}
function getAssetInformation(id) {
return axios({
method: 'GET',
url: "/asset-information",
params: {assetId: id}
})
}
async function main() { // async
const asset = await getAssetInformation (11022) // await
console.log(asset)
}
main()
// 1 second later ...
// { asset: 11022 }
You will need to use .then function.
const asset = getAssetInformation(11002)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Promises return another promise.
The way to unpack and work with a promise is through the .then() function, which will run after the promise returns.
const asset = getAssetInformation(11002);
function getAssetInformation(id) {
return axios({
method: 'GET',
url: "/asset-information",
params: {assetId: id}
});
}
Asset here is a promise, you want to use a then on it to get the value.
Instead of..
const asset = getAssetInformation(11002);
use
getAssetInformation(11002)
.then((response) => {
//What you returned will be here, use response.data to get your data out.
} )
.catch((err) => {
//if there is an error returned, put behavior here.
})
It gets complicated to me when I mix the promise with subscribe and another async task together.
This is my auth service:
getCurrentUserToken(){
return new Promise((resolve,reject)=>{
firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
resolve(idToken)
}).catch(function(error) {
reject(error)
});
})
}
This is my HTTP service:
sendEmail(email) {
return this.authService.getCurrentUserToken().then(token => {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic server-Password',
})
};
let data = email
data['idToken'] = token
return this.http.post(this.apiServer + 'sendEmail', data, httpOptions)
})
}
This is how I call the sendEmail(email) function at the component:
Observable.fromPromise(this.httpService.sendEmail(element)).subscribe(
data3 => {
console.log(data3)
}, error => {
console.log(error)
}
))
I have to pass currentUserToken to the API to let the API authenticate the user session. Still, both of the the getCurrentUserToken() sendEmail() are running in async, so I have to use Promise to pass the Token to sendEmail() function, and let the sendEmail function to call the API to send the email.
Without the promise, I am able to subscribe to the http.post like this:
this.httpService.sendEmail(element).subscribe(
data3 => {
console.log(data3)
}, error => {
console.log(error)
}
))
Unfortunately, I screwed it up when I added the promise into it, and the console.log is returning this:
Observable {_isScalar: false, source: Observable, operator: MapOperator}
Please advise on how to subscribe to the http.post that is placed inside the Promise.
There's seriously no need of Complicating things here.
I'll use async/await syntax here and for that, we'll have to work with Promises instead of Observables. Good thing is, we can leverage the toPromise() method on an Observable value to change it to a Promise
Focus on my comments in the code as well
Here's the implementation
For getCurrentUserToken
getCurrentUserToken() {
return firebase.auth().currentUser.getIdToken(true);
// This will already return a Promise<string>
// So no need to do a .then and then return from there.
}
For sendEmail
async sendEmail(email) {
// Since getCurrentUserToken returns a Promise<string> we can await it
const token = await this.authService.getCurrentUserToken();
// token will now have the Current User Token
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic server-Password',
})
};
let data = email
data['idToken'] = token
return this.http.post(this.apiServer + 'sendEmail', data, httpOptions).toPromise();
// Notice how we're calling the .toPromise() method here
// to change Observable into a Promise
}
How to use it?
This code will go in your Component Method where you were previously calling this.httpService.sendEmail. DO MAKE SURE TO MARK THAT FUNCTION AS async THOUGH.
// We can only await something in a function which is declared of type async
async sendEmail() {
try {
const data = await this.httpService.sendEmail(element);
// Since sendEmail again returns a Promise, I can await it.
console.log(data);
} catch (error) {
console.log(error);
}
}
Why don't we use Observable instead of Promises here.
getCurrentUserToken() {
return new Observable(obs => {
firebase
.auth()
.currentUser.getIdToken(/* forceRefresh */ true)
.then(function(idToken) {
obs.next(idToken);
obs.complete();
})
.catch(function(error) {
obs.error(error);
});
});
}
sendEmail(email): Observable {
return new Observable(obs => {
this.authService.getCurrentUserToken().subscribe(token => {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Basic server-Password'
})
};
let data = email;
data['idToken'] = token;
this.http
.post(this.apiServer + 'sendEmail', data, httpOptions)
.subscribe(
result => {
obs.next(result);
obs.complete();
},
error => {
obs.error();
}
);
});
});
}
// now call the service from Component like this.
this.httpService.sendEmail(element).subscribe(
data3 => {
console.log(data3)
}, error => {
console.log(error)
}
));
I'm having some problems getting a response from a chained Promise.
I have my component where the chain starts
component
componentDidMount = async ()=> {
try{
const products = await post('payments/getProducts', {});
console.log(products);
} catch(e) {
console.log(e)
}
}
This component calls my API helper:
async function post(url, data) {
token = null;
if (firebase.auth().currentUser) {
token = await firebase.auth().currentUser.getIdToken();
}
try {
const response = axios({
method: 'POST',
headers: {
Authorization: `${token}`,
},
data,
url: `${API_URL}${url}`,
})
return response;
} catch(e){
Promise.reject(e);
}
}
and my API Helper then calls a Firebase Cloud Function which calls Stripe:
paymentRouter.post('/getProducts', (req, res) => {
return stripe.products.list()
.then(products => {
console.log(products.data)
return products.data;
})
.catch(e => {
throw new functions.https.HttpsError('unknown', err.message, e);
})
})
Calling the function is no problem, and my Cloud Function logs out the product data, but I can't get the response to log in my API Helper nor my component.
Promise.reject(e);
That is completely senseless as it creates a new rejected promise that is not used anywhere. You could await it so that it gets chained into the promise returned by the async function, or you just return the promise from axios:
async function post(url, data) {
let token = null; // always declare variables!
if (firebase.auth().currentUser) {
token = await firebase.auth().currentUser.getIdToken();
}
return axios({
method: 'POST',
headers: {
Authorization: `${token}`,
},
data,
url: `${API_URL}${url}`,
});
}
Now the errors don't go into nowhere anymore and you can probably debug the problem :)