Search code examples
javascriptarraysreactjsreactjs-fluxreactjs-native

ReactJS render a OBJ.map based on values of an array


I am trying to render a set of <div> </div> based on the items that are in an object but I don't want to have to specify the name of the items in the object in order to display them.

In the example below I want the WorkObjectID and WorkObjectVal to be dynamic and not static. If I add the tempObject to the object it will not be displayed when the data is rendered because I did not define it in the miniTable.

I would like to specify which ones will be shown by sending them if possible in the var WORKOBJECTSVALS = {}.

  var WORKOBJECTS = [ {
                      WorkObjectID: "1", WorkObjectVal: "First",
                      TempObject1: "55", TempObject2: "Denied" 
                      }, 
                      {
                       WorkObjectID: "2", WorkObjectVal: "Second",
                      TempObject1: "110", TempObject2: "Allowed" 
                      }];
  var WORKOBJECTSVALS = {"WorkObjectID", "WorkObjectVal", "TempObject1" };

  render: function () {
    var miniTable = this.state.WORKOBJECTS.map(function(val) {
      return (
         <div> {val.WorkObjectID} </div>
         <div> {val.WorkObjectVal} </div>

      );
    });
    return(
      {miniTable}
    );
}

In the example above I would like the TempObject1 to be displayed but not the TempObject2. If I decide in the future that I would like the TempObject2 to be added into the div I would only need to add it to WORKOBJECTSVALS, how can I do this?


Solution

  • What you need to do is work with the property names since those are the key. Object.keys returns an array of property names. Then add a filter before the map so that the unwanted property names are removed.

    Here's a modification of your example that starts by using Object.keys (Note the changes in definition of WORKOBJECTS and WORKOBJECTSVALS so they are both objects and not arrays)

    var WORKOBJECTS = { WorkObjectID: "1", WorkObjectVal: "First",
                        TempObject1: "55", TempObject2: "Denied" };
    var WORKOBJECTSVALS = { WorkObjectID: true, WorkObjectVal: true, TempObject1: true };
    
    render: function () {
      var workObjects = this.state.WORKOBJECTS;
      var miniTable = Object.keys(workObjects).
        .filter(function(keyName) {
          return WORKOBJECTSVALS[keyName];
        })
        .map(function(keyName) {
          var workObjectID = keyName;
          var workObjectVal = workObjects[keyName];
          return (
             <div> {workObjectID} </div>
             </div> {workObjectVal} </div>
          );
        });
      return(
        {miniTable}
      );
    }
    

    And if WORKOBJECTSVALS has to be an array, you can change the filter to do this. However it is less efficient, especially if the array is large

    .filter(function(keyName) {
      return WORKOBJECTSVALS.indexOf(keyName) !== -1;
    })