I'm developing a project in React Native. The problem I have encountered is that the fetches all develop at the same time, instead I would like one fetch to wait before the end of another fetch to use its data.
I would then like to use idTitle
in the second fetch, but I am unable because they are executed simultaneously
function SongScreen({ route }) {
const { textArtist, textSong } = route.params;
const geniusUrl = 'https://api.genius.com';
const [isLoading, setLoading] = useState(true);
const [idTitle, setIdTitle] = useState([]);
const [idVideoYT, setIdVideoYT] = useState([]);
useEffect(async () => {
fetch(geniusUrl + '/search?q=' + textSong, {
headers: { 'Authorization': 'Bearer ' + geniusToken }
})
.then((response) => response.json())
.then((json) => {
for (const value of json.response.hits) {
if ((value.result.title.toLowerCase() == textSong.toLowerCase()) &&
(value.result.primary_artist.name.toLowerCase() == textArtist.toLowerCase())) {
setIdTitle(value.result.api_path)
setIdArtist(value.result.primary_artist.api_path)
}
}
})
.catch((error) => { AlertView(), setModalVisible(true) })
.finally(() => setLoading(false));
}, []);
useEffect(() => {
fetch(geniusUrl + idTitle, {
headers: { 'Authorization': 'Bearer ' + geniusToken }
})
.then((response) => response.json())
.then((json) => {
for (const value of json.response.song.media) {
if (value.provider == 'youtube')
setIdVideoYT(value.url)
}
})
.catch((error) => alert(error)) //{ AlertView(), setModalVisible(true) })
.finally(() => setLoading(false));
}, []);
return (
//.....
)
}
EDIT: I tried concatenating like this, but it keeps giving the same error:
useEffect(async () => {
fetch(geniusUrl + '/search?q=' + textSong, {
headers: { 'Authorization': 'Bearer ' + geniusToken }
})
.then((response) => response.json())
.then((data) => {
for (const value of data.response.hits) {
if ((value.result.title.toLowerCase() == textSong.toLowerCase()) &&
(value.result.primary_artist.name.toLowerCase() == textArtist.toLowerCase())) {
setIdTitle(value.result.api_path)
setIdArtist(value.result.primary_artist.api_path)
}
}
})
.then(
fetch(geniusUrl + idTitle, {
headers: { 'Authorization': 'Bearer ' + geniusToken }
})
.then((response) => response.json())
.then((json) => {
for (const value of json.response.song.media) {
if (value.provider == 'youtube')
setIdVideoYT(value.url)
}
})
.catch((error) => alert(error)) //{ AlertView(), setModalVisible(true) })
.finally(() => setLoading(false))
)
.catch((error) => { AlertView(), setModalVisible(true) })
.finally(() => setLoading(false));
}, []);
EDIT 2: I tried adding the then
inside the if
, but it gives as error that it doesn't find the then
variable:
useEffect(async () => {
fetch(geniusUrl + '/search?q=' + textSong, {
headers: { 'Authorization': 'Bearer ' + geniusToken }
})
.then((response) => response.json())
.then((data) => {
for (const value of data.response.hits) {
if ((value.result.title.toLowerCase() == textSong.toLowerCase()) &&
(value.result.primary_artist.name.toLowerCase() == textArtist.toLowerCase())) {
setIdTitle(value.result.api_path)
setIdArtist(value.result.primary_artist.api_path)
then(() => fetch(geniusUrl + value.result.api_path, {
headers: { 'Authorization': 'Bearer ' + geniusToken }
})
.then((response) => response.json())
.then((json) => {
for (const value of json.response.song.media) {
if (value.provider == 'youtube')
setIdVideoYT(value.url)
}
})
.catch((error) => alert(error))
.finally(() => setLoading(false))
)
}
}
})
.catch((error) => alert(error))
.finally(() => setLoading(false));
}, []);
EDIT 3: I added all 3 fetches in the same useEffect for convenience. I tried using await for the third fetch but it always goes into the catch.
useEffect(async () => {
fetch(geniusUrl + '/search?q=' + textSong, {
headers: { 'Authorization': 'Bearer ' + geniusToken }
})
.then((response) => response.json())
.then((data) => {
for (const value of data.response.hits) {
if ((value.result.title.toLowerCase() == textSong.toLowerCase()) &&
(value.result.primary_artist.name.toLowerCase() == textArtist.toLowerCase())) {
setIdTitle(value.result.api_path) //for third fetch
setIdArtist(value.result.primary_artist.api_path)
}
}
})
.catch((error) => { AlertView(), setModalVisible(true) })
.finally(() => setLoading(false));
fetch(lyricsUrl + textArtist + '/' + textSong)
.then((response) => response.json())
.then((text) => setDataLyrics(text.lyrics))
.catch((error) => { AlertView(), setModalVisible(true) })
.finally(() => setLoadingLyrics(false));
try {
let response = await fetch(geniusUrl + idTitle, {
headers: { 'Authorization': 'Bearer ' + geniusToken }
});
let id = await response.json();
for (const value of id.response.song.media) {
if (value.provider == 'youtube')
setIdVideoYT(value.url)
}
}
catch (error) {
alert(error);
}
setLoading(false);
}, []);