REACT: Render the keys of only one object

So I have an object of objects, and I’m trying to render only the keys from the first object. I’ll post the full codepen at the end, but so far I’ve got:

renderKeys = () => {
  return Object.keys(this.props.data).filter((obj) => Object.keys(this.props.data).indexOf(obj) == 0).map(obj => {
    return (
    <div>
     {Object.keys(obj)}   
    </div>
    )
  })
  }

The first part


Object.keys(this.props.data).filter((obj) => Object.keys(this.props.data).indexOf(obj) == 0)

Is being used to isolate the first object, and renders “object1” to the DOM as I’d intended. However, when I try to map over it to get just the keys, like so:

.map(obj => {
    return (
    <div>
     {Object.keys(obj)}   
    </div>
    )
  })

I’m getting 0123456 rendered to the DOM, which for the life of me I cannot figure out. Can anyone shed some light on this?

Full codepen: https://codepen.io/mkedenburg/pen/mGJBjg

The problem with

(this.props.data).filter((obj) => Object.keys(this.props.data).indexOf(obj) == 0)

is that you are returning just the key name object1 and you then you try to map over this. A string is a bit like an array of characters so when you try to get Object.keys of a string it gives you the index of each array item. In javascript under the hood an array is just a keyed object.

["red", "green", "blue"] is the same as

{
   0: 'red',
   1: 'green',
   2: 'blue'
}

Hence when you get the key of this array of letters it give you 01234.

So your solution would be to do something like this:

renderKeys () {
    const firstObject = Object.keys(this.props.data)[0];
    return Object.keys(this.props.data[firstObject])
      .map(key => {
        return <div>{key}</div>;
      });
  };
1 Like

I agree with what your saying here. I guess the question is here is somewhat of a strange use case. In general if you are using a keyed object to store values, you would be doing so, so that you can access objects by Id. If you wanted to access values in a way where order matters, arrays are a much better mechanism.

A more full proof solution where we need to be sure we always access the first element in a data structure would be to use an array.

A third solution, combining the best of both words, store the order in a separate property.

const Cdata = {
 data: {
 object1: {
    name: "name1",
    finished: "2018-07-18",
    price: "£100",
    paid: "Pending"
  },

  object2: {
    name: "name2",
    started: "2018-08-22",
    price: "£100",
    paid: "Received"
  }
},
byId: ['object1', 'object2', '1', 'anotherObjectKey']
};

// access the keys
const id = this.props.data.byId[0];
const props = Object.keys( this.props.data.data[id]);

Good catch!