hernandeΩ
hernandeΩ

Reputation: 89

React set state to nested object value

I need to set state on nested object value that changes dynamically Im not sure how this can be done, this is what Ive tried.

const [userRoles] = useState(null);

const { isLoading, user, error } = useAuth0();

useEffect(() => {
    console.log(user);
    // const i = Object.values(user).map(value => value.roles);
    // ^ this line gives me an react error boundary error 
  }, [user]);

// This is the provider
<UserProvider
      id="1"
      email={user?.email}
      roles={userRoles}
>

The user object looks like this:

{
    name: "GGG",
    "website.com": {
      roles: ["SuperUser"],
      details: {}
    },
    friends: {},
    otherData: {}
}

I need to grab the roles value but its parent, "website.com" changes everytime I call the api so i need to find a way to search for the roles.

Upvotes: 1

Views: 591

Answers (3)

StefanBob
StefanBob

Reputation: 5128

I would recommend what others have said about not having a dynamic key in your data object.

For updating complex object states I know if you are using React Hooks you can use the spread operator and basically clone the state and update it with an updated version. React hooks: How do I update state on a nested object with useState()?

Upvotes: 1

Drew Reese
Drew Reese

Reputation: 202751

You can search the values for an element with key roles, and if found, return the roles value, otherwise undefined will be returned.

Object.values(user).find(el => el.roles)?.roles;

Note: I totally agree with others that you should seek to normalize your data to not use any dynamically generated property keys.

const user1 = {
    name: "GGG",
    "website.com": {
      roles: ["SuperUser"],
      details: {}
    },
    friends: {},
    otherData: {}
}

const user2 = {
    name: "GGG",
    friends: {},
    otherData: {}
}

const roles1 = Object.values(user1).find(el => el.roles)?.roles;
const roles2 = Object.values(user2).find(el => el.roles)?.roles;

console.log(roles1); // ["SuperUser"]
console.log(roles2); // undefined

Upvotes: 1

Code-Apprentice
Code-Apprentice

Reputation: 83527

I think you need to modify the shape of your object. I find it strange that some keys seem to be fixed, but one seems to be variable. Dynamic keys can be very useful, but this doesn't seem like the right place to use them. I suggest that you change the shape of the user object to something like this:

{
    name: "GGG",
    site: {
      url: "website.com",
      roles: ["SuperUser"],
      details: {}
    },
    friends: {},
    otherData: {}
}

In your particular use case, fixed keys will save you lots and lots of headaches.

Upvotes: 1

Related Questions