i've tried to make a fetch and take one element of the data base by id on Reactjs, backend with javascript(node express sequelize), but i had some problems and i couldn't at anytime. im searched on google but i dont know hot to apply the solutions on my code... here some examples of my trying:
import { useState } from "react";
import { useParams, Link } from "react-router-dom";
import "./detallesBarrio.css";
const BarriosDetails = () => {
const { id } = useParams();
const [barrio, setBarrio] = useState({});
const loadBarrioDetails = () => {
fetch("http://localhost:3001/api/barrios")
.then((x) => x.json())
.then((y) => y.data)
// .then((z) => console.log(z))
.then((allBarrio) => setBarrio(allBarrio));
};
let byid = barrio.filter(obj => {
return obj.id === id;
});
console.log(byid);
loadBarrioDetails();
return (
<main className="barrio-details">
{byid.map(obj => {
return (
<div key={obj.id}>
<div>
<h1>Detalles de {obj.nombre}</h1>
<img src={obj.foto} alt="imagen no disponible" />
<article>
<Link to="/barrios">Volver</Link>
</article>
</div>
</div>
);
})}
</main>
);
};
export default BarriosDetails;
also my tryings:
-no filter function (problem: map is not a function)
import { useState } from "react";
import { useParams, Link } from "react-router-dom";
import "./detallesBarrio.css";
const BarriosDetails = () => {
const { id } = useParams();
const [barrio, setBarrio] = useState({});
const loadBarrioDetails = () => {
fetch(`http://localhost:3001/api/barrios`)
.then((x) => x.json())
.then((y) => y.data)
// .then((z) => console.log(z))
.then((allBarrio) => setBarrio(allBarrio));
};
loadBarrioDetails();
return (
<main className="barrio-details">
{barrio.map((barri) => {
return (
<div key={barri.id}>
<div>
<h1>Detalles de {barri[id].nombre}</h1>
<img src={barri[id].foto} alt="imagen no disponible" />
<article>
<Link to="/barrios">Volver</Link>
</article>
</div>
</div>
);
})}
</main>
);
};
export default BarriosDetails;
-no maping (problem: the code dont recognise 'nombre'(database camp') on '{barrio[id].nombre}')
import { useState } from "react";
import { useParams, Link } from "react-router-dom";
import "./detallesBarrio.css";
const BarriosDetails = () => {
const { id } = useParams();
const [barrio, setBarrio] = useState({});
const loadBarrioDetails = () => {
fetch(`http://localhost:3001/api/barrios`)
.then((x) => x.json())
.then((y) => y.data)
.then((z) => console.log(z))
.then((allBarrio) => setBarrio(allBarrio));
};
loadBarrioDetails();
return (
<main className="barrio-details">
<div>
<h1>Detalles de {barrio[id].nombre}</h1>
<img src={barrio[id].foto} alt="imagen no disponible" />
<article>
<Link to="/barrios">Volver</Link>
</article>
</div>
</main>
);
};
export default BarriosDetails;
yes console.log give me the correct array
CodePudding user response:
- You are getting map is not a function because you're initiating the state as an object. is should be
useState([])
instead ofuseState({})
- based on your code you want to filter by id and id is unique so it's better to use
array.find(obj => obj.id === id)
than usingarray.filter()
. - in your first snippet
let byid = barrio.filter(obj => { return obj.id === id; });
is executed before running the fetch and loading data.
try using useEffect
for this kind of needs and loading data as a side effect after mounting the component and you should check the existance of an object or array before accessing it useEffect(() => loadBarrioDetails(), [])
Or since you just need one single object you can use like this:
import { useState } from "react";
import { useParams, Link } from "react-router-dom";
import "./detallesBarrio.css";
const BarriosDetails = () => {
const { id } = useParams();
const [barrio, setBarrio] = useState(null);
const loadBarrioDetails = () => {
fetch(`http://localhost:3001/api/barrios`)
.then((x) => x.json())
.then((y) => y.data)
.then((allBarrio) => {
const byId = allBarrio.find(obj => obj === id);
setBarrio(byId ?? null);
});
};
useEffect(() => loadBarrioDetails(), []);
if (!barrio) return <></> // anything to display that the data is loading or doesn't exist depends on you need.
return (
<main className="barrio-details">
<div>
<h1>Detalles de {barrio.nombre}</h1>
<img src={barrio.foto} alt="imagen no disponible" />
<article>
<Link to="/barrios">Volver</Link>
</article>
</div>
</main>
);
};
export default BarriosDetails;