How to merge two array of objects with reactjs?

37,230

Solution 1

Because you are making an HTTP call to your server, it takes some time to fetch the data. Instead of setting events state directly, you should wait for the response of your HTTP call. Your code should be like this:

componentDidMount() {
    fetch("url")
        .then(Response => Response.json())
        .then(data => {
            let evts = data;
            for (let i = 0; i < evts.length; i++) {
                evts[i].start = moment(evts[i].start).toDate();
                evts[i].end = moment(evts[i].end).toDate();
                this.state.evt1.push(evts[i])
            }
            this.setState({
                evt1: evts,
                prevEvents: evts
            })
        })
        .then(() => {

            console.log(this.state.evt1)
            const cachedHits = JSON.parse(localStorage.getItem('Evènements'))
            console.log(cachedHits)
            for (let j = 0; j < cachedHits.length; j++) {
                cachedHits[j].start = moment(cachedHits[j].start).toDate();
                cachedHits[j].end = moment(cachedHits[j].end).toDate();
                this.state.evt2.push(cachedHits[j])
            }
            this.setState({
                evt2: this.state.evt2
            })
            this.setState({
                events: [...this.state.evt1, ...this.state.evt2]
            })
            console.log(this.state.events)

        });
}

I also recommend you to have a catch block in your promise chain to handle errors.

Solution 2

You can use spread operator to merge two array.

var a = [{fname : 'foo'}]
var b = [{lname : 'bar'}]
var c = [...a, ...b] // output is [{fname : 'foo'},{lname : 'bar'}]

Solution 3

Try using the concat method maybe that works.

this.setState({
      events: evt1.concat(evt2)
    })

Solution 4

Add state.evt1 on evts, then iterate through data that you get from fetch, make changes to current element inside for loop, push element to evts and then add that evts to state

        let evts = this.state.evt1;
        for (let i = 0; i < data.length; i++) {
          data[i].start = moment(data[i].start).toDate();
          data[i].end = moment(data[i].end).toDate();
          evts.push(data[i])
        }                   
        this.setState({
          evt1: evts
        })
Share:
37,230

Related videos on Youtube

Ichrak Mansour
Author by

Ichrak Mansour

I am Full stack engineer with more than 4 years of experience and solid experience in Fullstack and Mobile development. I like to build websites and mobile applications that can have a large satisfied user-base, delight and inspire people.

Updated on April 10, 2020

Comments

  • Ichrak Mansour
    Ichrak Mansour about 4 years

    I have a react-big-calendar, I want to fetch the events of this week from the backend and the other weeks from the local storage.

    My code is :

    componentDidMount() {
        fetch("url")
        .then(Response => Response.json())
          .then(data => {
            let evts = data;
            for (let i = 0; i < evts.length; i++) {
              evts[i].start = moment(evts[i].start).toDate();
              evts[i].end = moment(evts[i].end).toDate();
              this.state.evt1.push(evts[i])
            }                   
            this.setState({
              evt1: evts,
              prevEvents : evts
            })
          }) 
          console.log(this.state.evt1)
          const cachedHits = JSON.parse(localStorage.getItem('Evènements')) 
          console.log(cachedHits)
          for (let j = 0; j <cachedHits.length; j++) {
            cachedHits[j].start = moment(cachedHits[j].start).toDate();
            cachedHits[j].end = moment(cachedHits[j].end).toDate();
            this.state.evt2.push(cachedHits[j])
          }
        this.setState( {
          evt2: this.state.evt2
      })
        this.setState({
          events: [...this.state.evt1, ...this.state.evt2]
        })
      console.log(this.state.events)
      }
    

    the events is the merged array of evt1 (events from the backend) and evt2 (events from the localstorage), when I run it, I get on my console :

    The evt1 are :

    enter image description here

    The evt2 are :

    enter image description here

    But, on my calendar, just the evt2 are displayed and not all the events (evt1 and evt2).

    How can display all the events on my calendar ?

  • Ichrak Mansour
    Ichrak Mansour about 5 years
    It is still the same issue, just evt2 are displayed
  • lwolf
    lwolf about 5 years
    @burak-gavas probably is the way to go
  • Vrangle
    Vrangle almost 4 years
    frustrated for while, your answer made me happy!! still confused about the best practice of setting a state, array of objects or object of object :(
  • Niamul
    Niamul over 3 years
    On var b if I just add this var b = [{fname : 'other'}], note I've used the same key. Now, it's just merging with the same key again. So, the output is just like: // [{fname : 'foo'},{fname : 'other'}]. Not sure how to update the value only.