Use Array.filter() to Dynamically Filter an Array

Tell us what’s happening:
I am getting this error message below and can’t figure out how to fix it. I believe that I am writing the filter and map methods correctly. I believe that I using the key in each li correctly. Any ideas appreciated!!!

// running test
Method “key” is only meant to be run on a single node. 0 found instead.
MyComponent should render li elements that contain the username of each online user.
MyComponent should return a div, an h1, and then an unordered list containing li elements for every user whose online status is set to true.
// tests completed

Your code so far


class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [
        {
          username: 'Jeff',
          online: true
        },
        {
          username: 'Alan',
          online: false
        },
        {
          username: 'Mary',
          online: true
        },
        {
          username: 'Jim',
          online: false
        },
        {
          username: 'Sara',
          online: true
        },
        {
          username: 'Laura',
          online: true
        }
      ]
    }
  }
  render() {
    const usersOnline = this.state.users.filter(user => user.online);
    const renderOnline = usersOnline.map((item) => 
      {<li key={item.toString()}>{item}</li>})
    return (
       <div>
         <h1>Current Online Users:</h1>
         <ul>
           {renderOnline}
         </ul>
       </div>
    );
  }
};

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/react/use-array-filter-to-dynamically-filter-an-array

The line

      {<li key={item.toString()}>{item}</li>})

It is not required to place in the outer curly braces that surround the list tags, nor is it needed to convert the values to strings. Correct those first, and mind you the variable item is a object, you want to pull something from it to represent the key.

1 Like

RESENDING DUE TO WRONG FORMATTING!

Thank you for your reply! I added an index element in map and used that as the key. I am still getting an error that says ‘Objects are not valid as a React child (found: object with keys {username, online}).’ Don’t really understand what this error means but below is my code. Appreciate your feedback!

Thank you for your reply! I added an index element in map and used that as the key. I am still getting an error that says ‘Objects are not valid as a React child (found: object with keys {username, online}).’ Don’t really understand what this error means but below is my code. Appreciate your feedback!

Here is the link to my code
https://learn.freecodecamp.org/front-end-libraries/react/use-array-filter-to-dynamically-filter-an-array

Not sure that it will show up correctly but what I did was re-do the map to:

const renderOnline = usersOnline.map((user,index) => <li key={index}>{user}</li>);

Arrow function has implicit return.

So when you wrote this:

usersOnline.map((user,index) => <li key={index}>{user}</li>)

You are actually saying " for each element RETURN a li"

While on the other hand wrapping the statement of the arrow function in curly braces means you need to be explicit about what you want to RETURN.

So this

usersOnline.map((item) => 
      {<li key={item.toString()}>{item}</li>})

is not returning nothing (undefined perhaps).

You could have changed the statment to:

usersOnline.map((item, index) => {
  return <li key={index}>{item}</li>
})

To be equivalent to the working wersion :slight_smile:
Hope it helps

Hello! Thank you for your reply! So I made the change per your suggestion but I am still getting an error
Objects are not valid as a React child (found: object with keys {username, online}). Any ideas appreciated!

 const renderOnline = usersOnline.map((item, index) => {
  return <li key={index}>{item}</li>
});

usersOnline returns an array of objects.

So your “item” in the usersOnline array actually refers to an object. But what you want is the username in the object and not the object itself.

Try this:

const renderOnline = usersOnline.map(x => <li key={x.username}>{x.username}</li>);
7 Likes

<li key={item.toString()}>{item}</li>

In the above code, remember that “item” represents an object, in this case a “user.” Each “user” object has two properties associated with it, a ‘username’ property and an ‘online’ property (online status). What we want to display is the username of the user, which would be, in this case,
item.username

Hope this helps:

render() {
    let usersOnline = this.state.users.filter(user => {
      return user.online === true;  /* can use just - (return user.online),
                                       put for your  reference. */
    }) ; 

/* filters through the Array - 'users' which is present in the 
'state' and returns only those users which has 'online' property with 
value of 'true' in a new Array called 'usersOnline'*/

    let renderOnline = usersOnline.map((Un,i) => {
     return <li key={i}> {Un.username} </li>
    }); 

/* Now, the new Array 'usersOnline' is mapped through to get the 
  'username' values present in it, and return a <li> element containing 
   the 'usernames' and a unique 'key' value (here its the index value) 
   which is passed in to a new Array called  'renderOnline' containing 
   the above mentioned values */

    return (
       <div>
         <h1>Current Online Users:</h1>
         <ul>
           {renderOnline}  
         </ul>
       </div>
    );
  }
}; 
1 Like

Glitton, hi! Have you found resolving of this problem? It seems like I stuck with almost the same issue for shamefully long time

Hi everyone! You can handle it with the following code. Good luck! :slight_smile:
It’s 100% working

    const usersOnline = this.state.users.filter(user => user.online == true); 
    const renderOnline = usersOnline.map((i) => <li key={i.username + 1}>{i.username}</li>)

Take a look to my solution :wink: