#hola vuelvo con algo más concreto a ver

1 messages · Page 1 of 1 (latest)

wide garnet
#

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.

stone nacelle
wide garnet
# stone nacelle Hola <@710579581681139793>, lo que podrías hacer es usar la función `Promise.all...

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

stone nacelle
#

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)

wide garnet
#

eso he intentado, creo que estoy haciendo algo mal. Me puedes dar un ejemplo?

stone nacelle
#
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

wide garnet
#

se ve mucho más limpio, genial... pero el console.log (el último) sigue estando vacio (el arreglo)

stone nacelle
#

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));

wide garnet
#

ah, claro... voy a probar eso luego. Creo que has dado con un punto muy importante...gracias. Volveré para contar si ha funcionado

stone nacelle
#

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

wide garnet
#

y cuál sería esa forma?

stone nacelle
#

Usando un map para la creación de promesas con Promise.all

wide garnet
stone nacelle
#

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