0

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})
        }
      }
    }
  }
1
  • Why are people downvoting? Please state a reason in comments. Commented Nov 21, 2018 at 20:48

5 Answers 5

1

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);
Sign up to request clarification or add additional context in comments.

1 Comment

YES! thank you so much @Marius, this worked perfectly with slight modifications... I will edit my original post to show the modification.
1

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;
}

4 Comments

Thank you for the reply Gatsby, how would I return this to state? - The 5th line sort of confuses me on what to do?
@Tearz When you change a reference to an object, it will also change the actual object. findChild.schedules = newSched; will change state.children[0 or whatever].schedules
it seems to crash when I try and use this? - would you mind maybe having a look for me if I gave you the repo?
@Tearz Yes. I will.
0

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

2 Comments

Thanks Velimir, but I think this seems to delete the schedules as a whole? After I do this, it crashes the schedules.map within a parent component.
state does not equal findChild.schedules. It should not be placing it there.
0

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.

3 Comments

Thank you @Akrion for your response, however, I'm really struggling to find a way to make this work as I'm not sure how to make this work without it being just one single function?
Not sure I understand ... you want to change the state inside delSchedule?
Kind of yeah, I'm setting the state from within the function, much like this... 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 }) }
0

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

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.