How to map a JSON array to a List in ReactJS?

By : Brian J
Source: Stackoverflow.com
Question!

I'm requesting a sample JSON array from http://jsonplaceholder.typicode.com/users and creating a list of items using the name values of that array in a ReactJS project.

The list is a Grommet list and I use the .map function to map the web service data to each list item.

But when the code renders, instead of creating a list of names using the web service. It creates only one list item and renders the call to .map and rows.push.

Question:

How can you to map a JSON array to a List in ReactJS?

enter image description here

This is what I've tried, first getting the web service via an AJAX GET and then calling .map to map that data to a list:

loadNameData() {
    $.ajax({
      url: 'http://jsonplaceholder.typicode.com/users',
      dataType: 'json',
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error('#GET Error', status, err.toString());
      }.bind(this)
    });
  }

  getInitialState(){
    return {
       data: {
          names: [] 
       }
    };
  }

  componentDidMount() {
    this.loadAssetData();
  }

  render() {
      let layerNode;
      var rows = [];

      layerNode = (
        <Layer flush={true} closer={true} onClose={() => this._onCloseLayer()} align='right'>
          <Box pad='medium' colorIndex='grey-3'>
            <Heading>Filter Options</Heading>
            <Label>Names</Label>
                this.props.data.names.map(function(name) {
                    rows.push(<ListItem justify="between">)
                    rows.push(<span>)
                    rows.push({name})
                    rows.push(</span>)
                    rows.push(</ListItem>)
                }
                <List selectable={true} selected={0}>       
                    {rows}
                </List>           
          </Box>
        </Layer>
      );  

    return (
      <Section pad="small" full="vertical" flex={true}>         
                {layerNode}             
      </Section>
    );
  }
By : Brian J


Answers

I see a few problems here, hopefully I will be able to address them all.

1) I mentioned this in the comments, but it doesn't look like you understand what .map() is supposed to do. Here's a reference.

tl;dr: Calling .map() on an iterable object and passing a function to be executed on each item will return a collection of the return values of that function.

As an example, consider an array with a few names ['Michael', 'Brian', 'John']. I can call .map() on this array and use it to return an array of strings that say "hello" to everyone in the list:

var names = ['Michael', 'Brian', 'John'];
var sayHello = names.map(function (name) {
    return 'Hello, ' + name;
});
console.log(sayHello); // ['Hello, Michael', 'Hello, Brian', 'Hello, John'];

This can be used in React to perform logic that looks something like "Given some names, return some React components that represent the markup for those names".

2) The JSON data you have linked is an array of objects, each with their own name property. It looks like you're using jQuery to fetch this and save the result in this.state.data. This means that this.state.data is an array. So if you try to do this.state.data.names.map(), it's going to fail, because this.state.data.names is undefined. You'll want to do this.state.data.map() instead.

3) Inside of JSX, you can perform JavaScript expressions/statements as long as they're within curly braces {}. It doesn't look like you're doing that.

4) Your call to .map() is on this.props.data, I think you want to do this.state.data instead.

This is everything I saw that should be fixed or improved before this starts working as you expect it to. If it were me, I'd keep your .map() call inside of the <List /> that you're trying to render to:

<List selectable={true} selected={0}>       
    {
        this.state.data.map(function (person) {
            return (
                <ListItem justify="between">
                    <span>{person.name}</span>
                </ListItem>
            );
        })
    }
</List>

Or perhaps a cleaner solution would be to pull this logic out to its own helper function. But that isn't necessary for this to work.

Edit: Here's a demo



Instead of validation testing, System testing is correct word. And Database testing is a part of integration and system testing. Also Load testing will be performed on the phase of system and user acceptance test.

By : Bhanu


While your code does not explicitly mention it, you are actually using an initializer_list in the constructor of list:

list( std::initializer_list<T> init, 
      const Allocator& alloc = Allocator() );

Indeed, you are probably more likely to use standard library containers that accept initializer lists in their constructors (e.g. std::vector, std::list) than writing functions with std::initializer_list arguments yourself. Another example in the standard library are aggregation functions like std::min and std::max that compute a single value from an arbitrary number of input values.

However, there are cases where you might want to use it for your own functions, e.g. for the constructor of a data structure that you implement yourself, or for your own aggregation function. While these things would also be possible with std::vector or std::list, the most straightforward way with the smallest overhead is to use std::initializer_list.



This video can help you solving your question :)
By: admin