Reputation: 1
I'm trying to access the data of an api and I have a problem that I can't solve...
export const getCharacters = async (category) => {
const url = `https://www.breakingbadapi.com/api/characters?name=${encodeURI(category)}`;
const resp = await fetch(url);
const data = await resp.json();
const characters = data.map(item => {
return {
id: item.char_id,
title: item.name,
url: item.img,
nickname: item.nickname,
bday: item.birthay,
occupation: item.occupation,
status: item.status
}
})
return characters;
}
I put the results into a card and then I add in the character card a link to another component where I want to show "more details":
import React from 'react'
import { Link } from 'react-router-dom'
import '../../index.css'
export const CharactersGridItem = ({id, title, url}) => {
return (
<div className="card-global">
<span className="col">
<span className="card" style={{width: '10rem'}}>
<span className="row">
<img src={url} className="card-img-top" alt={title} style={{ width: '270px', height: '250px'}}></img>
<h6 className="card-title">{title}</h6>
<Link
className="card-body"
to={`/Characters/${id}`}
>
Details...
</Link>
</span>
</span>
</span>
</div>
)
}
All this works correctly and takes me to the url of the character's id on which I click.
My problem is when I try to recover those other properties of the character that, curiously, I can see them in the console (before everything explodes).
Here is the hook with which I made that second "request" for data:
import { useState, useEffect } from "react";
export const useCharacter = (id) => {
const [character, setCharacter] = useState()
function getCharacter(id) {
return fetch(
`https://www.breakingbadapi.com/api/characters/${encodeURI(id)}`
);
}
useEffect(() => {
// Después de que el componente se monta, se ejecuta este callback
getCharacter(id).then((resp) => resp.json()).then(([body]) => {
//console.log(body)
setCharacter(body)
})
}, [])
//return character;
return character;
}
import React from 'react'
import { useParams } from 'react-router-dom';
import { useCharacter } from '../../hooks/useCharacter';
export const CharactersDetail = (setCharacter) => {
const { id } = useParams()
const characters = useCharacter(id)
console.log(characters)
return (
<div className="container">
<div className="container-section">
<p>{characters.name}</p>
<p>{characters.nickname}</p>
</div>
</div>
)
}
When I click on a character, and go to the details page (CharacterDetails), if I don't put this code on the return...:
<p>{characters.name}</p>
<p>{characters.nickname}</p>
...everything works correctly and with console.log it prints the data json correctly (console). Even if I write the code and refresh the page (localhost:3000), it prints what I ask for.
But the moment I go back to the character page, click on another one (different id) and get to its corresponding detail page, everything explodes. An error tells me that it doesn't recognize the characters.name or characters.nickname.
Any ideas on why this might be happening? Any help is greatly appreciated!!!
Upvotes: 0
Views: 212
Reputation: 99525
wcharacters
will be undefined
for the first render. Only after the data is received your components render again.
So you need to explicitly handle the case where useCharacter
returns undefined
.
For example:
export const CharactersDetail = (setCharacter) => {
const { id } = useParams();
const characters = useCharacter(id);
if (!characters) {
return <div>Loading...</div>;
}
return (
<div className="container">
<div className="container-section">
<p>{characters.name}</p>
<p>{characters.nickname}</p>
</div>
</div>
)
}
Upvotes: 1