Mahmud Adam Mahmud Adam - 4 months ago 13
Javascript Question

Mapping over array returns [object Object]

I have a

Keypad
component, each time I press a button it should add that button's value to an array:

var keys = this.props.keys.map(function(k, index){
return (
<tr className="button-row" key={index}>
<td>
<button
className="keypad-buttons"
onClick={self.props.number.bind(null, k.k)}
>{k.k}</button>
</td>
</tr>
)
})


In my main
App
component I have a method for adding the numbers entered by
Keypad
so that I can map over them and display them in the
textArea
of
my
Screen
component. Here is the relevant part of
App
:

getInitialState: function(){
return {numbers: []}
},
addNumber: function(num){
var number = [
{
n: num
}
]
this.setState({
numbers: this.state.numbers.concat(number)
})
},


In
Screen
component I am trying to map over the props received from
App
like this:

var pinNumbers = this.props.pin.map(function(num, index){
return (
<span key={index}>{num.n}</span>

)
}).join(' ')


And then display that in
textArea
by doing
value={pinNumbers}
. So if I type 1 2 3 on the keypad, it should map over the array of objects and display each of those values (123) in the
textArea
of my
Screen
component; instead, it displays [object Object] and I cannot figure out why. Here is a demo: http://codepen.io/p-adams/pen/PzZWJJ

Answer

The problem is in this code

var pinNumbers = this.props.pin.map(function(num, index){
        return (
                <span key={index}>{num.n}</span>    
                )
    }).join(' ');

It contains JSX. Let's desugar JSX to see what actually happens in that snippet.

<span key={index}>{num.n}</span> will be transpiled to

React.createElement(
  "span",
  { key: index },
  num.n
);

by Babel. You can verify this in online Babel REPL.

Hence, you have an array of React Elements which you convert to strings (receiving obvious [Object object]) and join with spaces.

Actually, your attempt to add spans doesn't make sense because you can not embed HTML formatting into textareas. This piece works for me

var pinNumbers = this.props.pin.map(function(num, index){
  return num.n; 
}).join(' ');
Comments