Home > Enterprise >  Empty Array is being returned before PromiseAll is resolved when used in useEffect method
Empty Array is being returned before PromiseAll is resolved when used in useEffect method

Time:10-07

I am iterating through a multidimensional array then pushing my data to a new array. When I log my array using the 'then' chain it logs empty. Not sure I am goin about this the proper way.

Array.js

export const Cars = [
    {
      type: "A",
      cars: [
        { name: "buick", id: "1259263" },
        { name: "ford", id: "1299830" },
        { name: "audi", id: "0181545" },
        { name: "gmc", id: "0016024" },
      ],
    },
    {
      type: "B",
      cars: [
        { name: "mazada", id: "1306193" },
        { name: "chevy", id: "1374540" },
        { name: "nissan", id: "1419526" },
        { name: "toyota", id: "1333007" },
      ],
    },
    {
      type: "C",
      cars: [
        { name: "bmw", id: "1259297" },
        { name: "porsche", id: "1305493" },
        { name: "tesla", id: "1042547" },
        { name: "mercedes", id: "1012982" },
      ],
    },
  ];

CarComponent.js

...
export const CarComponent = () => {
  const myArr = [];
  useEffect(() => {
    const fetchList = () => {
      Promise.all(
        Cars.map((car) => {
          return car.cars.map((id) => {
            return new Promise((resolve) => {
              fetch(`/api/=${id.id}`).then((response) => {
                return new Promise(() => {
                  response.json().then((id) => {
                    console.log(id); //<----returns normal
                    myArr.push(id);
                    resolve();
                  });
                });
              });
            });
          });
        }),
      ).then(() => {
        console.log("myArr", myArr); //<-----array is empty?
      })
    };
    fetchList();
  }, []);

...

CodePudding user response:

Look at

  Promise.all(
    Cars.map((car) => {
      return car.cars.map((id) => {

The item being returned from the mapper function is not a Promise, but an array - the return car.cars.map needs to be changed to a Promise.

You should also avoid the explicit Promise construction antipattern.

const fetchList = () => {
    Promise.all(
        Cars.map(({ cars }) => Promise.all(
            cars.map(({ id }) =>
                fetch(`/api/=${id}`)
                    .then(res => res.json())
                    .then((result) => myArr.push(result))
            )
        ))
    ).then(() => {
        console.log("myArr", myArr);
    })
};

Another option, rather than pushing to an external array:

const fetchList = () => {
    Promise.all(
        Cars.map(({ cars }) => Promise.all(
            cars.map(({ id }) =>
                fetch(`/api/=${id}`)
                    .then(res => res.json())
            )
        ))
    ).then((results) => {
        console.log("myArr", results.flat());
    })
    .catch(handleErrors); // don't forget this part
};
  • Related