2

How can I iterate through this object using .map():

state = { 
      contacts: [
        { "id":1,
           "name":"Leanne Graham",
           "email":"[email protected]",
           "address":{
              "street":"Kulas Light",
              "city":"Gwenborough",
              "geo":{
                 "lat":"-37.3159",
                 "lng":"81.1496"
              }
           },
           "phone":"1-770-736-8031",
        },
        { "id":2,
           "name":"Ervin Howell",
           "email":"[email protected]",
           "address":{
              "street":"Victor Plains",
              "city":"Wisokyburgh",
              "geo":{
                 "lat":"-43.9509",
                 "lng":"-34.4618"
              }
           },
           "phone":"010-692-6593",
        }
     ]
    }

so map over the contacts will work because is an array and all data like id, name, email and phone is accessible but if I want to iterate over the address, is crashing. I have used some example like:

render(){
  const {contacts} = this.state
  return(
    <>
       {Object.keys(contacts.address).map((address, index) => (
          <span className="d-block" key={index}>{contacts.address[address]}</span>
        ))}
    </>
  );
}

which should work with address but is crashin on geo{} and at this point I have lost the signal.

Anyone can give me an ideea ?

2
  • how do you want the the output to be in case of geo? Commented Mar 23, 2020 at 10:49
  • @Supercool I don't think is matter as long as it displays them Commented Mar 23, 2020 at 10:50

3 Answers 3

2

This should help:

const address = contacts[0].address;

<>
  {Object.keys().map((addressKey, index) => (
    <span className="d-block" key={index}>
      {typeof address[addressKey] === "object"
        ? Object.keys(address[addressKey]).map(e => (
            <span>{address[addressKey][e]}</span>
          ))
        : contacts[0].address[address]}
    </span>
  ))}
</>;
Sign up to request clarification or add additional context in comments.

Comments

2

I don't think is a matter as long as it displays them

After you mapped the contacts you can excess the addresses properties as you like:

const contacts = [
  {
    id: 1,
    name: "Leanne Graham",
    email: "[email protected]",
    address: {
      street: "Kulas Light",
      city: "Gwenborough",
      geo: {
        lat: "-37.3159",
        lng: "81.1496",
      },
    },
    phone: "1-770-736-8031",
  },
  {
    id: 2,
    name: "Ervin Howell",
    email: "[email protected]",
    address: {
      street: "Victor Plains",
      city: "Wisokyburgh",
      geo: {
        lat: "-43.9509",
        lng: "-34.4618",
      },
    },
    phone: "010-692-6593",
  },
];

const addresses = contacts.map(({ address, id }) => ({
  id,
  ...address,
}));

console.log(addresses);

Like rendering them:

addresses.map(({ street, city, id }) => (
  <span className="d-block" key={id}>
    {street}:{city}
  </span>
))

Comments

1

You can map over an array because you expect it to have consistent values through each element, but that is not really the case for object. All the values are different and have different meaning. Also, your span will not be able to display objects, it will only primitive values such as strings or numbers

You can do what you want to achieve manually.

const { contacts } = this.state;
return (
  <>
    {contacts.map(({ address }, id) => {
      return (
        <React.Fragment key={id}>
          <span>Street: {address.street}</span>
          <span>City: {address.city}</span>
          <span>Lat: {address.geo.lat}</span>
          <span>Lng: {address.geo.lng}</span>
        </React.Fragment>
      );
    })}

If you really want to do it using a loop or some form of iteration you can look into Object.entries. But it would be really difficult to do that with nested objects if you do not know what you are dealing with.

contacts.map(({ address }) => {
  for (let [key, value] of Object.entries(address)) {
    console.log(`${key}: ${value}`); // logs "street: Kulas Light"
  }
})

but note for geo it will give "geo: [Object object]" if you put this directly into a span.

P.S I would recommend finding a better key than the index of array for the Fragment.

2 Comments

this look good to me but didn't worked on my code :| can you add your example in here ? codesandbox.io/s/wonderful-mahavira-bmsqw
codesandbox.io/s/sharp-noether-cr4km. Added a solution here, the issue was that I had not added Fragments before the elements. I will update the answer as well.

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.