0

There is array of objects

this.props.comments = [{
id: "b149b076-93b1-4ac7-b913-65a7b1ee9a5b", 
addedBy: "user1", 
addedById: "3dc8e8a0-dc40-42da-ae53-f10b01a0b197", 
addedDate: "2018-10-08T10:47:46.829258", 
content: "test1"
}, {
id: "ee997e10-919c-42cc-8efb-7ea49cf5c197", 
addedBy: "user22", 
addedById: "1781e165-82f4-4a49-884c-ba66031ad0da", 
addedDate: "2018-10-08T10:41:59.264111", 
content: "test2"}]

I am trying to filter and output comments using reduce

const comments = this.props.comments.reduce((result, cm, index) => {
            if(cm.addedById === "3dc8e8a0-dc40-42da-ae53-f10b01a0b197") {
                result += <li key={index} className="task-comments__comment">
                    <p className="task-comments__comment-header">
                        <span className="task-comments__comment-author">{ cm.addedBy }</span>
                        <span
                            className="task-comments__comment-date">
                            {moment(cm.addedDate).format('DD.MM.YYYY HH:MM')}
                        </span>
                    </p>
                    <p className="task-comments__comment-text">
                        { cm.content }
                    </p>
                </li>;
            }
            return result;
        }, {});

but as result I get
enter image description here

What's wrong and how to fix it?

2
  • 1
    Why don't you use filter? seems like you want to filter Commented Oct 9, 2018 at 7:07
  • Also, how can you do result += <li key={index} ...? you are adding something which is not a string Commented Oct 9, 2018 at 7:08

2 Answers 2

1

You are concatenating objects.

Instead, result should be an array.

const comments = this.props.comments.reduce((result, cm, index) => {
        if(cm.addedById === "3dc8e8a0-dc40-42da-ae53-f10b01a0b197") {
            result.push(<li key={index} className="task-comments__comment">
                <p className="task-comments__comment-header">
                    <span className="task-comments__comment-author">{ cm.addedBy }</span>
                    <span
                        className="task-comments__comment-date">
                        {moment(cm.addedDate).format('DD.MM.YYYY HH:MM')}
                    </span>
                </p>
                <p className="task-comments__comment-text">
                    { cm.content }
                </p>
            </li>);
        }
        return result;
    }, []);
Sign up to request clarification or add additional context in comments.

6 Comments

@Heidel If result should be an array then don't use reduce, use map
@slebetman why? I need not only map, I also need to filter the array
@Heidel P.s. using filter instead of reduce is more than reasonable here. My goal was just to locate an issue in the current code.
@Heidel P.s.s. check out functions for arrays and objects here lodash.com/docs/4.17.10 Some of them are available in pure javascript devdocs.io/javascript/global_objects/array
@Heidel jsfiddle.net/hvztgusp/1 at first you filter comments and then you map them into react components.
|
1

Since you did not describe what exactly is it that you want, I've made some guesses:

First lets use map to create a new modified Array and last lets use filter to filter out empty array items, since the map will create those (because of the if statement)

Last, I would advise to separate the HTML from the logic:

const comments = this.props.comments.map((item, index) => {
    if(item.addedById === "3dc8e8a0-dc40-42da-ae53-f10b01a0b197")
        return createListItem(item, index);
}).filter(Boolean);

function createListItem(item, index){
  return <li key={index} className="task-comments__comment">
      <p className="task-comments__comment-header">
          <span className="task-comments__comment-author">{ item.addedBy }</span>
          <span className="task-comments__comment-date">
              {moment(item.addedDate).format('DD.MM.YYYY HH:MM')}
          </span>
      </p>
      <p className="task-comments__comment-text">{ item.content }</p>
  </li>
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.