0

I'm trying to extract deep data from a Json, but when I navigate to my screen, my code executes the first promise, but the second is a promise that maps through my hook that I've set up in the previous promise. I'm trying to figure out how to execute the second promise only when the first one is resolved. Here is my code:

  const [tableHead, setTableHead] = useState('');
  const [performance, setPerformance] = useState('');
  const [performanceKpis, setPerformanceKpis] = useState('');

  useEffect(() => {
    async function getKpis() {
      const findData = await Promise.all(
        json.map((performance) => performance.performance)
      );
      setPerformance(...findData);

      const findValues = await Promise.all( <=============== This is the stuff 
        setPerformanceKpis(performance.map((performance) => performance.value))
      );
      // setPerformanceKpis(findValues);
    };
    getKpis()
  }, []);

I'm pretty new to promises. I didn't figured out how it works correctly.

[
  {
      "id": "3c20fbe3-fc59-433d-b349-6aa3b4a4c17b",
      "name": "20210504",
      "external_id": "3ad0c67e-170c-4ea8-afcc-850c94f449aa",
      "farm_id": "489cd6a6-db19-4a6f-bc95-1d981edc972f",
      "farm_name": "Granja Presence",
      "producer_id": null,
      "producer_name": "Produtor Granja Presence",
      "type": "limited",
      "finished": true,
      "walkthrough_available": false,
      "performance": [
          {
              "key": "AVERAGE_DATE_INPUT",
              "name": null,
              "abbreviation": null,
              "value": "2021-05-04T00:00:00",
              "measurement_unit": "date",
              "decimal_places": null,
              "is_critical": false
          },
          {
              "key": "AVERAGE_DATE_OUTPUT",
              "name": null,
              "abbreviation": null,
              "value": "2021-05-04T00:00:00",
              "measurement_unit": "date",
              "decimal_places": null,
              "is_critical": false
          },

This is my JSON structure, I want to extract the objects inside my Performance Array. So I made a map and pushed the data to my Hook, now I'm trying to map inside my Performance array and push the objects to my hook, later I'll render in a table.

Gabriel Savian
  • 166
  • 1
  • 11
  • According to the code, you send in the mapped result `performance` as a parameter to `setPerformanceKpis`. You need to chain them, if `performances` should be executed after `setPerformancesKpis`. I learned about promises at MDN (link), where you can learn to chain promises with `.then`. `Promise.all` is only used when you want to execute all promises at the same time. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – Rickard Elimää May 21 '21 at 12:51
  • What is `json`, where does it come from? Why are there promises in it? I don't think anything asynchronous is going on here, you probably don't even need promises. – Bergi May 21 '21 at 12:51
  • `setPerformance` has only a single parameter, you probably do not want to use spread syntax for the call. – Bergi May 21 '21 at 12:52
  • You need to use `findData.map(…)`, not `performance.map(…)`. Notice that `setPerformance` does not assign to the `performance` constant! – Bergi May 21 '21 at 12:53
  • 1
    Your code looks a bit weird. I think `Promise.all` is not the method you are looking for. Could you add some more examples explaining what you are trying to accomplish? – Leroy May 21 '21 at 12:54
  • I'll post my JSON to make things clear. – Gabriel Savian May 21 '21 at 12:59
  • Yeah, no promises in there. Your `map` calls are essentially synchronous, you shouldn't use any promises. The `findData` vs `performance` problem persists. – Bergi May 21 '21 at 14:34

1 Answers1

0

I assume Promise is not needed here. Because i don't see you make any API calls inside the json.map nor your performance.performance is a function call which returns a Promise.

const getPerformanceValues = async () => {
   try {
     const json = await //your api call 
     const findData = json.map((performance) => performance.performance)
     setPerformance(findData);
     const findValues = findData.map((performance) => performance.value);
     setPerformanceKpis(findValues)
   } catch(error){
     // do something if api calls fails
   }
}


useEffect(() => {
  getPerformanceValues ();
}, []);
Shyam
  • 5,292
  • 1
  • 10
  • 20
  • …and if that is the case, one actually shouldn't use two separate `useState`s either. – Bergi May 21 '21 at 12:55
  • yes if you already have what you needed in performance , then we can just iterate it over to get the performance.value . But i am not sure what the author is doing with both the states . – Shyam May 21 '21 at 12:58
  • I posted my JSON to make things clear. In the future this will be an api request. This is why I'm using promises. – Gabriel Savian May 21 '21 at 13:03
  • I have updated my answer for the case when you are getting the json from a API Call . – Shyam May 21 '21 at 13:10