Why fetching(API) gives me undefined? - javascript

I created an API using Flask, and it is working perfectly when using it in Postman, giving me JSON.
Anyways, when I try to fetch it in javascript, it is giving me undefined:
api = 'http://127.0.0.1:5000/';
const getData = () => {
fetch(api)
.then(response => {
response.json();
})
.then(data => {
console.log(data);
});
};
getData();
As I said, when I try to log the data, it prints
undefined

You need to return your json data(return response.json();), fixed snippet:
api = 'http://127.0.0.1:5000/';
const getData = () => {
fetch(api)
.then(response => {
return response.json();
})
.then(data => {
console.log(data);
});
};
getData();

You get undefined because you dont return anything. Every function returns undefined if you dont return something.
api = 'http://127.0.0.1:5000/';
const getData = () => {
fetch(api)
.then(response =>{
return response.json();
})
.json() is asynchronous too so you will need an .then() block after ur function call.
getData().then( res => {
console.log(res);
});

Related

Struggling with promises and async functions in React

I'm working on a React project where I have a function that fetches paginated data recursively. This function is defined in another function, where I activate the loading screen with showLoading() at the start, where I'm calling the fetching data function in the body and deactivate the loading screen with hideLoading() at the end. The function:
const fetchPlaylist = (playlistId) => {
showLoading()
const getPlaylistDataRecursively = (url) => {
fetch('/spotify/get-track-ids', {headers: {
'url': url
}})
.then(response => response.json())
.then(data => {
console.log(data)
setTitles(data.title)
setArtists(data.artist)
setFeatures(data.features)
setIds(data.track_ids)
if (data.next_url) {
const next_url = data.next_url.replace('https://api.spotify.com/v1', '')
getPlaylistDataRecursively(next_url)
}
})
}
getPlaylistDataRecursively(`/playlists/${playlistId}/tracks/?offset=0&limit=100`)
hideLoading()
}
I believe I can attach a promise to the getPlaylistDataRecursively call with the then keyword but I'm getting a TypeError: Cannot read property 'then' of undefined. Probably because getPlaylistDataRecursively doesn't return anything. How do I make sure that hideLoading is called after getPlaylistDataRecursively is done?
You always need to return a promise.
const fetchPlaylist = (playlistId) => {
showLoading()
const getPlaylistDataRecursively = (url) => {
return fetch('/spotify/get-track-ids', {headers: {
'url': url
}})
.then(response => response.json())
.then(data => {
console.log(data)
setTitles(data.title)
setArtists(data.artist)
setFeatures(data.features)
setIds(data.track_ids)
if (data.next_url) {
const next_url = data.next_url.replace('https://api.spotify.com/v1', '')
return getPlaylistDataRecursively(next_url)
}
})
}
return getPlaylistDataRecursively(`/playlists/${playlistId}/tracks/?offset=0&limit=100`)
.then(() => hideLoading());
}
Or, using async/await:
const fetchPlaylist = async (playlistId) => {
showLoading()
const getPlaylistDataRecursively = async (url) => {
const response = await fetch('/spotify/get-track-ids', {headers: {
'url': url
}})
const data = response.json()
console.log(data)
setTitles(data.title)
setArtists(data.artist)
setFeatures(data.features)
setIds(data.track_ids)
if (data.next_url) {
const next_url = data.next_url.replace('https://api.spotify.com/v1', '')
await getPlaylistDataRecursively(next_url)
}
}
await getPlaylistDataRecursively(`/playlists/${playlistId}/tracks/?offset=0&limit=100`)
hideLoading()
}

await for all files to be fetched

I'm using only pure JS and HTML. No frameworks.
I'm fetching a few html files to my index.html. After they are all fetched I'd like to continue with the script. I'm tryint to figure out how to resolve this (I guess with Promises) but cannot make it work. How to wait for all of them to finish?
const prepareHead = fetch("../static/_includes/_head.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("head").innerHTML = data;
resolve();
});
const prepareHeader = fetch("../static/_includes/_header.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("header").innerHTML = data;
});
const prepareStaticLinks = fetch("../static/_includes/_static_links.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("static_links").innerHTML = data;
});
const prepareFooter = fetch("../static/_includes/_footer.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("footer").innerHTML = data;
});
await Promise.all([prepareHead, prepareHeader, prepareFooter, prepareStaticLinks]);
// next line should be called only after all files are fetched
console.log("document prepared");
but await Promise does not work:
Uncaught SyntaxError: await is only valid in async functions and async generators
What is the correct way to do this?
Try replacing
await Promise.all([prepareHead, prepareHeader, prepareFooter, prepareStaticLinks]);
console.log("document prepared");
with
Promise.all([prepareHead, prepareHeader, prepareFooter, prepareStaticLinks])
.then(() => {
console.log("document prepared")
});
Your other option would be to use await inside an async function, like so
const getData = async () => {
const prepareHead = fetch("../static/_includes/_head.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("head").innerHTML = data;
resolve();
});
const prepareHeader = fetch("../static/_includes/_header.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("header").innerHTML = data;
});
const prepareStaticLinks = fetch("../static/_includes/_static_links.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("static_links").innerHTML = data;
});
const prepareFooter = fetch("../static/_includes/_footer.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("footer").innerHTML = data;
});
await Promise.all([prepareHead, prepareHeader, prepareFooter, prepareStaticLinks]);
// next line should be called only after all files are fetched
console.log("document prepared");
};
getData();

Why does this code return undefined and how to make this code work

Request to the api successfully return the data as expected. The data from api is saved to 'fact' variable. The problem is that the 'getData' function returns promise which is expected to resolve
the data, instead it returns undefined.
const getData = num => {
let fact;
if (Array.isArray(num)) {
fetch(`http://numbersapi.com/${num[0]}/${num[1]}/date`)
.then(response => response.text())
.then(data => {
fact = data;
});
} else if (num.math === true) {
fetch(`http://numbersapi.com/${num.val}/math`)
.then(response => response.text())
.then(data => {
fact = data;
});
} else {
fetch(`http://numbersapi.com/${num}`)
.then(response => response.text())
.then(data => {
fact = data;
});
}
return new Promise((resolve, reject) => {
resolve(fact);
});
};
getData([1, 26]).then(val => {
console.log(val);
});
Fetch is a promise based api, it returns a promiss, and you don't need to wrap fetch in promise.
You could prepare the url string in the if checks, and then use it in the fetch call.
Example
const getData = num => {
let url;
if (Array.isArray(num)) {
url = `http://numbersapi.com/${num[0]}/${num[1]}/date`;
} else if (num.math === true) {
url = `http://numbersapi.com/${num.val}/math`;
} else {
url = `http://numbersapi.com/${num}`
}
return fetch(url);
};
getData([1, 26]).then(response => {
console.log(response.text());
});

how to retrieve results after api call which is returning a promise [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have a module that invokes a service
let getData = () => fetch("https://jsonplaceholder.typicode.com/posts")
.then(response => response.json())
.then(json => (getData = json));
export {getData };
I try to log to console the result (and put it on an HTML page) like this
import { getData } from "./api";
const app = document.querySelector("#target");
let data = getData()
.then(res => res.map(r => r.title).join("\n"))
.then(res => (data = res));
console.log(data);
app.innerHTML = data;
However, I get an unresolved promise like this [object Promise]
I've tried a few variations which also don't work
// none of these work don't work
// .then(async res => data = await res);
// .then(res => (data = Promise.resolve(res)));
Any suggestions as to what I am doing wrong?
Firstly, you shouldn't use the second then in getData - that's the result, and it reassigns your variable. Then change some other things in your code - syntax errors and wrong methods mostly:
let getData = () => fetch("https://jsonplaceholder.typicode.com/posts").then(response => response.json());
const app = document.querySelector("#target");
getData()
.then(res => res.map(r => r.title).join("<br>"))
.then(res => app.innerHTML = res);
<p id="target"></p>
i think you have to 'return' response.json() and then exec another then()
and also is better to include cathc to see problems
read
Making fetch requests
https://developer.mozilla.org/it/docs/Web/API/Fetch_API/Using_Fetch
let getData = () => fetch("https://jsonplaceholder.typicode.com/posts")
.then(function (response) {
return response.json();
})
.catch(function (err) {
console.log(err);
});
const app = document.querySelector("#target");
getData()
.then(res => res.map(r => app.innerHTML += r.title));

Javascript fetch api

i'm trying to assign the variable countries to the response of the fetch api but when i print out countries i get undefined ? can anyone explain to me why ? and a solution if it is possible.
async function getCountries(url) {
const data = await fetch(url);
const response = await data.json();
return response;
}
let countries;
document.addEventListener('DOMContentLoaded', () => {
getCountries('https://restcountries.eu/rest/v2/all')
.then(res => countries = res)
.catch(err => console.log(err));
})
console.log(countries);
function getCountries(url) {
return new Promise((resolve,reject)=>{
fetch(url).then(res => {
//You can parse the countries from the api response here and return to the
//event listener function from here using the resolve methood call parameter
resolve(res);
})
.catch(err => console.log(err));
})
}
document.addEventListener('DOMContentLoaded', () => {
getCountries('https://restcountries.eu/rest/v2/all')
.then(res => {
//the returned value after api call and parsing will be available here in res
})
})
Or if you dont want another function for this one you can directly get it using the following way,
document.addEventListener('DOMContentLoaded', () => {
let countries;
fetch('https://restcountries.eu/rest/v2/all')
.then(res => {
//the returned value after api call and parsing out the countries hereit self
countries = res.data.countries;
})
})

Categories

Resources