How can I grab the key of a list item generated from a map function?

react map object
javascript map function
react map array of objects
react native map array of objects
javascript map object
angular map function
react map nested array
react loop through array of objects

So I am learning React, and I've tried searching for solutions to my problem both on stackoverflow and on React's own documentation, but I am still stumped.

Essentially, I have a list of 10 subreddits that is being mapped to list items in the form of the subredditsArray variable.

I render the results, and try to pass the selected item when I click that list item to my getSubredditInfo function. However, this doesn't work - event.target.key is undefined. (To clarify, I am looking to grab the key of the single list element that I have clicked).

When I try to just get event.target, I get the actual htmlElement (ex: <li>Dota2</li>), where as I want to get the key, or at least this value into a string somehow without the tags. I also tried putting my onClick method in the list tag of the map function, but that did not work.

Here is the relevant code:

//this is where I get my data
componentDidMount(){
    fetch('https://www.reddit.com/api/search_reddit_names.json?query=dota2')
    .then(results => {
        return results.json();
    })
    .then(redditNames => {
        //this is there I set my subreddits state variable to the array of strings
        this.setState({subreddits: redditNames.names});
    })
}

   getSubredditInfo(event){
    //console.log(event.target.key); <-- DOESNT WORK

}

render() {

 var subredditsArray = this.state.subreddits.map(function(subreddit){
    return (<li key={subreddit.toString()}>{subreddit}</li>);
});

  return (
    <div className="redditResults">
      <h1>Top 10 subreddits for that topic</h1>
      <ul onClick={this.getSubredditInfo}>{subredditsArray}</ul>
    </div>
  );
}

My questions essentially boil down to:

  1. How do I grab the key value from my list object?
  2. Additionally, is there a better way to generate the list than I currently am?

Thank you in advance.

EDIT: Added my componentDidMount function in hopes it clarifies things a bit more.

try the following code:

class App extends React.Component {
  constructor(props){
     super(props);
     this.state = {subreddits:[]};
  }
  
  componentDidMount(){
    fetch('https://www.reddit.com/api/search_reddit_names.json?query=dota2')
    .then(results => {
        return results.json();
    })
    .then(redditNames => {
        //this is there I set my subreddits state variable to the array of strings
        this.setState({subreddits: redditNames.names});
    })
  }
  
  getSubredditInfo(subreddit){
     console.log(subreddit);
  }
  
  render() {
    return <div className="redditResults">
      <h1>Top 10 subreddits for that topic</h1>
      <ul>
        { 
            this.state.subreddits.map((subreddit)=>{
                return (<li key={subreddit.toString()} onClick={()=>this.getSubredditInfo(subreddit)}>{subreddit}</li>);
            })
        }
      </ul>
    </div>;
  }
}

ReactDOM.render(
  <App/>,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

From an array of objects, extract value of a property as array, property() is a shorthand function that returns a function for getting the value of a property in an object. Additionally, _.map() now allows a string to be passed in as​  The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys: const todoItems = todos. map ((todo) => < li key = { todo. id } > { todo. text } </ li >) ;

You can use lamda function or make component for item list which have own value for getSubredditInfo function

getSubredditInfo(value) {}

render() {

  var subredditsArray = this.state
   .subreddits.map((subreddit, i) => 
     (<li key={i} 
          onClick={() => this.getSubredditInfo(subreddit)}>{subreddit}</li>));

  return (
    <div className="redditResults">
      <h1>Top 10 subreddits for that topic</h1>
      <ul>{subredditsArray}</ul>
    </div>
  );
}

Index inside map() Function, How to store a key=> value array in JavaScript ? In JavaScript, map() method handles array elements, which creates a new array with the help The index is used inside map() method to state the position of each element in an array, but it doesn't Please use ide.geeksforgeeks.org, generate link and share the link here. Let’s step away from the individual data structures and talk about the iterations over them. In the previous chapter we saw methods map.keys (), map.values (), map.entries (). These methods are generic, there is a common agreement to use them for data structures. If we ever create a data structure of our own, we should implement them too.

1) Key should be grabbed either by the id in your object in array. Or you can combine the 2 properties to create a unique key for react to handle re-renders in a better way.

If you have a string array, you may use a combination of string value + index to create a unique value, although using index is not encouraged.

Given a quick example for both below.

2) A better way could be to move your map function into another function and call that function in render function, which will return the required JSX. It will clean your render function.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      subredditsObjArray: [
        { id: 1, value: 'A'},
        { id: 2, value: 'B'},
        { id: 3, value: 'C'},
        { id: 4, value: 'D'}
        ],
      subredditsArray: ['A', 'B', 'C', 'D'],
      selectedValue: ''
    };
  }

  getSubredditInfo = (subreddit) => {
    console.log(subreddit)
    this.setState({
      selectedValue: ((subreddit && subreddit.id) ? subreddit.value : subreddit),
    });
  }

  render() {
    return (
      <div className="redditResults">
        <p>Selected Value: {this.state.selectedValue}</p>
        <h1>Top {this.state.subredditsArray.length || '0'} subreddits for that topic</h1>
        <p>With Objects Array</p>
        <ul>
          {
            this.state.subredditsObjArray
              && this.state.subredditsObjArray.map(redditObj => {
                return (<li key={redditObj.id}><button onClick={() => this.getSubredditInfo(redditObj)}>{redditObj.value || 'Not Found'}</button></li>);
              })
          }
        </ul>
        <br />
        <p>With Strings Array</p>
        <ul>
          {
            this.state.subredditsArray
              && this.state.subredditsArray.map((reddit, index) => {
                return (<li key={reddit + '-' + index}><button onClick={() => this.getSubredditInfo(reddit)}>{reddit || 'Not Found'}</button></li>);
              })
          }
        </ul>
      </div>
    );
  }

}

ReactDOM.render(
  <App etext="Edit" stext="Save" />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

How to simplify your codebase with map(), reduce(), and filter() in , If you have a good example of using a map or reduce method — post it in the comments section. Remove duplicates from an array of numbers/strings The filter() method creates a new array with all elements that pass the test Extract the unique values for the given key of each item in the array. map (), filter (), lambda, and list comprehensions provide compact, elegant, and efficient ways to encode a few common idioms in programming. We often encounter the following scanarios involving for-loops: Building up a list from scratch by looping over a sequence and performing some calculation on each element in the sequence.

Are you trying to do this? I'm not sure what you want to do.

getSubredditInfo(e, subreddit) {
  console.log(subreddit)
}

render() {
  const { subreddits } = this.state
  var subredditsArray = subreddits.map(subreddit => (
    <li 
      key={subreddit.toString()} 
      onClick={(e) => {
        this.getSubredditInfo(e, subreddit)
      }}
    >
      {subreddit}
    </li>
  ))

  return (
    <div className="redditResults">
      <h1>Top 10 subreddits for that topic</h1>
      <ul>{subredditsArray}</ul>
    </div>
  );
}

The key purpose is to pass your subreddit to the onClick function so you will receive the value while you click the item.


If you still get error try this and tell me what's happened.

render() {
  const { subreddits } = this.state
  var subredditsArray = subreddits.map(subreddit => (
    <li 
      key={subreddit.toString()} 
      onClick={(e) => {
        console.log(subreddit.toString())
      }}
    >
      {subreddit}
    </li>
  ))

  return (
    <div className="redditResults">
      <h1>Top 10 subreddits for that topic</h1>
      <ul>{subredditsArray}</ul>
    </div>
  );
}

Lists and Keys – React, Below, we loop through the numbers array using the JavaScript map() function. We return a <li> element for each item. Finally, we assign the resulting array of  Python map () function is used to apply a function on all the elements of specified iterable and return map object. Python map object is an iterator, so we can iterate over its elements. We can also convert map object to sequence objects such as list, tuple etc. using their factory functions. Python map () function syntax is:

.map(), Within the callback function, this refers to the current DOM element for each iteration. The function can return an individual data item or an array of data items to be  A new array with each element being the result of the callback function. Description. map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values (including undefined).

Map.prototype.keys(), The keys() method returns a new Iterator object that contains the keys for each element in the Map object in insertion order. The last scenario is an infrequent iteration one where you may need to get a property by its index. For example, you may have a filtered list where you know there's a fixed result and you just want to grab a specific result - typically the first one. function getMapKeyValueByIndex(obj, idx) { var key = Object.keys (obj) [idx]; return { key: key

Getting JavaScript Properties for Object Maps by Index or Name , Enter the Object.keys() method which allows you to get a specific property Lots of applications including my own use object maps for holding lists of values or enumerated types. a filtered list where you know there's a fixed result and you just want to grab a this post created with Markdown Monster  Hello, guys! Many of my readers emailed me, asking to write a post about the map and filter function of Java 8, because they found it difficult to use and understand. Even though I have previously

Comments
  • So I tried something similar earlier in my efforts, and it didn't work. I get an undefined error: "TypeError: Cannot read property 'getSubredditInfo' of undefined"
  • can you tell me about the content of your subreddits array? is it string array? or object array? i am trying to create a jsfiddle for you.
  • It's an array of strings.
  • Your were getting error: "TypeError: Cannot read property 'getSubredditInfo' of undefined" only because you were using conventional function. notice i use arrow function and this does not block the this. so its working now.
  • @ddantas you can run my code snippet now and it works perfectly as you expect it to.
  • I think there is an issue with having "this.getSubredditInfo" inside of the map function. It returns "TypeError: Cannot read property 'getSubredditInfo' of undefined". Do you perhaps know why this is the case when I put it in the map function but not in the ul tag in the return statement?
  • Need use lamda function =>. It save parent context (this)
  • I think this might be a good way to go, however, it runs into the issue that all the other comments are resulting in - it returns an undefined error when I put this.getSubredditInfo in the map function, but doesn't when I put it in the <ul> tag below in the final render return. Any ideas why it returns an error?
  • Do you have the full error log can we take a look? May be a screenshot or something else.That's shouldn't be a problem.