Reputation: 73
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
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) )
}
Upvotes: 0
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
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
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
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