I'm trying to retrieve the [[PromiseValue]] of a Promise.
My function currently returns a Promise instead and the value I want myFunction to return is the value stored in [[PromiseValue]] of the returned Promise.
This returns a Promise.
myFunction(){
return fetch("/api")
.then(res => {
return res.json();
})
.then(json => {
return json;
})
}
I tried this code, but when I print the data in console, it prints the correct value, but the returned value is undefined.
myFunction(){
return fetch("/api")
.then(res => {
return res.json();
})
.then(json => {
return json;
})
.then(data => {
const stringData = data.toString();
console.log(stringData); // prints the correct string
return stringData; // returns undefined
})
}
How would I make my function return the value stored in [[PromiseValue]] as a String?
Please help me out, thanks!
Your function cannot return the PromiseValue directly, since fetch works asynchronously. It will return a Promise which will eventually resolve to that value.
Using async/await, what you could do is:
async function myFunction() {
const res = await fetch('/api');
const json = await res.json();
return JSON.stringify(json);
// json.toString() is a bit weird … but do as you please
// I'd return the json and parse it at the callsite.
}
const result = await myFunction();
(note: this snippet requires a modern engine which supports top-level await. Latest chrome will work just fine.)
Related
I'm trying to fetch a json file the api in the code below ,When I convert the json response to a javascript object I expect to be able to access the value of the key results in that object which is an array but when i log the response in the second then chain i get unidentified
const URLS = "https://pokeapi.co/api/v2/pokemon?limit=1000"
fetch(URLS)
.then(response => {
return response.json().results
})
.then((pokemons) => {
console.log(typeof pokemons)
});
When I changed the code to this
const URLS = "https://pokeapi.co/api/v2/pokemon?limit=1000"
fetch(URLS)
.then(response => {
return response.json()
})
.then((pokemons) => {
console.log(typeof pokemons.results)
});
it seems working fine but i don't understand why this problem is happening
response.json() returns a Promise resolving to the result of parsing the text of the response as JSON. You cannot directly access properties on that result without awaiting the Promise with .then or await in an async function.
I am crawling 5 different sites for data using node-fetch and cheerio.
everything checks out but I need to collect the returned data from these 5 separate functions in an array.
First I store function name and url for each site in an object like so
url: 'https://sampleurl.com',
crawl: FirstLinkCrawl
}
const secondLink = {
url: 'https://sampleurl.com',
crawl: secondLinkCrawl
}
}```
Then I write the function to crawl each site like so, I ran this function with and without promise, both check out
```const secondLinkCrawl = (body) =>{
return new Promise((res, rej)=>{
"this crawl function is ran here, everything works fine, Data is an object"
const error = false
if(!error){
res(Data)
}else{
rej()
}
})
}```
This here is my fetch function that takes the url and a callback, which is the crawl function
```async function Fetch(url, callback){
const response = await fetch(url)
const html = await response.text()
callback(html)
}
Then I call the fetch and crawl using promise.all() in an attempt to have it return in an array, but in an array,
const promises = [
Fetch(firstLink.url, firstLink.crawl),
Fetch(secondLink.url, secondLink.crawl)]
Promise.all(promises)
.then(values => console.log(values))
.catch(err => console.log(err))
}
When I run this, I get [ undefined, undefined ]
But when I run it without promises and simply log the result, both of them run successfully.
My aim is to get my results in a single array. what can I do?
I also tried declaring an array a the top of the page and then pushing each result into the array, after which I log the array at the bottom of the functions call. But the array returns empty
You're not returning anything from Fetch function that's why it's undefined. You can fix it by -
async function Fetch(url, callback){
const response = await fetch(url)
const html = await response.text()
const result = await callback(html);
return result;
}
As the callback, you are passing in Fetch function returns Promise so we can await it and return the result
I want to fetch data for every object in an array and return an array of new objects with the previous and newly fetched data.I got stucked on getting my result array as my function is returning an array of resolved undefined promises.
I am using a flight search api thats using the apca function for fetching
export const searchApcaLocation = async (dataArr,setDeals) => {
const promises = await dataArr.map(async item => {
apca.request(item.destination);
apca.onSuccess = (data) => {
return fetch('http://localhost:3050/googlePlaceSearch',{
method:"post",
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
cityName:data.airports[0].city
})
})
.then(res => res.json())
.then(imagelinkData => {
const locationObject = {
data: item,
imagelink: imagelinkData.link
}
return locationObject
})
.catch(err => console.log('error on image search',err))
};
apca.onError = (data) => {
console.log('error',data)
};
})
const results = await Promise.all(promises)
return results
}
can someone guide me please on what am I doing wrong?
edit:
as I am trying to fix it realized the problem is I am not returning anything in my map function but if trying to return the apca.onSuccess I am getting an array of functions
just return is missing before fetch function. since you're not returning your promise result it's giving undefined.
export const searchApcaLocation = async (dataArr,setDeals) => {
const promises = await dataArr.map(async item => {
apca.request(item.destination);
apca.onSuccess = (data) => {
return fetch('http://localhost:3050/googlePlaceSearch',{
method:"post",
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
cityName:data.airports[0].city
})
})
.then(res => res.json())
.then(imagelinkData => {
const locationObject = {
data: item,
imagelink: imagelinkData.link
}
return locationObject
})
.catch(err => console.log('error on image search',err))
};
apca.onError = (data) => {
console.log('error',data)
};
})
const results = await Promise.all(promises)
return results
}
The issue in your case might be, that you are using async/await and then blocks together.
Let me sum up what is happening :
1) you await dataArray.map
2) within the map callback, you use the onSuccess method of apca
3) within this method you are using then blocks which won't await until you got a response.
At this point where you return the locationObject, your function already reached the return statement and tries to return results.
But results are of course undefined because they never get resolved at all.
Also, keep in mind that your function returns another promise because you used async/await which you have to resolve where you imported it.
Cheers :)
I´m pretty new to Promises and found many examples here how to access the actual value which is always done with console.log. But my goal is to store the result in a variable and work with it.
getdata = () =>
fetch(
"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&outputsize=full&apikey=demo"
)
.then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error("This is an error");
}
})
.then(data => {
console.log(data);
});
getdata();
This code works. Can you help me to rewrite it that the getdata() function allows me to store the result in a variable. Return does not work since I will receive another pending Promise.
You can do it like this:
getdata = () =>
fetch(
"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&outputsize=full&apikey=demo"
).then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error("This is an error");
}
});
getdata().then(data => {
//I can do whatever with data
});
Of course you would also want to handle the scenario where the request failed, so you could also chain a .catch(). Alternately, if you have your build process configured for it, you can use async and await so you could do:
try {
const data = await getdata();
} catch(err) {
}
This would need to be in a function marked as async
Well at first we need to declare a variable let's say temp. Then use fetch API to request our query with URL. If server status is 200 then it will return a promise, we need to use then method by passing any argument (res, response, r anything...) and then a fat arrow function (=>) so that we can make the response as json format. After then we need to use another then method to return the json output and assign the value to our declared temp variable.
But if there is any error like 500, 400, 404 server error we need to use catch method with err argument and console it out.
let temp;
fetch('https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&outputsize=full&apikey=demo')
.then(res => res.json())
.then(data => temp = data)
.catch(err => console.log(err));
Maybe a trivial one, but I am new with Typescript and fetch API.
In an exported class I have a public method remoteFetchSomething like:
export class className {
remoteFetchSomething = (url : string) : Promise<Response> => {
return fetch(url)
.then(
(r) => r.json()
)
.catch((e) => {
console.log("API errore fetching " + objectType);
});
}
}
export const classInstance = new className();
The method queries a remote JSON API service, and in the code, I am using it like:
import { classInstance } from ...
classInstance.remoteFetchSomething('https://example.url')
.then((json) => {
console.log(json);
}
)
The console.log is actually showing the results, but the remoteFetchSomething returns a Promise and I am unable to parse and access the JSON object values.
I would like to wait for the response before executing the remaining code, but how do I unwrap content from promise? Should I again put another .then? What am I missing?
Thank you.
By now I resolved the problem defining the return type of the remoteFetch as any:
remoteFetchSomething = (url : string) : any => {
return fetch(url)
.then(
(r) => r.json()
)
.catch((e) => {
console.log("API errore fetching " + objectType);
});
}
And now I can access JSON values like data below:
classInstance.remoteFetchSomething('https://example.url').then(
(json) => {
console.dump(json.data);
}
)
[sincerely still not clear why I cant' use the Promise<Response> type]
You can't synchronously block while waiting for a request in javascript, it would lock up the user's interface!
In regular javascript, and most versions of TypeScript, you should be / must be returning a promise.
function doRequestNormal(): Promise<any> {
return fetch(...).then(...);
}
function someOtherMethodNormal() {
// do some code here
doRequestNormal.then(() => {
// continue your execution here after the request
});
}
In newer versions of typescript, there's async/await keyword support - so instead it might look like this:
async function doRequestAsync() {
var result = await fetch(...);
// do something with request;
return result;
}
async function someOtherMethodAsync() {
// do some code here
var json = await doRequestAsync();
// continue some code here
}
Keep in mind, doRequestAsync still returns a Promise under the hood - but when you call it, you can use await to pretend that you're blocking on it instead of needing to use the .then( callback. If you call an async method from a non-async method, you'll still need to use the callbacks as normal.
this is how I do it:
type Payload = {
id: number
}
type ReturnType = number
export const functionThatHasNumberType = async (
payload: Payload
): Promise<ReturnType> => {
let url = `/api/${payload.id}`
return await axios.get(url)
}