How to access nested JSON data | REACT

Advertisements

I have a problem when trying to fetch one nested JSON object from local API endpoint /user/{id} that looks like this :

{"userId":122,"name":"kissa","email":"kissa@kissa.com","phone":"04819283921","profile":{"profileId":1,"profileName":"student"}}

Everything else works like a charm but when trying to implement "user.profile.profileName" it gives me an error when reloading the page:

Uncaught TypeError: Cannot read properties of undefined (reading ‘profileName’)

User.jsx

import React from "react";
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import './user.css';

const User = () => {
  const [user, setUser] = useState([]);
  const params = useParams();
  useEffect(() => {
    fetch("http://localhost:8080/api/users/" + params.id)
      .then((response) => response.json())
      .then((user) => setUser(user));
  }, []);

  return (
    <div className="user__container">
      
      <div className="user__table">
        <table>
          <thead>
          <tr>
            <th>UserId</th>
            <th>Name</th>
            <th>Email</th>
            <th>Phone</th>
            <th>Profile</th>
          </tr>
          </thead>
          <tbody>
          <tr>
            <td>{user.userId}</td>
            <td>{user.name}</td>
            <td>{user.email}</td>
            <td>{user.phone}</td>
            <td>{user.profile.profileName}</td>
          </tr>
          </tbody>
        </table>
      </div>
    </div>
  );
};

export default User;

Without {user.profile.profileName} property the table looks good and every other data is visible.

I tried to fetch data from nested JSON object and excepted it to work like other properties but keys inside profile cant be fetched like other properties.

>Solution :

At first render, your user is not loaded yet, so user.profile is undefined.

So you can either, have an early return while you do not have a user loaded

const [user, setUser] = useState();
...

if (!user) return null;

Or use the optional chaining in your JSX

<td>{user?.profile?.profileName}</td>

Leave a ReplyCancel reply