This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 months ago.
I have a function that must validate some artist from Spotify API, but when I run it artists[] remains empty because the function is running asynchronously, it fills the variable user without having set artists.
let artists = []
function setArtists(input) {
artists.length = 0
let parsedInput = input.value.split(",")
parsedInput.forEach(artist => {
validateArtist(artist)
})
}
function validateArtist(s) {
let token = localStorage.getItem("Token")
let url = "https://api.spotify.com/v1/search?type=artist&q=" + s
console.log(url)
fetch(url, {
"method": "GET",
"headers": {
'Accept': 'application/json',
'Content-Type': 'application/json',
"Authorization": "Bearer " + token,
}
})
.then(response => {
if (response.status === 401) {
refreshToken(s)
}
return response.json()
})
.then(searchedResults => searchedResults.artists.items.length != 0)
.then(isArtist => {
if (isArtist) {
artists.push(s)
}
})
}
Here is were I call the function, I call it before so it can fill artists
setArtists(document.getElementById("artistiPreferiti"))
var user = {
username: document.getElementById("username").value,
email: document.getElementById("email").value,
password: document.getElementById("password").value,
gustiMusicali: document.getElementById("gustiMusicali").value,
artistiPreferiti: artists
}
What am I missing?
The async (and await) keywords are tools to manage promises which are, in turn, tools to manage asynchronous code in a standard way.
The use of the async keyword doesn't make a function run asynchronously and not using the keyword doesn't prevent asynchronous code from being so.
fetch runs asynchronously. Your code uses fetch. Therefore your code is asynchronous.
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 days ago.
I'm learning JS, but i can't find how to save a request body after my fetch POST. Using only JS
async function connectUser () {
const log = document.querySelector("#formulaireConnexion")
log.addEventListener("submit", function(event){
event.preventDefault()
const user = {
email: event.target.querySelector("[name=mail]").value,
password: event.target.querySelector("[name=mdp]").value
}
const objectUser = JSON.stringify(user)
fetch("http://localhost:5678/api/users/login", {
method: "POST",
headers: {"Content-Type" : "application/json"},
body: objectUser
}).then(r => r.json())
.then(body => console.log(body))
})
}
connectUser()
You can save it in session or localstoreAge.
Like that
const objectUser = sessionStorage.setItem(”saveit”,JSON.stringify(user));
You can then use it like
SessionStorage.getItem(”saveit”);
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I am trying to do a GET request with vanilla javascript from a .html, and I am looking to assign the response inside a variable, I have to use the response to manipulate the DOM however, I get a Promise < pending > and not a JSON
This is my code:
let data = fetch('http://localhost/api/products')
.then(response => response.json())
console.log(data)
I'd like to get this from console.log(data):
{ "name": "SHOES", "price": 129}
this code will be a good guide, you can get json data at then second then
const getCart = () => {
fetch("/cart.js", {
method: 'GET',
headers: new Headers({'content-type': 'application/json', 'X-Requested-With':'xmlhttprequest'})
}).then(res => {
return res.json();
}).then(json => {
console.log(json);
});
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
im not sure why await is not working for me, can someone help me out?
I followed some guides and copied it exactly the same but still won't work.
I need CardsID array to be filled before calling console.log(CardsID.length)
code:
"[LL_REPTAG_URLPREFIXFULL /]/api/v2/businessworkspaces?where_workspace_type_id=54";
async function postData() {
let response = await fetch(url, {
method: "GET", // *GET, POST, PUT, DELETE, etc.
headers: {
"Content-Type": "application/json",
OTCSTicket: "[LL_REPTAG_OTCSTICKET /]",
},
//body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return await response.json();
}
//(async function(){
postData().then(function (data) {
// Log the data to the console
// You would do something with both sets of data here
//console.log(data);
data.results.forEach((element) => {
CardsID.push(element.data.properties.id);
console.log("added");
});
});
//})();
console.log(CardsID.length);
console.log(CardsID);```
result (console):
0
[]
[]
[]
24 added
You are calling the console.logs immediately after the postData() call, which is async (well, promise) and therefore won't wait for the execution to finish.
Either you need to place the console.logs inside the then handler, like this:
postData().then(function (data) {
data.results.forEach((element) => {
CardsID.push(element.data.properties.id);
console.log("added");
});
console.log(CardsID.length);
console.log(CardsID);
});
Or (for the sake of consistency), you could make it all async/await, eg.:
async function postData() {
const response = await fetch(url, {
method: "GET", // *GET, POST, PUT, DELETE, etc.
headers: {
"Content-Type": "application/json",
OTCSTicket: "[LL_REPTAG_OTCSTICKET /]",
},
});
return await response.json();
}
async function run() {
const data = await postData();
const CardsID = [];
for (const element of data.results) {
CardID.push(element.data.properties.id);
console.log("added");
}
console.log(CardsID.length);
console.log(CardsID);
}
run();
The problem is that code in the postData().then block is executed asynchronously, after the promise get resolved. The console.log(CardsID.length) statement will run before the then block get executed.
To fix that, you can run the console.log statement in the promise callback.
postData().then(function (data) {
data.results.forEach((element) => {
CardsID.push(element.data.properties.id);
console.log("added");
});
// move the console.log statement here
console.log(CardsID.length);
console.log(CardsID);
});
Just remember that your code below the .then block will run before it resolves because Javascript waits to resolve but continues through its synchronous run to execute the code below the any asynchronous code.
I'm trying to work with async await and fetching data using the fetch api
My problem is, I just don't quite understand how I really get the answer from the server and not the status of the promise. I get the following in the console
Promise {<pending>}
-------------------------------
{locale: "en"}
but what I rather expect is the server response which should be "locale: en".
my code:
const locale = getLocale();
console.log(locale) // here I want to have "locale: en" as a output
async function fetchLocale() {
return await fetch('/get-language', {
headers: {
'Accept': 'application/json'
},
method: 'GET',
}).then(response => {
if (response.ok) {
return response.json()
}
return Promise.reject(Error('error'))
}).catch(error => {
return Promise.reject(Error(error.message))
})
}
async function getLocale() {
return await fetchLocale();
}
The goal I want to archive is, to return this "locale: en" response and store it in the "locale" const at the beginning of my code example.
KR
Your function should look more like this:
async function getLocale() {
let response = await fetch('/get-language', {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: 'GET',
});
// you can check for response.ok here, and literally just throw an error if you want
return await response.json();
}
And you can consume the result of that in an async function using await
const locale = await getLocale();
console.log(locale);
or by using the promise methods
getLocale().then(function(locale){
console.log(locale);
})
To get the value a Promise resolves with and not the promise itself, use .then() or await. Note that both require a callback or asynchronous context as it's simply not possible to bring this asynchronous result to a synchronous context such as the top level of your file.
getLocale().then(locale => {
console.log(locale);
//locale is only valid here
});
I am using ternary if else for calling different APIs(API calls are stored in another file).
(this.props.item === "burger" ? burgerObj.GetBurger (this.props.burger_id) : pizzaObj.GetPizza (this.props.pizza_id)) // burgerObj and pizzaObj are objects of their respective classes
.then((response) => {
if(response.status === 400) {
console.log ("Bad Request")
}
else {
response.json()
.then((findresponse) => {
this.prepareFood(findresponse) // Some function call
})
}
})
.catch ((e) => {
console.log (e)
})
}
// API calls in different classes. Same is for GetPizza
GetBurger(burger_id) {
return fetch(url + 'burgerId' + burger_id , {
headers: {
'Authorization': 'Bearer ' + authorization,
'Content-Type': 'application/json',
}
})
}
Is this a wrong way of handling such calls. Because when I'm using this API calling is working fine but the code never reaches promise (.then((response) => { - line no. 2). If I check Network I can see the response returned from API. Sorry if I am wrong somewhere I'm still new to React. Please help me.
Using Ternary is ok. But you can you can use Async/Await to clean up callbacks -
const { item, burger_id, pizza_id} = this.props;
function fetchWrapper(url) {
fetch(url, {
headers: {
Authorization: `Bearer${authorization}`,
'Content-Type': 'application/json',
}
})
.then(data => { return { data, error: null }; })
.catch(error => { return { error, data: null }; });
}
// API calls in different classes. Same is for GetPizza
async function GetBurgerAsync(burgerId) {
let response = await fetchWrapper(`url burgerId${burgerId}`);
const data = await response.json();
return data;
}
const foodType = item === 'burger' ? GetBurgerAsync(burger_id) : GetPizzaAsync(pizza_id);
if (foodType.data) {
this.prepareFood(foodType);
}
Edit: refactored, wrapping fetch as only url should change on every call. Token should be same across all calls.