I'm given a code with 3 parts that must not be changed:
1. a call to getData function, and then prints the output.
getData().then(console.log);
2. The function signeture:
async getData(): Promise<string[]>
3. function getDataFromUrl
function getDataFromUrl(url: string, callback: any) {
fetch(URL)
.then((content: any) => content.json())
.then((data) => callback(data));
}
This is my implementation for getData function:
async getData(): Promise<string[]> {
return await new Promise<any>(function(resolve, reject) {
resolve(getDataFromUrl(myUrl, ((data: string[]): string[]=> {
return data
})))
});
}
The problem is that the code after fetch, runs after
getData().then(console.log);
so console.log prints: undefined
What do I need to change in the getData function?
Thanks
CodePudding user response:
Instead of resolving the getDataFromUrl
function, you should resolve the value that the callback function exposes.
getData(): Promise<string[]> {
return new Promise<string[]>(function(resolve, reject) {
getDataFromUrl(myUrl, (data: string[]): string[] => {
resolve(data)
})
});
}
It's unfortunate you can't change anything about the other functions, because returning the promise created by fetch
in your getDataFromUrl
function, would make the code way better, as Quentin demonstrates.
CodePudding user response:
getDataFromUrl
doesn't have a return value, so it returns undefined
.
So you pass undefined
to resolve
(which resolves your other promise) and then, later the promise created by getDataFromUrl
(or rather fetch
) resolves.
- Don't create bonus promises
- Don't mix callbacks and promises
Just return the promise from fetch
.
function getDataFromUrl(url: string, callback: any) {
return fetch(URL)
.then((content: any) => content.json());
}
And use that promise instead of creating a new one in getData
(which doesn't need to use await
because that will just resolve the promise which will immediately get wrapped in a new promise by async
.
getData(): Promise<string[]> {
return getDataFromUrl(myUrl);
}
CodePudding user response:
function getDataFromUrl(url, f) {
// call fetch (returns promise) but we can use then as well.
// note our callback: f where we pass the data to the callback.
fetch(url).then((content) => content.json()).then(data => f(data));
}
// edit: note we don't need this be async anymore...
async function getData() {
// create a promise...
return new Promise((resolve, reject) => {
// we call with callback arrow and resolve data here
getDataFromUrl('https://randomuser.me/api/', (data) => resolve(data));
})
}
// we print the data once the getData is done fetching
// you can also use reject to handle anything that goes wrong in above.
getData().then(data => console.log(data));
Resources used:
- Fetch API
- Async, Await, and Promise
- Callback