1

I am using React-Redux and have problem to parse array.

I using selector to return data to component, but I am getting error TypeError: this.props.messages.map is not a function. But if I console.log values it returns me normal array. What I am doing wrong?

Components render method:

render() {

    const {loading, error, messages} = this.props;
    const mes = JSON.stringify(messages);

    console.log(mes); //<------------- returns [{"key":"value"}]
return (
     <div>
       <MessageList
         messages={mes}
       />
   );
 }

MessageList component map function:

  {this.props.messages.map((item, i) => (
            <MessageItem
              key={i}
              message={item.message}
              }

Maybe someone could tell me what I am doing wrong?

PrEto
  • 395
  • 2
  • 7
  • 23
  • 1
    **It's just a typo,** voting to close as such. PrEto - You're passing `mes`, not `messages`, to your `MessageList`. `mes` is a string (the result of `JSON.stringify`). I assume `mes` is for debugging, and you meant to pass `messages` to `MessageList`. `messages` is an array, with a `map` method; `mes` is a string, which doesn't have `map`. *(Oops, I can't vote to close as typo, I mistakenly voted to close as a duplicate having initially misread the question.)* – T.J. Crowder Sep 25 '18 at 08:35
  • Also you shouldn't be using just an integer index for your component key. You should make it unique by adding a prefix/suffix to it. Something like `key={i + 'mi'}`. See https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318. – Adam Sep 25 '18 at 08:36
  • @T.J.Crowder, messages returns List, I want to convert it to an array of JSON's – PrEto Sep 25 '18 at 08:37
  • @PrEto, do not use `json.stringify` as suggested by T.j it will convert it to string and can not be iterated. You should be passing `message={messages}` – Just code Sep 25 '18 at 08:44
  • @PrEto - *"I want to convert it to an array of JSON's"* JSON is a *textual notation* for data exchange. [(More here.)](http://stackoverflow.com/a/2904181/157247) If you're dealing with JavaScript source code, and not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Sep 25 '18 at 08:46

2 Answers2

1

What you can do is

render() {
const {loading, error, messages} = this.props;
return (
      <div>
         <MessageList
           messages={messages}
         />
      </div>
   );
 }

Looks like the messages are from redux state. So initially the messages props will be undefined. So before doing map check whether messages is not undefined using conditional operator like below

  {this.props.messages && this.props.messages.map((item, i) => (
        <MessageItem
          key={i}
          message={item.message}
          />
       ))}
You Nguyen
  • 9,961
  • 4
  • 26
  • 52
Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
  • 1
    Thank you It did the job! One question and I will accept your answer. Can I use redux state in componentDidMount or ComponentWillMount to SetState? – PrEto Sep 25 '18 at 08:58
  • You usually get values from redux state in mapStateToProps in your component and then you pass mapStateToProps to redux connect method. Now you can access those values using for eg this.props.messages in anywhere in the component. – Hemadri Dasari Sep 25 '18 at 09:01
  • @PrEto your question properly is about the moment when the component actually receive the `props` from `redux store`. You could take a look at this: https://stackoverflow.com/questions/39618767/react-redux-why-mapstatetoprops-is-called-before-constructor – You Nguyen Sep 25 '18 at 09:13
  • @Think-Twice, Thank you again. One last question is it normal if I connect to websockets to get 1k saga request per second? When I was doing with with `fetch` it was done only one time? Also I appove your answer! – PrEto Sep 25 '18 at 09:25
  • Sorry I do not have idea about web sockets and redux saga. I never used these libraries. Please don't forget to do upvote as well :) – Hemadri Dasari Sep 25 '18 at 09:27
0

In a comment you've said:

messages returns this: List, not array

JavaScript doesn't have a List type, and it's clear from the result of JSON.stringify that messages is an array, or at least something that JSON.stringify thinks is an array.

I think if you look more carefully, you'll find that messages is an array and you can just use it in your MessageList directly.

If messages really, really doesn't have a map method, you can convert it from whatever it is into an array using Array.from:

mes = Array.from(messages);

...or possibly (depending on what it is) spread notation:

mes = [...messages];

You certainly don't want JSON.stringify, which creates a string.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875