I've been reading up on promises for a few hours and I'm loosing my mind here. According to what I've read in SO and articles on google. To get the value of a response in a variable I have to use async and await. So going that route I've written this code:
async function getZpid() {
let response = await function getZillowZpid(){
zillow.get('GetSearchResults', parameters)
.then(results => {
let zpidResponse = results.response.results.result[0].zpid;
console.log("i ran");
return zpidResponse;
});
}
}
getZpid();
Here I would expect that when getZpid() runs "response" would wait for the function get ZillowZpid to be done. Once it would be completed it would console.log "i ran" and then return the zpidResponse.
I get no error but the console.log never appears. Ultimately the console.log is just a test what I am trying to do is get zpidResponse in to a variable I could use outside the function. Any help would be greatly appreciated!
You are defining an extraneous function with await function getZillowZpid() which you never call. This is why you see no error or results. If you log the variable response in your function above you will see that it is something [Function: getZillowZpid], you've defined a function and assigned it to response which is certainly not what you want.
Since zillow.get returns a promise, you can just await that. Here's an example with a mocked zillow object:
// fake the zillow object
let zillow = {
get() {
return Promise.resolve({response: {results: {result: [{zpid: "Some data"}]}}})
}
}
async function getZpid() {
let parameters = {}
// zillow.get returns a promise, you can use await to get the returned value
let response = await zillow.get('GetSearchResults', parameters)
.then(results => {
let zpidResponse = results.response.results.result[0].zpid;
console.log("i ran");
return zpidResponse;
});
console.log(response)
}
getZpid();
FYI, if you're using async/await it's cleaner to avoid the then() although you still should add some error-checking:
// fake zillow
let zillow = {
get() {
return Promise.resolve({response: {results: {result: [{zpid: "Some data"}]}}})
}
}
async function getZpid() {
let parameters = 0
let response = await zillow.get('GetSearchResults', parameters)
let zpidResponse = response.response.results.result[0].zpid;
console.log(zpidResponse)
return zpidResponse
}
getZpid();
Related
I wast trying to fetch some data in componentDidMount and then set it to state, wrote an async await function for the same. But if i was trying to set the state with the values right after await, the value was getting set to a pending promise but console logging would give the correct output.
For that reason i called the getData().then() to set the data, why it was giving pending promise can someone clear the concept out here?
componentDidMount() {
async function getData() {
const baseUrl = `https://........`;
const response = await fetch(baseUrl);
if (response.status === 200) {
const json = await response.json();
const { data } = json;
//console.log(data) =>correct output
return data;
}
return null;
}
getData().then(data => {
this.setState({ names: data });
});
}
You can simply do it like that:
componentDidMount() {
const baseUrl = `https://........`;
fetch(baseUrl)
.then((response) => response.json())
.then(result => {
this.setState({ names: result.data});
});
}
getData is an async function that you syncronize your fetch call inside. So it returns a promise. You're console logging inside that function after response fetched. So it logs the data.
You can think it as Fetch function that you use, you're awaiting it because it's a async function and you should await for the response. It's the same for the getData too. No matter how you wait, use then or await.
The 1st example logs the resolved value of the promise from the fetch.
The 2nd example logs the pending promise object to the console which I then have to .then((res) => {console.log(res)}) to get the resolved value.
I'm using async functions so I thought both examples were equivalent...?
I have not shown my API key but it works when I use it in the code.
1st Example:
const apiKey = 'somekey';
const city = 'Berlin'
const getWeather = async (cityArg, apiKeyArg) => {
let city = cityArg;
let apiKey = apiKeyArg;
try{
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`);
if(response.ok) {
let jsonResponse = await response.json();
console.log(jsonResponse);
//return jsonResponse;
}
} catch(error) {
console.log(error);
}
}
getWeather(city, apiKey);
//console.log(getWeather(city, apiKey));
2nd Example:
const apiKey = 'somekey';
const city = 'Berlin'
const getWeather = async (cityArg, apiKeyArg) => {
let city = cityArg;
let apiKey = apiKeyArg;
try{
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`);
if(response.ok) {
let jsonResponse = await response.json();
//console.log(jsonResponse);
return jsonResponse;
}
} catch(error) {
console.log(error);
}
}
//getWeather(city, apiKey);
console.log(getWeather(city, apiKey));
The reason is that you are awaiting inside that async function, but not in the console.log at the bottom.
Anything outside of that async is going to continue on running as normal. So the console.log(getWeather(city, apiKey) keeps running even though that function has not gotten a response yet. There are a few solutions. First, you could await getWeather, which requires wrapping it in a function.
await function secondFunc(){
console.log(await getWeather(city, apiKey));
}
secondFunc();
In my opinion, the better way is to use .then. I almost always use it, it is cleaner and more logical to me. Don't forget that you can chain promise statements.
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`)
.then(response => response.json())
.then((response)=>{
console.log(response);
//Other code to do stuff with the response
})
.catch((error)=>{
console.log(error);
});
Another way to think of it is that the getWeather is Async, which will wait for a response, and return a promise in the meanwhile. But console.log is not async. So console.log keeps running as usual, but it has only recieved a Promise from getWeather, because that function is not resolved.
Hope that is clear. If you don't quite understand, let me know and I will do my best to explain further.
async functions return promises and since console.log isn't an async function it won't wait for getWeather() to resolve and will just log pending
hope that clears it up
id recommend just using .then()
//you could do
getWeather(city,ApiKey).then((response) =>{console.log(response));
hope that was helpful
In the following code I wrote to get data from an API, I am getting promises as an output instead of data. What am I missing? Can someone please help?
const axios = require('axios');
const ageFinder = async (userName) => {
try {
let userDetails =await axios.get(`https://hacker-news.firebaseio.com/v0/user/${userName}.json`)
let user =userDetails.data
return user
} catch(err) {
console.log(err.message)
}
}
console.log(ageFinder("someUser"))
As per the MDN page on async functions, any function declared async returns a promise, which resolves whatever the function returns or rejects with an error, if any is encountered within the function (see "Return Value" section of page linked above).
So you will need to put your function call ageFinder("someUser") in another async function and await its result before logging, or you may use .then().
An async function always returns a promise. To use it you need to await it in another async function. If you do not want to await in another async function you may use it with the alternative then method. For example:
ageFinder("someUser")
.then((response) => {
console.log(response);
}).
.catch((err) => {
console.log(err);
});
First of I'm really new to Javascript and programming in general and
This is a small part of code that is suppose to take the Json object filter it to the single string "poster_path" in the array and then send out an alert and console log it.
Now on the console log I get the desired string but the alert gives an "[Object promise]" instead of the string
async function getposter()
{
let response = await fetch('https://api.themoviedb.org/3/discover/movie?api_key=XXXXX&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1');
let poster = await response.json()
.then(poster => console.log(poster.results[0].poster_path));
return poster
}
alert(getposter())
getposter() is a promise, you need to await them to resolver before use.
An better example of how you can use or handle with your request is the code below:
async function getposter() {
const response = await fetch(
'https://api.themoviedb.org/3/discover/movie?api_key=XXXXX&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1'
);
const poster = await response.json()
const { poster_path } = poster.results[0];
return poster_path
}
(async () => {
try {
alert(await getposter());
} catch (error) {
alert(error.message);
}
})();
Why the output shows "Promise { }" when it expected to shows "Bienvenue"
const translate = require('google-translate-api');
async function translateSentence(sentence, languebase, languagetranslation) {
var sentenceTranslated = await translate(
sentence,
{ from: languebase, to: languagetranslation });
return sentenceTranslated.text;
}
var Translatedtext = translateSentence("Welcome", "en", "fr");
console.log(Translatedtext);
UPDATE:
I'm trying to return the translated data into JSON here is what I'm trying to do:
data = new Object();
data.Translatedtext = Translatedtext;
var string = JSON.stringify(data);
console.log(JSON.parse(string));
The out shows as { Translatedtext: {} } and I expected something like { Translatedtext: {Bienvenue} }
Because async functions return promises, so Translatedtext is a reference to a promise, and when you dump it out, you see the details of that promise, including the fact that it's pending.
If you meant to get the result, you'd have to await it (or use then):
var Translatedtext = await translateSentence("Welcome", "en", "fr");
// ------------------^
console.log(Translatedtext);
(handling the exception if it rejects), or
translateSentence("Welcome", "en", "fr")
.then(Translatedtext => {
console.log(Translatedtext);
})
.catch(err => {
// Handle the fact an error occurred
});
Note that to use await, you'd have to be in an async function.
If your code is written with async/await it does not mean that you can get the value in not an async function. Your function just returns the Promise. Anyway you need to write like
translateSentence("Welcome", "en", "fr").then(text => console.log(text));
or call this function in the another async function
async anotherFunction() {
const text = await translateSentence("Welcome", "en", "fr");
console.log(text);
}
Assuming translate is returning a promise, we could make an async function and wait for translateSentence to do it's thing then add the text to the object.
This would be done like this:
async function performOperations(){
let Translatedtext = await translateSentence("Welcome", "en", "fr")
data = new Object();
data.Translatedtext = Translatedtext;
var string = JSON.stringify(data);
console.log(JSON.parse(string));
}
performOperations()
What you are doing is checking the object before it has finished processing the request to the google api. So your data is more than likely getting to its location, its just that you're looking at the object too soon.
translateSentence is defined as async, thus it returns a Promise.
This means you need to wait for the promise resolve/reject before being able to access the result:
translateSentence("Welcome", "en", "fr")
.then(Translatedtext => {
var data = { Translatedtext };
var string = JSON.stringify(data);
console.log(JSON.parse(string));
})
.catch(err => console.log(err);