I want to get a value from an API and save that value for later, but I'm having troubles.
I get the result I want when I use console.log(), but when I do exactly the same thing with "return()" I get this result:
Promise{< resolved >:"The value I want"}
I'll show you my code:
const getDataAA = async () => {
const response = await fetch("https://s3.amazonaws.com/dolartoday/data.json")
const data = await response.json()
console.log("async/await based")
console.log(data.USD.transferencia)
}
When I call getDataAA() I get what I want in the console, but I want to store that value in order to use it, so I changed "console.log(data.USD.transferencia)" for "return(data.USD.transferencia)".
Then I do something like this in order to save the value:
let dolarPrice = getDataAA()
Why when I use "console.log" I get the value but when I use "return" I get also the promise?
const getDataAA = async () => {
const response = await fetch("https://s3.amazonaws.com/dolartoday/data.json")
return response.json()
}
let response = await getDataAA();
console.log(response);
-- EDITED
so this one another example how use it.
the async method (getDataAA) have to return something.
everytime you need to call an async method you have to use await (
if you wait until it's completed)
everytime you use await the method must be async.
<!DOCTYPE html>
<html>
<script type="text/javascript">
var f = async () => {
const getDataAA = async () => {
const response = await fetch("https://s3.amazonaws.com/dolartoday/data.json")
return response.json()
}
let response = await getDataAA();
console.log(response);
}
f();
</script>
</html>
I discovered I way to solve this! I defined a variable outside the function and then the function stored the value I wanted inside that variable. This is my code:
const getDataAA = async () => {
const response = await fetch("https://s3.amazonaws.com/dolartoday/data.json")
const data = await response.json()
console.log("async/await based")
dolarPrice = (data.USD.transferencia)
}
let dolarPrice
getDataAA()
That way I stored the value inside the "dolarPrice" variable. Thanks all the people who answered my question, I found the solution thanks to all of you.
Related
I'm trying to get this function to asynchronously call an API and return the response's JSON. However, the function returns nothing, before the API call has returned and populated res.
I'm confused about the proper usage of asynchronous JavaScript in this use case.
From my understanding, once async has been declared in a function, then the code will pause whenever it hits an await until the await has returned a promise. But that obviously isn't the case. What am I missing?
let queryApi = async (query) => {
const url = "http://localhost:3000/test";
const response = await fetch(url)
const res = await response.json();
return res;
}
Thanks friends!
Yes, that is how Promises work. You must call asynchronous code from an asynchronous setting or a top-level module. So let's say you have the following code (adjusted).
let queryApi = async (query) => {
const response = await fetch(query);
const res = await response.json();
return res;
}
You can call it like so:
let result = await queryApi('https://www.example.com');
console.log(result);
It must be inside an asynchronous function OR in a <script type='module'></script>.
Here you have some problems with your braces.
Actually you need something like this:
const queryApi = async (query) => {
const response = await fetch(query);
const res = await response.json();
return res;
}
I have a problem. Could anyone tell me why my setTimeout function within the try block does not work? It doesn't wait for 10000 milliseconds and simple runs through.
As a result, the console shows the error message "cannot read property data of "undefined".
The API should return an object, but needs some time to fetch the answer.
The console.log(responseInformation) returns also "undefined".
const fetchAnswerFromDialogflow =
try {
const res = await axios.post(
`https://dialogflow.googleapis.com/v2/projects/myteachingbot-arxmxd/agent/intents:batchUpdate`,
node,
config
);
const waitForResponseAssignment = async () => {
let nodesSavedToChatbot = await res.response.data;
return nodesSavedToChatbot;
};
const responseInformation = setTimeout(
await waitForResponseAssignment(),
10000
);
console.log(responseInformation);
The problems in your code:
const res = await axios.post(
`https://dialogflow.googleapis.com/v2/projects/myteachingbot-arxmxd/agent/intents:batchUpdate`,
node,
config
);
const waitForResponseAssignment = async () => {
/*
axios response doesnt have a property called response,
so res.response.data is error.
Also res.data is already a response from the api(res is
not a promise so you dont have to use await below,
even you dont need this `waitForResponseAssignment` function)
*/
let nodesSavedToChatbot = await res.response.data;
return nodesSavedToChatbot;
};
// This timeout function is not correct, setTimeout
// accepts the first param as callback(but you passed a value)
// Actually you also dont need this `setTimeout`
const responseInformation = setTimeout(
await waitForResponseAssignment(),
10000
);
You can just use the below code:
const res = await axios.post(
`https://dialogflow.googleapis.com/v2/projects/myteachingbot-arxmxd/agent/intents:batchUpdate`,
node,
config
);
return res.data;
i recieve some data from x API, but i am stuck between a rock, if i want to use 'states' variable into another function, for example i want to map json object like this :
of course, it shows me error, 'state is not define';
any short way to solve this problem?
//recieve data
window.onload = async () => {
const response = await fetch("x");
const states = await response.json();
console.log(states);
};
states.map(function(bra){
// something
}
You do not need to access local variables, if you use vanilla JS you can do something like this:
const request = async () => {
const response = await fetch("x");
const data = await response.json();
renderYourData(data);
}
const renderYourData = (data) => {
//apend your data in DOM
}
window.addEventListener('load', function() {
request();
});
But if you use SPA framework it's no a better approach;
I'm fetching my user data and the map function is called several times for each user. I want to wait until all data was pushed to the array and then manipulate the data. I tried using Promise.all() but it didn't work.
How can I wait for this map function to finish before continuing?
Needless to say that the array user_list_temp is empty when printed inside the Promise.all().
const phone_list_promise_1 = await arrWithKeys.map(async (users,i) => {
return firebase.database().ref(`/users/${users}`)
.on('value', snapshot => {
user_list_temp.push(snapshot.val());
console.log(snapshot.val());
})
}
);
Promise.all(phone_list_promise_1).then( () => console.log(user_list_temp) )
I changed the code to this but I still get a wrong output
Promise.all(arrWithKeys.map(async (users,i) => {
const eventRef = db.ref(`users/${users}`);
await eventRef.on('value', snapshot => {
const value = snapshot.val();
console.log(value);
phone_user_list[0][users].name = value.name;
phone_user_list[0][users].photo = value.photo;
})
console.log(phone_user_list[0]);
user_list_temp.push(phone_user_list[0]);
}
));
console.log(user_list_temp); //empty array
}
It is possible to use async/await with firebase
This is how I usually make a Promise.all
const db = firebase.database();
let user_list_temp = await Promise.all(arrWithKeys.map(async (users,i) => {
const eventRef = db.ref(`users/${users}`);
const snapshot = await eventref.once('value');
const value = snapshot.value();
return value;
})
);
This article gives a fairly good explanation of using Promise.all with async/await https://www.taniarascia.com/promise-all-with-async-await/
Here is how I would refactor your new code snippet so that you are not mixing promises and async/await
let user_list_temp = await Promise.all(arrWithKeys.map(async (users,i) => {
const eventRef = db.ref(`users/${users}`);
const snapshot= await eventRef.once('value');
const value = snapshot.val();
console.log(value);
phone_user_list[0][users].name = value.name; // should this be hardcoded as 0?
phone_user_list[0][users].photo = value.photo; // should this be hardcoded as 0?
console.log(phone_user_list[0]);
return phone_user_list[0]; // should this be hardcoded as 0?
})
);
console.log(user_list_temp);
Here is a simple example that uses fetch, instead of firebase:
async componentDidMount () {
let urls = [
'https://jsonplaceholder.typicode.com/todos/1',
'https://jsonplaceholder.typicode.com/todos/2',
'https://jsonplaceholder.typicode.com/todos/3',
'https://jsonplaceholder.typicode.com/todos/4'
];
let results = await Promise.all(urls.map(async url => {
const response = await fetch(url);
const json = await response.json();
return json;
}));
alert(JSON.stringify(results))
}
If I understand your question correctly, you might consider revising your code to use a regular for..of loop, with a nested promise per user that resolves when the snapshot/value for that user is available as shown:
const user_list_temp = [];
/*
Use regular for..of loop to iterate values
*/
for(const user of arrWithKeys) {
/*
Use await on a new promise object for this user that
resolves with snapshot value when value recieved for
user
*/
const user_list_item = await (new Promise((resolve) => {
firebase.database()
.ref(`/users/${users}`)
.on('value', snapshot => {
/*
When value recieved, resolve the promise for
this user with val()
*/
resolve(snapshot.val());
});
}));
/*
Add value for this user to the resulting user_list_item
*/
user_list_temp.push(user_list_item);
}
console.log(user_list_temp);
This code assumes that the enclosing function is defined as an asynchronous method with the async keyword, seeing that the await keyword is used in the for..of loop. Hope that helps!
I realise very similar questions have been answered before, but I'm still finding it very confusing as to how this works...
From my understanding promises are used to deal with asyc requests - these promises essentially send back the state or a "promise" that at some point later a JSON body (or other object) will be delivered.
What I'm trying to understand is how I properly handle these requests so that the function doesn't return until the JSON body is ready to be parsed.
Below I'm trying to simply extract the key "result" (which returns a string "result") and parse it to another variable that can be stored and then later used somewhere else in my code. Unfortunately, my code always returns a [Object Promise], rather than the extracted JSON. I believe this is because response.json is also a promise... however, I don't understand how I get out of the "chain of promises" and return a value that I can actually do something with.
Thanks for any advice,
async function name() {
const response = await fetch('https://xxxxx.herokuapp.com/timespent', {});
const json = await response.json();
return json.result;
}
let varr = name();
console.log(varr)
Since your function is async it always return a promise. You need to use await for result.
read more about async here
async function name() {
const response = await fetch('https://mautargets.herokuapp.com/timespent', {});
const json = await response.json();
return json.result;
}
async function result(){
//await can only be called from inside of async function. So we need async function for await name()
let varr = await name();
console.log(varr) // Success
}
result()
In your example code, name function is declared async, so it returns a promise.
Inside that function body, you correctly handle async calls like fetch or the JSON transformation.
What you need now is either use await to wait for the function to "resolve", or use the "older" then/catch promises methods. Note that you cannot always use await outside an async function so you may need to wrap it.
Example :
async function name() {
const response = await fetch('https://mautargets.herokuapp.com/timespent', {});
const json = await response.json();
return json.result;
}
// using promise.then
name().then(result => console.log(result));
// wrapping await
(async function test() {
try{
console.log(await name());
}catch(error) {
// error goes here if promise got rejected
}
})()
You could have a callback in the function declaration, and use '.then(...)' and call it when the promise has been resolved:
async function name(cb) {
const response = await
fetch('https://mautargets.herokuapp.com/timespent', {});
const json = response.json();
json.then(x => cb(x))
}
name(console.log)
This is because you're using an Async function, which will return a promise.
Or if you would like the method to return, you could either call it in another Asynchronous context and utilize await again:
// Assume no callback: code just as you had it.
async function wrapper() {
console.log(await name())
}
Or you could do name().then(...) as specified before:
// Assume no callback: code just as you had it.
name().then(console.log)
Hope this helps!
I'm actually looking for the answer(same as yours), so I found this way.
I. ASK/REQUEST for data
async function fetchMyJson() {
const response = await fetch('https://1stAPI.devdeveloper1.repl.co/fiveD');
const myData = await response.json();
return myData;
}
II.GET Extract data
fetchMyJson().then(myData => {
let myData_output = myData.USD[0].rate; // fetched or Get OUTPUT data
console.log(myData_output);
document.body.innerHTML = `<div>${myData_output}</div>`; //make sure you add ${} for output
});
async function fetchMyJson() {
const response = await fetch('https://1stAPI.devdeveloper1.repl.co/fiveD');
const myData = await response.json();
return myData;
}
//GET Extract data
fetchMyJson().then(myData => {
let myData_output = myData.USD[0].rate; // fetched or Get OUTPUT data
console.log(myData_output);
document.body.innerHTML = `<div>${myData_output}</div>`; //make sure you add ${} for output
});
It is correct that you await fetch and .json since they are async.
async function name() {
const response = await fetch('http://blah.com/api', {});
const json = await response.json();
return json.result;
}
However, async and Promises inside function name make it async too. So the return value of name is a Promise that you should await it, or .then it, like:
// Old style .then
name().then(result => console.log(result))
// Modern style await
async function main() {
const result = await name()
console.log(result)
}