Tearz
Tearz

Reputation: 73

How to delete an object in an array of an object in an array?

I'm trying to create a function that deletes an object within a nested array of an object which is within an array...

How would I delete one of the schedules by date?

state = {
children: [
  {
    id: 1,
    firstName: 'Bella',
    lastName: 'Laupama',
    profile: 'child_care',
    schedules: [
      {
        date: '25 December, 2018',
        parent: 'Chris',
        activity: 'Christmas'
      },
      {
        date: '28 December, 2018',
        parent: 'Mischa',
        activity: 'Christmas with Malane Whanau'
      },
      {
        date: '31 December, 2018',
        parent: 'Laura',
        activity: 'New Years Eve'
      },
      {
        date: '1 January, 2019',
        parent: 'Laura',
        activity: 'New Years Day'
      }
    ]
  }
 ]
}

Would something like this work?...

delSched = (firstName, date) => {
  let children = [...this.state.children]
  let findChild = children.find(child => child.firstName == firstName)
  let newState = findChild.filter(sched => sched.date !== date)
  this.setState({
    children: newState
  })
}

UPDATE:

Even though most of these solutions would most probably work, the one I could get working was thank you to @Marius. I used a modified version of his code.

delSched = (firstName, date) => {
    var children = this.state.children

    for (var i = 0; i < children.length; i++) {
      var child = this.state.children[i]

      if (child.firstName == firstName) {
        //Loop through the schedules
        for (var k = 0; k < child.schedules.length; k++) {
          var schedule = child.schedules[k]

          //remove schedule if date == date
          if (schedule.date == date) {
            child.schedules.splice(k, 1)
          }
          this.setState({children})
        }
      }
    }
  }

Upvotes: 0

Views: 65

Answers (5)

xadm
xadm

Reputation: 8418

You probably searched for sth like:

delSched = (firstName, date) => {
  let newChildren = this.state.children.map( child => {
    // don't modify other people
    if( child.firstName != firstName ) return child;

    // new object
    let newChild = {...child}
    // mutate schedule by date
    newChild.schedules = child.schedules.filter(sched => sched.date !== date)
    console.log(newChild);
    return newChild
  })
  this.setState({
    children: newChildren
  }, () => console.log(this.state.children) )
}  

Working code

Upvotes: 0

Marius
Marius

Reputation: 1574

Good ol' for loops. The newer Array prototypes are good, but not supported everywhere. Plus having it in a loop, you can change things if you need.

Working example:

var state = {
  children: [
    {
      id: 1,
      firstName: 'Bella',
      lastName: 'Laupama',
      profile: 'child_care',
      schedules: [
        {
          date: '25 December, 2018',
          parent: 'Chris',
          activity: 'Christmas'
        },
        {
          date: '28 December, 2018',
          parent: 'Mischa',
          activity: 'Christmas with Malane Whanau'
        },
        {
          date: '31 December, 2018',
          parent: 'Laura',
          activity: 'New Years Eve'
        },
        {
          date: '1 January, 2019',
          parent: 'Laura',
          activity: 'New Years Day'
        }
      ]
    }
  ]
}

var children = state.children;

for (var i = 0; i < children.length; i++) {
  var child = state.children[i];

  if (child.firstName == "Bella") {

    //Loop through the schedules
    for (var k = 0; k < child.schedules.length; k++) {
      var schedule = child.schedules[k];

      //remove schedule if date == date
      if (schedule.date == "25 December, 2018") {
        child.schedules.splice(k, 1);
      }

    }

  }
}

console.log(state);

Upvotes: 1

Akrion
Akrion

Reputation: 18515

You can also make it slightly shorter by doing something like this:

let state = { children: [{ id: 1, firstName: 'Bella', lastName: 'Laupama', profile: 'child_care', schedules: [{ date: '25 December, 2018', parent: 'Chris', activity: 'Christmas' }, { date: '28 December, 2018', parent: 'Mischa', activity: 'Christmas with Malane Whanau' }, { date: '31 December, 2018', parent: 'Laura', activity: 'New Years Eve' }, { date: '1 January, 2019', parent: 'Laura', activity: 'New Years Day' } ] }] }

const delSchedule = (arr, name, date) => {
  let f = arr.find(x => x.firstName == name)	
  f.schedules = f ? f.schedules.filter(y => y.date != date) : f.schedules
}

this.setState({
  children: delSchedule(this.state.children, 'Bella', '1 January, 2019')
})

This way delSchedule is not modifying the state but returns the new one which you assign in this.setState etc.

Upvotes: 0

Velimir Tchatchevsky
Velimir Tchatchevsky

Reputation: 2815

It should work, with a small correction:

delSched = (firstName, date) => {
  let children = [...this.state.children]
  let findChild = children.find(child => child.firstName == firstName)
  let newState = findChild;
  newState.schedules = newState.schedules.filter(sched => sched.date !== date)
  this.setState({
    children: newState
  })
}

Your findChild is the object that contains the schedules array, you need to go one level deeper to grab the array and use filter on it

Upvotes: 0

gatsbyz
gatsbyz

Reputation: 1075

Your code fixed:

delSched = (firstName, date) => {
  const children = state.children;
  const findChild = children.find(child => child.firstName === firstName)
  const newSched = findChild.filter(sched => sched.date !== date)
  findChild.schedules = newSched;
}

Upvotes: 1

Related Questions