Home > Mobile >  REACT Component renders and then disappears
REACT Component renders and then disappears

Time:06-07

I have only one function that first gets the list of devices. the list is a JSON array. then the function loops over each element and request the shadow.

The function builds a new array using the device properties and the shadow property

The REACT page renders and show the data for a second, and then it disappears.

If I modify the getShadow function to just return the list of devices (without shadows), the page renders just fine. But the problem starts when I build the new array using the shadow data from each device.

Any idea what am I missing here?

many thanks

here is the code

async function getShadows() { 

    const listThings_command = new ListThingsCommand({});

    const data = await iotClient.send(listThings_command);  /* First get the list of things */ 
    const things = data.things;

    let devices_list = [];  // to store the final array with data to render

    let shadowRequests = things.map (thing => {   /* List calls to get shadow for each thing */ 

      return new Promise((resolve, reject) => {

        const getThingShadow_command = new GetThingShadowCommand({thingName: thing.thingName}); /** get device shadow */ 

        iotDataPlaneClient.send(getThingShadow_command).then(
          (data) => {

            const string_data = new TextDecoder('utf-8').decode(data.payload);  /* Decode payload as it is returned in Uint8Array format*/ 
            const shadow_data = JSON.parse(string_data);

            var deviceInfo = {  /* Create a new object to store required device info*/ 
              thingName : thing.thingName,
              thingTypeName: thing.thingTypeName,
              thingArn : thing.thingArn,
              shadow : shadow_data.state.reported
            };

            resolve(deviceInfo);
          },
          (error) => {

            reject(error);
          }
        ); 
      })
    })

    Promise.all(shadowRequests).then((data) => {
      data.forEach (res => {  /* loop over each promise */ 
        if (res) {
            devices_list.push(res); /* add the data as a new element in the array*/ 
        }
      })
    }
    )

    return devices_list;

  }; 
 
  function Home (){

    const [mydevices, updateMydevices] = React.useState([]);

    useEffect(() => {
      getShadows().then(data => updateMydevices(data)); 
    }, []);    


    return (
      <div className="App">
        <h1>Dashboard</h1> 
        <div>
          <h4>Devices List</h4>
          <ListGroup id="device_list">
              {
                mydevices.map((device, key) => {
                  return (
                    <ListGroup.Item key = {key}> 
                    <div>{device.thingName} </div>
                    </ListGroup.Item>
                  )
                })
              }
            </ListGroup>
        </div> 
      </div>
    );
  }
```


CodePudding user response:

If you don't use await here, the devices list will be returned before the shadow requests are complete. So it will always be an empty array. You can try something like this.

try {
    const data = await Promise.all(shadowRequests);
    data.forEach (res => {  /* loop over each promise */ 
        if (res) {
            devices_list.push(res); /* add the data as a new element in the array*/ 
        }
    })
}
catch(err) {
     //handle error
}
return devices_list;
  • Related