27

I have a JSON object that I want to iterate through.

"phone": {
    "Samsung": {
        "type": "S7"
    },
    "iPhone": {
        "type": "6S"
    },
    "Google": {
        "type": "Pixel"
    }
}

I'm using Object.key to map through each of these values, which I THINK is the correct way to work with objects:

render() {
    //this.props.phone contains the objects "Samsung", "iPhone", and "Google"
    return (
        Object.keys(this.props.phones).map((type) => {
            console.log(type)
            return (
                <p>Type of phone: {type}</p>
            )
        })
    )
} 

However, the console.log above returns this when I was expecting an object to return:

enter image description here

Why is it returning a value, and not an object?

patrickhuang94
  • 2,085
  • 5
  • 36
  • 58
  • *"Return value: An array of strings that represent all the enumerable properties of the given object."* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys – Felix Kling Feb 20 '17 at 21:04

5 Answers5

37

This is strictly speaking a answer, but it can easily be shimmed into older versions of Javascript.

You want to use either Object.values or Object.entries to loop through all the properties in an object. Where Object.keys gives you the keys, Object.values gives you the properties (well, duh) and Object.entries gives you an array [key, value] for each entry in the object.

You don't use the key in your current code, so here's the Object.values option:

    Object.values(this.props.phones).map((type) => {
        console.log(type)
        return (
            <p>Type of phone: {type}</p>
        )
    })

and here's the Object.entries option, if you wanted to use both:

    Object.entries(this.props.phones).map(([make, type]) => {
        console.log(make)
        console.log(type)
        return (
            <p>Make of phone: {make}</p>
            <p>Type of phone: {type}</p>
        )
    })

You'll see that we're using ES6 destructuring to get the two values out of the array we get from Object.entries.

The shims are linked on the MDN pages for each function.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
5

Because you iterate over object keys. To return object in your case you have to use given key to get its value:

render() {
    //this.props.phone contains the objects "Samsung", "iPhone", and "Google"
    return (
        Object.keys(this.props.phones).map((type) => {
            console.log(this.props.phones[type])
            ...
        })
    )

}
Bartek Fryzowicz
  • 6,464
  • 18
  • 27
3

The keys of an object are strings, so that is what you will get back when looking at Object.keys(someObject). The value associated with that key is the object you were looking for. In order to obtain the value, in your map iteration, you would need to access the object with your key.

var self = this;//close over this value for use in map
return (
    Object.keys(this.props.phones).map((type) => {
        console.log(self.props.phones[type]);//this will yield the object
        return (
            <p>Type of phone: {self.props.phones[type]}</p>
        )
    })
)
Travis J
  • 81,153
  • 41
  • 202
  • 273
1

You have iterated over the keys. So the type variable in your loop will be set to Samsung, iPhone and Google. Then you use this.props.phone[type] to access the value objects. Please fix the phones key in your code which is different from phone key in the JSON object.

render() {
    //this.props.phone contains the objects "Samsung", "iPhone", and "Google"
    return (
        Object.keys(this.props.phone).map((type) => {
            console.log(this.props.phone[type])
            return (
                <p>Type of phone: {this.props.phone[type]}</p>
            )
        })
    )
} 
uautkarsh
  • 492
  • 3
  • 9
1

You can use arrow function and destructuring of params to make it easier to read your code. Since Object.keys return the keys of the given object as an array, you need to iterate over the array and extract the value using the current key. You need to assign a unique key to list elements in React, so p key={phoneKey}.. is related to that, for more information checkout Lists and Keys

const {phones} = this.props;
const phoneKeys = Object.keys(phones);

render() {
    return (
        phoneKeys.map(phoneKey) => <p key={phoneKey}>Type of phone: {phones[phoneKey].type}</p>)
    )
} 
cubbuk
  • 7,800
  • 4
  • 35
  • 62