0

I'm trying to get specific values from an array object returned by my node.js api

Here's the array of object returned by my node.js api

[
  {
    "name": "device1",
    "serial": "WMD105222022",
    "status": "online"
  },
  {
    "name": "device2q",
    "serial": "sdfsdf",
    "status": "online"
  },
  {
    "name": "ducs",
    "serial": "WMD105222022",
    "status": "online"
  }
]

Here's my react.js code

import React, {useState, useEffect} from "react";
import './Module.css';
import {SDH} from '../../components';
import {temp, water, humidity, nutrient} from '../../assets';
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
import Form from 'react-bootstrap/Form';
import {Link} from 'react-router-dom';
import Axios from "axios";

const Module = () => {
    const [show, setShow] = useState(false);

    const handleClose = () => setShow(false);
    const handleShow = () => setShow(true);

    const email = sessionStorage.getItem("email");
    const [device, setDevice] = useState({});

    Axios.defaults.withCredentials = true;

    useEffect(() => {
        Axios.get("http://localhost:3020/getdevice", {
            params: { 
              email: email
            }
          })
          .then((response) => {
            setDevice(response.data);
          })
          // .then((response) => {},
          //   (err) => {
          //     alert("No Data To Show");
          //   }
          // )
          .catch((err) => {
            return false;
          });
    },[]);

    const DisplayData = () => {
      return (
        <div>
          <td>{device.name}</td>
          <td>{device.serial}</td>
          <td>{device.status}</td>
        </div>
      );
    };

    return (
        <div className="MainBodyM">
            <SDH/>
            <h3 className="deviceStatus"></h3>
            {/* <Button onClick={getDevices} variant="primary" type="submit">Refresh List</Button> */}
            <div className="tempHeader">
                <table>
                  <tr>
                    <td>Name</td>
                    <td>Serial Number</td>
                    <td>Status</td>
                  </tr>
                  <tr>
                      {DisplayData}
                  </tr>
                </table>
            </div>
            
            <Link to="/registerdevice">
                <Button>Add Control Module</Button>
            </Link>
        </div>
    );
};

export default Module;

I needed to get the name, serial, and status to be displayed in a table. up until now i'm still getting nowhere, please help, i'm only using {JSON.stringify(device, null, 3)} to display the returned array of object that's why i know i'm getting an array of object. I'm open to suggestions and correction. Thank you.

I need the output to be like this, regardless how many devices/data i add in array of object.

Device      Serial             Status
Device1     121                online
device2     234135             offline
balcony     ash3               online
bathroom    dsgfkahaskj23      online
so on...    tj2l5              offline

2 Answers 2

1

You must send an array from the backend. You must send a JSON

In express

app.get("/test", (req, res) => {
  res.json({
    array: [
      {
        name: "device1",
        serial: "WMD105222022",
        status: "online",
      },
      {
        name: "device2q",
        serial: "sdfsdf",
        status: "online",
      },
      {
        name: "ducs",
        serial: "WMD105222022",
        status: "online",
      },
    ],
  });
});

Note that I send a JSON, not an array

In React:

const [data, setData] = useState([]); 

  useEffect(() => {
    var config = {
      method: "get",
      url: "http://localhost:3000/test",
      headers: {},
    };

    axios(config)
      .then(function (response) {
        const data = JSON.stringify(response.data);
        const array = JSON.parse(data).array;
        setData(array);
      })
      .catch(function (error) {
        console.log(error);
      });
  }, []);

Note that I convert the JSON to an object to be able to iterate it

the return on the component

  <table>
    {data &&
      data.map((row, key) => {
        return (
          <tr key={key} style={{ color: "red" }}>
            <td>{row.name}</td>
            <td>{row.serial}</td>
            <td>{row.status}</td>
          </tr>
        );
      })}
  </table>
Sign up to request clarification or add additional context in comments.

1 Comment

Remember that they are asynchronous calls; the value is not available and ready to render until the data arrives; that takes time, so you must validate that you have the data before iterating. {data && data.map((row, key) => {})
0

You can extract the columns name, ie. "Device", "Serial", "Status", into an array, and iterate over them using map function:

  const [data, setDate] = useState();
  const columns = ["Device", "Serial", "Status"]; // hard code the columns

  const lookUpDataKey = {
    Device: "name",
    Serial: "serial",
    Status: "status"
  };

  useEffect(() => {
    setDate(dataFromApi); // mimic getting data from api
  }, []);

  if (!data) return <div>loading</div>;

  return (
    <div className="App">
      <div style={{ display: "flex" }}>
        {columns.map((column, columnIndex) => (
          <div key={columnIndex}>
            {/* Column name */}
            <div>{columns[columnIndex]}</div>

            {/* Column data */}
            {data.map((item, dataIndex) => (
              <div key={dataIndex}>
                <div>{item[lookUpDataKey[column]]}</div>
              </div>
            ))}
          </div>
        ))}
      </div>
    </div>
  );

Notice we use a lookUpDataKey object for matching column's name to the corresponding object key.

Try it out in updated sandbox.

4 Comments

i'm getting a TypeError: Cannot read properties of undefined (reading 'name') i thought this would work too but not sure what's going on with it.
Did you forget to initilize the columns array: const columns = ["name", "serial", "status"]; ? Where's does the error come from?
my bad, this works but i have an issue, after adding a new data it doesn't show since it's tide on the number of columns, and the data shows in one column, how can i change that to show only the name of devices under column name and serial numbers only in serial column and so on
but i have an issue, after adding a new data it doesn't show since it's tide on the number of columns, and the data shows in one column, how can i change that to show only the name of devices under column name and serial numbers only in serial column and so on.... i also update the kind of output i need on my question, regardless how many data i add on my array of objects

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.