0

This is the original data:

const myArray = [
  'id': 'stuff', 'location': 'stuff2', 
  'phone_numbers'['stuff3','stuff4'], "address" : 'stuff5'
]


// so far, I'm getting the correct values back in an array from an API.
console.log(myReturnedArray) = [
{
"id": "10001",
"brand": "Best Brand",
"center_name": "Best Brand Texas",
"status": "Active",
"emails": [
  {
    "CreateDate": "October 12, 2022 at 10:59:09 AM UTC-5",
    "emailAddress": "[email protected]",
    "firstName": "Test",
    "lastName": "Tester",
    "id": "0eac8839-6e61-42f5-b55f-e2fa17b0262b",
    "licenseType": "Unlimited",
    "updateDate": "October 12, 2022 at 10:59:09 AM UTC-5",
    "userType": "STORE"
  }
],
"licenses": [
  {
    "CreateDate": "October 12, 2022 at 10:59:09 AM UTC-5",
    "licenseType": "STORE",
    "status": "ASSIGNED",
    "updatedBy": "SYSTEM",
    "updateDate": "October 12, 2022 at 10:59:09 AM UTC-5",
    "renewDate": "October 12, 2022 at 10:59:09 AM UTC-5",
    "expirationDate": "October 12, 2022 at 10:59:09 AM UTC-5",
    "id": "0eac8839-6e61-42f5-b55f-e2fa17b0262b"
   }
  ]
 }
]

*** whenever i try a map function i get the error "Objects are not valid as a React child (found: object with keys {id, brand, center_name, status, emails, licenses}). If you meant to render a collection of children, use an array instead." ***

I would like to display each value from my returned array in a div or span, but I keep getting errors like cannot get properties of undefined reading map, or a unique keys error whenever I try something.

// I would like to have each value from the object inside of myReturnedArray to use in my return statement.
return (
    <span>your email is : "[email protected]", </span>
    <div> your first name is : "Test" </div>
    <span> your last name is : "lastName": "Tester", </span>
);

Anytime I try and use a map function like this in my return statement:

{ myReturnedArray.map(item => <div>{item.name}</div>) } 

It returns myReturnedArray is undefined. But when I do:

{ JSON.stringify(myReturnedArray) }

It renders returnedArray as a string correctly. So I know the return method has access to the array; I just can't display it.

2
  • Can you show us more react codes before the return statement? Commented Oct 12, 2022 at 22:24
  • myArray looks pretty messed up. Are you sure that is the correct format that is being returned by your database? Commented Oct 12, 2022 at 23:16

3 Answers 3

1

You don't have a name property in your array items. Here is an example of code with your data that displays its content properly:

https://codesandbox.io/s/vigorous-euclid-nzbcp0?file=/src/App.js:24-283

Sign up to request clarification or add additional context in comments.

2 Comments

This looks great, I tried your code with my actual data, i got the error that I listed in my question though. Could you try doing it with my actual data. I listed it in the question
If you mean this data const myArray = [ 'id': 'stuff', 'location': 'stuff2', 'phone_numbers'['stuff3','stuff4'], "address" : 'stuff5' ] you have a problem, it's not an array, should be an object and you are missing a ":" between your 'phone_numbers' key and its value ['stuff3','stuff4']. That's probably why you got an error. I modified the code with that assumption and it works, check it out again and let me know.
1

Final solution: codeSandbox

Explantion to the errors you got:

1: The data structure you updated is very complex and nested with object inside array and arrays inside this object and so on. So, of course it will throw an error "Objects are not valid as a React child".

You can't put an entire object between div tags, You need to map this object fields one by one to have single values between each div.

2: About the "unique key" issue - this is a warning, not an error. It's always showing this warning when you map object items to elements without adding the key attribute to each item.

So in order to get rid of this warning, Just add the key attribute to the divs that are returned inside a map function, and choose some uniqe key.


How can you map it like this?

As I understood, The structure you have is one big array - myReturnedArray, and in this array you will have many(now you have just one) objects when each one contains:

  • An emails array which contains object(s).
  • An licenes array which contains object(s).
  • Some other key:value pairs.

In order to map myReturnedArray correctly - You'll need a ForEach loop that will map every big object inside of it, and then return all the mapped objects together.


First, I created an helper function that maps an array of objects(without nested arrays or something) to HTML div tags.

And I will use this function in order to map the emails and licenes arrays.

Helper function:

  const mapArrayOfObjects = (array) => {
    const arrayAsDivs = array.map((obj, index) => {
      const mappedObj = Object.entries(obj).map(([key, value]) => {
        return <div key={key}>{key + ' : ' + value}</div>;
      });
      return (
        //Returns a div with one object of the array and space after it.
        <div key={'nestedObj' + index}>
          {mappedObj}
          <br />
        </div>
      );
    });
    return arrayAsDivs; //The function returns ALL the mapped objects in the array.
  };

It looks complex, but all it does is going through the array, and mapping each object to a big div tag with all the key:value pairs as nested divs. (And I added the br to have some space between the objects. (In your case you have just one object in the emails, but I assume that there would more.)

Using forEach

In this function, I map all the big objects that are inside myReturnedArray:

const allObjectsHTML = [];

  myReturnedArray.forEach((obj) => {
    const emailsAsDivs = mapArrayOfObjects(obj.emails);
    const licensesAsDivs = mapArrayOfObjects(obj.licenses);
    const otherFields = Object.entries(obj).map(([key, value]) => {
      if (!Array.isArray(value)) {
        return <div key={key}>{key + " : " + value}</div>;
      }
    });
    const objectAsHTML = (
      <div>
        <div>{otherFields}</div>
        <div>
          <h3>Emails:</h3>
          {emailsAsDivs}
        </div>
        <div>
          <h3>Licenses:</h3>
          {licensesAsDivs}
        </div>
      </div>
    );
    allObjectsHTML.push(objectAsHTML);
  });

What this function does in each iteration:

  • Use the helper function to map the emails,licenses arrays.
  • Map the rest of the key:value pairs in the object.
  • Push the mapped object to the allObjectsHTML array that will contain all the mapped objects.

And for the last step

Now all you need to do is that in your JSX code you return:

 return (
    <>
      {allObjectsHTML.map((obj,index) => (
        <div key={"bigObj"+index}>{obj}<hr/></div>
      ))}
    </>
  );

This returns a mapped version of the allObjectsHTML.

This is the codeSandbox of my code.

And in case you want to check if it works on many objects in your array: second codeSandbox.

Note: If you know for sure that you have just one object in the myReturnedArray - then you don't need to use forEach. See this code.

Comments

0

The initial format of your data is flawed, it's not a JS syntax. To get it done properly first you have to make it a proper data container. For this kind of task you don't need arrays, you have an object for that.

  const data = {
    id: 'stuff',
    location: 'stuff2', 
    address: 'stuff5',
    phone_numbers: ['stuff3','stuff4']
  }

Then in your React Components return section you may ve it done like this:

const {id, location:dataLoc, address, phone_numbers:phNums} = data
const [num1, num2] = phNums

return (
    <div>{dataLoc}</div>
    <span>{address}</span>
    //etc
)

I also reformatted yopur code a bit to meet the JS naming conventions. We use camelCase here, so no phone_numbers (snake_case is for Py)but phNum.

1 Comment

Thanks for the help. I think this question needed more specificity so I added my actual data. I still get the error though about objects not being valid with react child

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.