#hola vuelvo con algo más concreto a ver
1 messages · Page 1 of 1 (latest)
mi problema es que la info que obtengo en CITIES no la puedo almacenar en la variable que tengo fuera de fetch_info_capitales.
no puedo o no consigo hacerlo con el setState porque como son tres fetch, me los reescribe uno tras el otro.
Hola @wide garnet, lo que podrías hacer es usar la función Promise.all (https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise/all), donde te arroja un then (la data de todos las CITIES en un arreglo y un catch (si hay error)
gracias. He probado algo con Promise.all, pero voy a darle otra mirada. Igual algo he hecho mal.
El problema es, simpliicando, que consigo la info dentro de mi, digamos, funciónQueHaceFetch () , pero necesito esa información fuera de esa función.. no sé si queda claro.
Algo asi:
componente:
let x ={} // donde quiero almacenar la data
funcionFetch(){
fetch(url)
data = res.json
x = data_importante
console.log(x) // está acá toda la info como la necesito
}
console.log(x) // no hay nada, sólo mi objeto vacío
Puedes almacenar esa variable x en un state y usar spread operator de JS para hacer una concatenación (y así no sobrescribir la información)
eso he intentado, creo que estoy haciendo algo mal. Me puedes dar un ejemplo?
const url_capitals = [
"https://restcountries.com/v3.1/capital/berlin",
"https://restcountries.com/v3.1/capital/paris",
"https://restcountries.com/v3.1/capital/brussels"
];
let CITIES = []
const fetch_info_capitales = async () => {
for (let capital of url_capitals) {
await fetch(capital)
.then((response) => {
if (response.ok) {
return response.json();
}
throw response;
})
.then((json) => {
CITIES = [...CITIES, json[0]]
})
.catch((error) => {
console.error("Error fetching: error");
setError(error);
})
.finally(() => setLoading(false));
}
};
console.log(CITIES)
Cambie el tipo de CITIES por un arreglo y en el segundo then se hace un spread operator para añadir nuevos elementos al arreglo
se ve mucho más limpio, genial... pero el console.log (el último) sigue estando vacio (el arreglo)
Por que está fuera de la función y no se ha invocado la función, tendrias que borrarlo e invocar la función
const url_capitals = [
"https://restcountries.com/v3.1/capital/berlin",
"https://restcountries.com/v3.1/capital/paris",
"https://restcountries.com/v3.1/capital/brussels"
];
let CITIES = []
const fetch_info_capitales = async () => {
for (let capital of url_capitals) {
await fetch(capital)
.then((response) => {
if (response.ok) {
return response.json();
}
throw response;
})
.then((json) => {
CITIES = [...CITIES, json[0]]
})
.catch((error) => {
console.error("Error fetching: error");
setError(error);
})
.finally(() => setLoading(false));
}
};
fetch_info_capitales().then(() => console.log(CITIES));
ah, claro... voy a probar eso luego. Creo que has dado con un punto muy importante...gracias. Volveré para contar si ha funcionado
Dale quedo atento, de igual forma hay una forma más cómoda y legible de llegar al mismo resultado pero desde que funcione estaría bien
y cuál sería esa forma?
Usando un map para la creación de promesas con Promise.all
hola @stone nacelle disculpa que he andado liado. Mira, acá en codesandbox lo intento hacer. Si ves la línea 54 logo acceder a la información pero sólo de uno de los endpoints: https://codesandbox.io/s/berwerbertest-forked-gojiun?file=/src/Map.tsx
Hola @wide garnet ahí modifique el codesandbox, pero no se si persiste el cambio, de no ser así, te mando el código
import React, { useState, useEffect } from "react";
import "mapbox-gl/dist/mapbox-gl.css";
import { Map as _ReactMapboxGl, Marker } from "react-mapbox-gl";
const GERMANY_BOUNDS: [[number, number], [number, number]] = [
[3, 40],
[16, 56]
];
const url_capitals = [
"https://restcountries.com/v3.1/capital/berlin",
"https://restcountries.com/v3.1/capital/paris",
"https://restcountries.com/v3.1/capital/brussels"
];
const ICON = `M 10 10 H 90 V 90 H 10 L 10 10`;
const ReactMapboxGl = _ReactMapboxGl({
accessToken:
"pk.eyJ1IjoiZWNsZXZlciIsImEiOiJja3IzM3B3b24yMHNsMnBueGNya3I4eXExIn0.qNBd6dRRZLTTxKSJ0PUazg"
});
const Map = ({
children
}: {
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
}) => {
const [data, setData] = useState([]);
const dataFunc = async () => {
return Promise.all(
url_capitals.map((url_capital) =>
fetch(url_capital)
.then((result) => result.json())
.then((data) => data[0])
)
)
.then(setData)
.catch((error) => console.log({ error }));
};
useEffect(() => {
dataFunc();
}, []);
return (
<ReactMapboxGl
style="mapbox://styles/mapbox/streets-v11"
fitBounds={GERMANY_BOUNDS}
containerStyle={{ width: "100%", height: "100%" }}
>
{data.map((d) => (
<Marker
key={d.cca2}
coordinates={[d.capitalInfo.latlng[1], d.capitalInfo.latlng[0]]}
anchor="center"
onClick={() => {
console.log("click", [
d.capitalInfo.latlng[1],
d.capitalInfo.latlng[0],
d.cca2
]);
}}
>
<svg
aria-hidden="true"
height={32}
viewBox="0 0 24 24"
style={{ color: "red" }}
>
<path d={ICON} />
</svg>
</Marker>
))}
</ReactMapboxGl>
);
};
export default Map;
@wide garnet lo único que cambia es la forma que estaba modificando la variable del estado data siempre estaba modifican el ultimo resultado, lo que adapte es usar Promise.all que te arroja un arreglo de todas las peticiones y ahí se setea el estado setData