2

I have a form which renders and inserts a component into a timeline, but I can't figure out how to get it to render a new submission chronologically, so that it gets inserted in the correct order.

This is what I've been trying so far.

render() {
  return (
    <div className="timeline-container">
      <ul>
        {this.state.activities
          .sort((a, b) => a.date > b.date)
          .map((activity, i) => (
            <Activity
              key={i}
              data={activity}
              handleDelete={this.handleDelete}
            />
          ))}
      </ul>
    </div>
  );
}

And this is the Activity component:

<li>
  <span></span>
  <div className="activity-title">{this.state.activity.title}</div>
  <div className="activity-info">{this.state.activity.description}</div>
  <div className="activity-location">{this.state.activity.location}</div>
  <div className="activity-date">{this.state.activity.date.slice(0, 10)}</div>
  <button onClick={this.handleDelete.bind(this, this.state.activity.id)}>
    Delete
  </button>
</li>;

At the moment it is still automatically rendering when the form is submitted, but it isn't sorting them.

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
gnado
  • 23
  • 3
  • Can you please show us the contents of `this.state.activities` for helping you further with this question? The data is very important here. You can get in console, the data, using this: `console.log(JSON.stringify(this.state.activities))` and add it in your question. – Praveen Kumar Purushothaman Jul 28 '19 at 17:59
  • The log is: [{"id":27,"trip_id":5,"title":"Activity 1","description":"Description 1","location":"Location 1","date":"2019-07-03T23:00:00.000Z","pending":null,"created_at":"2019-07-28T17:49:40.269Z","updated_at":"2019-07-28T17:49:40.269Z"}] If I console log the state I get an array with all the info I need, I just can't get it to sort. Thanks – gnado Jul 28 '19 at 18:08
  • You have got only one activity in it. How do you want to sort it? Sorting is possible only if there are many activities right? – Praveen Kumar Purushothaman Jul 28 '19 at 18:12
  • Oh, sorry I thought you just wanted to see the key values. There are actually about 15 activities in the array : {"id":31,"trip_id":5,"title":"Activity 5","description":"Description 5","location":"Location 5","date":"2019-07-02T23:00:00.000Z","pending":null,"created_at":"2019-07-28T17:58:51.144Z","updated_at":"2019-07-28T17:58:51.144Z"},{"id":32,"trip_id":5,"title":"Activity 6","description":"Description 6","location":"Location 6","date":"2019-06-30T23:00:00.000Z","pending":null,"created_at":"2019-07-28T17:58:58.912Z","updated_at":"2019-07-28T17:58:58.912Z"}] – gnado Jul 28 '19 at 18:17
  • Don't worry, I managed to solve. The problem was in the date sorting method. And I have fixed it right and gave you the right way to solve it. Have a look at my answer and see if that helps. – Praveen Kumar Purushothaman Jul 28 '19 at 18:18

2 Answers2

2

You should be using new Date(date).getTime() method to compare and sort. A best way to do is:

.sort(
  (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
)

And with my dummy data I get this:

preview

I have added some more entries and here's a full code:

const Activity = props => (
  <li>
    {props.data.title} (#{props.data.id}) ({props.data.date.split("T")[0]})
  </li>
);

class App extends React.Component {
  state = {
    activities: [
      {
        id: 1,
        trip_id: 5,
        title: "Activity 1",
        description: "Description 1",
        location: "Location 1",
        date: "2019-07-03T23:00:00.000Z",
        pending: null,
        created_at: "2019-07-28T17:49:40.269Z",
        updated_at: "2019-07-28T17:49:40.269Z"
      },
      {
        id: 2,
        trip_id: 5,
        title: "Activity 2",
        description: "Description 1",
        location: "Location 1",
        date: "2019-07-05T23:00:00.000Z",
        pending: null,
        created_at: "2019-07-28T17:49:40.269Z",
        updated_at: "2019-07-28T17:49:40.269Z"
      },
      {
        id: 3,
        trip_id: 5,
        title: "Activity 3",
        description: "Description 1",
        location: "Location 1",
        date: "2019-07-02T23:00:00.000Z",
        pending: null,
        created_at: "2019-07-28T17:49:40.269Z",
        updated_at: "2019-07-28T17:49:40.269Z"
      }
    ]
  };
  render() {
    return (
      <div className="timeline-container">
        <ul>
          {this.state.activities
            .sort(
              (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
            )
            .map((activity, i) => (
              <Activity
                key={i}
                data={activity}
                handleDelete={this.handleDelete}
              />
            ))}
        </ul>
      </div>
    );
  }
}

Here in this example, I have used more than one activity to show you how they are sorted by date.

Demo: CodeSandbox

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
0

Hey your date is stored as a string so in comparator function instead of returning a boolean value you should -1, 1, 0 like

// where a and b are strings.
function camp(a, b){
    If (a>b) {
       return 1
}
if ( a<b){
     return -1
}

// in case of equal 
return 0

}
Krishna Kamal
  • 751
  • 2
  • 10
  • 21