Reputation: 787
On the previous screen, you can choose an episode. On this screen, episode ID coming from the previous screen and with this ID, its taking every character ID from API. Characters IDs are slicing from characters URLs. You can see details that in the episode data example. When this screen rendering, there is no error and there is no character name on the flatlist. How can I solve this problem?
API: https://rickandmortyapi.com/api/
Here codes:
const EpisodeDetailScreen = (props) => {
const { styles, colors } = useThemedValues(getStyles);
const loc = useLocalization();
// character list for flatlist
const [characterList, setCharacterList] = useState([
{
"created": "",
"episode": [""],
"gender": "",
"id": 0,
"image": "",
"location": { "name": "", "url": "" },
"name": "",
"origin": { "name": "", "url": "" },
"species": "",
"status": "",
"type": "",
"url": ""
},
])
// episode details
const [episodeDetail, setEpisodeDetail] = useState([])
// this id come from previous screen
const { episodeId } = props.route.params
// details of a chosen episode from the previous screen
useEffect(() => {
Axios.get('episode/' + episodeId)
.then(response => {
let episodeDetail = response.data
setEpisodeDetail(episodeDetail) // episode details
//Getting the IDs of the characters in the section from the last part of the URLs in the incoming data
// You can see in data example that
for (var i = 0; i < episodeDetail.characters.length; i++) {
var charactersUrlInEpisode = episodeDetail.characters[i]
var charactersIdInUrl = charactersUrlInEpisode.slice(42, charactersUrlInEpisode.length)
// Extracting character ids and character details from API and throwing them into state
takeCharacters(charactersIdInUrl)
console.log(charactersIdInUrl) // I can see the correct IDs
}
})
.catch(error => {
console.log(error)
})
}, [])
// function that pulls character details from api based on given id
const takeCharacters = (id) => {
Axios.get('character/' + id)
.then(response => {
let characterDetail = response.data
setCharacterList(characterDetail)
console.log(characterDetail) // I can see characters data on console
})
.catch(error => {
console.log(error)
})
}
const _renderCharactersItem = ({ item }) => {
console.log('flatlist') // its working but flatList not rendering anything
return (
<TouchableOpacity onPress={() => {
props.navigation.navigate("character-detail-screen", {
characterId: item.id
});
}}>
<View style={styles.characterButton}>
<Text style={styles.characterNameText} numberOfLines={1}>{item.name}</Text>
</View>
</TouchableOpacity>
)
}
return (
<View style={styles.container}>
<View style={styles.episodeNameContainer}>
<Text style={styles.episodeNameText}>{episodeDetail.name}</Text>
</View>
<View style={styles.detailsContainer}>
<Text style={styles.detailsText}>{loc.t(texts.episode)}{episodeDetail.episode}</Text>
<Text style={styles.detailsText}>{loc.t(texts.airDate)} {episodeDetail.air_date}</Text>
</View>
<View style={styles.characterTitleContainer}>
<Text style={styles.characterTitleText}>{loc.t(texts.characters)}</Text>
</View>
<FlatList
data={characterList}
renderItem={_renderCharactersItem}
keyExtractor={item => item.id}
style={styles.flatListContainer}
/>
</View>
);
};
export default EpisodeDetailScreen;
Episode data example:
{
"id": 1,
"name": "Pilot",
"air_date": "December 2, 2013",
"episode": "S01E01",
"characters": [
"https://rickandmortyapi.com/api/character/1",
"https://rickandmortyapi.com/api/character/2",
"https://rickandmortyapi.com/api/character/35",
"https://rickandmortyapi.com/api/character/38",
"https://rickandmortyapi.com/api/character/62",
"https://rickandmortyapi.com/api/character/92",
"https://rickandmortyapi.com/api/character/127",
"https://rickandmortyapi.com/api/character/144",
"https://rickandmortyapi.com/api/character/158",
"https://rickandmortyapi.com/api/character/175",
"https://rickandmortyapi.com/api/character/179",
"https://rickandmortyapi.com/api/character/181",
"https://rickandmortyapi.com/api/character/239",
"https://rickandmortyapi.com/api/character/249",
"https://rickandmortyapi.com/api/character/271",
"https://rickandmortyapi.com/api/character/338",
"https://rickandmortyapi.com/api/character/394",
"https://rickandmortyapi.com/api/character/395",
"https://rickandmortyapi.com/api/character/435"
],
"url": "https://rickandmortyapi.com/api/episode/1",
"created": "2017-11-10T12:56:33.798Z"
}
Character data example:
{
"id": 1,
"name": "Rick Sanchez",
"status": "Alive",
"species": "Human",
"type": "",
"gender": "Male",
"origin": {
"name": "Earth (C-137)",
"url": "https://rickandmortyapi.com/api/location/1"
},
"location": {
"name": "Earth (Replacement Dimension)",
"url": "https://rickandmortyapi.com/api/location/20"
},
"image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg",
"episode": [
"https://rickandmortyapi.com/api/episode/1",
"https://rickandmortyapi.com/api/episode/2",
"https://rickandmortyapi.com/api/episode/3",
"https://rickandmortyapi.com/api/episode/4",
"https://rickandmortyapi.com/api/episode/5",
"https://rickandmortyapi.com/api/episode/6",
"https://rickandmortyapi.com/api/episode/7",
"https://rickandmortyapi.com/api/episode/8",
"https://rickandmortyapi.com/api/episode/9",
"https://rickandmortyapi.com/api/episode/10",
"https://rickandmortyapi.com/api/episode/11",
"https://rickandmortyapi.com/api/episode/12",
"https://rickandmortyapi.com/api/episode/13",
"https://rickandmortyapi.com/api/episode/14",
"https://rickandmortyapi.com/api/episode/15",
"https://rickandmortyapi.com/api/episode/16",
"https://rickandmortyapi.com/api/episode/17",
"https://rickandmortyapi.com/api/episode/18",
"https://rickandmortyapi.com/api/episode/19",
"https://rickandmortyapi.com/api/episode/20",
"https://rickandmortyapi.com/api/episode/21",
"https://rickandmortyapi.com/api/episode/22",
"https://rickandmortyapi.com/api/episode/23",
"https://rickandmortyapi.com/api/episode/24",
"https://rickandmortyapi.com/api/episode/25",
"https://rickandmortyapi.com/api/episode/26",
"https://rickandmortyapi.com/api/episode/27",
"https://rickandmortyapi.com/api/episode/28",
"https://rickandmortyapi.com/api/episode/29",
"https://rickandmortyapi.com/api/episode/30",
"https://rickandmortyapi.com/api/episode/31",
"https://rickandmortyapi.com/api/episode/32",
"https://rickandmortyapi.com/api/episode/33",
"https://rickandmortyapi.com/api/episode/34",
"https://rickandmortyapi.com/api/episode/35",
"https://rickandmortyapi.com/api/episode/36",
"https://rickandmortyapi.com/api/episode/37",
"https://rickandmortyapi.com/api/episode/38",
"https://rickandmortyapi.com/api/episode/39",
"https://rickandmortyapi.com/api/episode/40",
"https://rickandmortyapi.com/api/episode/41"
],
"url": "https://rickandmortyapi.com/api/character/1",
"created": "2017-11-04T18:48:46.250Z"
}
Upvotes: 1
Views: 195
Reputation: 3602
When you call the endpoint 'character/' + id
, the shape of the object you get is this
{
"id": 1,
"name": "Rick Sanchez",
"status": "Alive",
"species": "Human",
"type": "",
"gender": "Male",
"origin": {
"name": "Earth (C-137)",
"url": "https://rickandmortyapi.com/api/location/1"
},
"location": {
"name": "Earth (Replacement Dimension)",
"url": "https://rickandmortyapi.com/api/location/20"
},
"image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg",
"episode": [
"https://rickandmortyapi.com/api/episode/1",
"https://rickandmortyapi.com/api/episode/2",
"https://rickandmortyapi.com/api/episode/3",
"https://rickandmortyapi.com/api/episode/4",
"https://rickandmortyapi.com/api/episode/5",
"https://rickandmortyapi.com/api/episode/6",
"https://rickandmortyapi.com/api/episode/7",
"https://rickandmortyapi.com/api/episode/8",
"https://rickandmortyapi.com/api/episode/9",
"https://rickandmortyapi.com/api/episode/10",
"https://rickandmortyapi.com/api/episode/11",
"https://rickandmortyapi.com/api/episode/12",
"https://rickandmortyapi.com/api/episode/13",
"https://rickandmortyapi.com/api/episode/14",
"https://rickandmortyapi.com/api/episode/15",
"https://rickandmortyapi.com/api/episode/16",
"https://rickandmortyapi.com/api/episode/17",
"https://rickandmortyapi.com/api/episode/18",
"https://rickandmortyapi.com/api/episode/19",
"https://rickandmortyapi.com/api/episode/20",
"https://rickandmortyapi.com/api/episode/21",
"https://rickandmortyapi.com/api/episode/22",
"https://rickandmortyapi.com/api/episode/23",
"https://rickandmortyapi.com/api/episode/24",
"https://rickandmortyapi.com/api/episode/25",
"https://rickandmortyapi.com/api/episode/26",
"https://rickandmortyapi.com/api/episode/27",
"https://rickandmortyapi.com/api/episode/28",
"https://rickandmortyapi.com/api/episode/29",
"https://rickandmortyapi.com/api/episode/30",
"https://rickandmortyapi.com/api/episode/31",
"https://rickandmortyapi.com/api/episode/32",
"https://rickandmortyapi.com/api/episode/33",
"https://rickandmortyapi.com/api/episode/34",
"https://rickandmortyapi.com/api/episode/35",
"https://rickandmortyapi.com/api/episode/36",
"https://rickandmortyapi.com/api/episode/37",
"https://rickandmortyapi.com/api/episode/38",
"https://rickandmortyapi.com/api/episode/39",
"https://rickandmortyapi.com/api/episode/40",
"https://rickandmortyapi.com/api/episode/41"
],
"url": "https://rickandmortyapi.com/api/character/1",
"created": "2017-11-04T18:48:46.250Z"
}
As you can see this is not an array, but an object which contains an array of episodes.
Inside your function takeCharacters
, you call setCharacterList(characterDetail)
, where characterDetail
is the response from your api, which, is I said, is not an array, that's why you see nothing (a FlatList
wants an array to render).
If you look carefully at the shape of the api's data, you have:
I suggest you to do something like this (I didn't test it, but it should work, just wanted to suggest you the Promise.all() pattern)
const promises = []
for (var i = 0;i < episodeDetail.characters.length;i++) {
var charactersUrlInEpisode = episodeDetail.characters[i]
var charactersIdInUrl = charactersUrlInEpisode.slice(42, charactersUrlInEpisode.length)
// Build a promise array to get the characters one by one
// takeCharacters(charactersIdInUrl)
promises.push(const promise = Axios.get('character/' + charactersIdInUrl);)
console.log(charactersIdInUrl) // I can see the correct IDs
}
Promise.all(promises)
.then((data) => {
// data should be an array that you can set as FlatList's data
console.log("fetched data", data);
})
PS: this is not related to your problem, but I suggest to replace this
var charactersIdInUrl = charactersUrlInEpisode.slice(42, charactersUrlInEpisode.length)
with this
cost splittedUrl=charactersUrlInEpisode.split("/");
var charactersIdInUrl = splittedUrl[splittedUrl-length - 1]
it more reliable since it does not depend by the url's length
Upvotes: 2