Deleting object from state removes key of parent object











up vote
2
down vote

favorite












I have this object in state



 tasks: [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
],


and function that deletes object of array by given id



_deleteTask = (id) => {
const tasks = [...this.state.tasks];
const updatedTasks = tasks.map((item) =>
{ return Object.values(item).map((boxForTask) => {
return Object.values(boxForTask).map((eachTaskBox => {
if (eachTaskBox.id !== id) return eachTaskBox

}));
})}
);
this.setState({ tasks: updatedTasks });
}


it deletes the task containing the id, but also deletes the outer key that marks day. I can't seem to find the answer why actions nested deeply affect the outer key










share|improve this question


















  • 2




    it seems the inner map is more of a filter (as you seem to only return it in case it differs from the given id) The reason the outer key disappears is because you are returning Object.values( item ).map, so in essence, you loop over all the properties, and only return the values. I personally don't see the need for spreading the array, since you map over all anyhow (and thus updatedTasks is anyhow already a complete copy)
    – Icepickle
    Nov 11 at 23:16










  • Expected return value of maps is an object, but you are returning an array (the mapped Object.values array).
    – ibrahim mahrir
    Nov 11 at 23:18








  • 1




    If you have full control over your data structure, you may find solving these types of problems becomes much easier logically if you change from dynamic property names {'Day 1': [...]} to static property names {name: 'Day 1', tasks: [...]}
    – Paul S.
    Nov 11 at 23:20












  • By spreading the array ([...this.state.tasks]) you are thinking that you are copying the array. In reality you are shallow copying the array. You need to deep copy the array in order to have exact clone of the array. Otherwise you will copy the reference of the deeper nested objects not the actual value. medium.com/@ziyoshams/…
    – Ziyo
    Nov 12 at 0:33















up vote
2
down vote

favorite












I have this object in state



 tasks: [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
],


and function that deletes object of array by given id



_deleteTask = (id) => {
const tasks = [...this.state.tasks];
const updatedTasks = tasks.map((item) =>
{ return Object.values(item).map((boxForTask) => {
return Object.values(boxForTask).map((eachTaskBox => {
if (eachTaskBox.id !== id) return eachTaskBox

}));
})}
);
this.setState({ tasks: updatedTasks });
}


it deletes the task containing the id, but also deletes the outer key that marks day. I can't seem to find the answer why actions nested deeply affect the outer key










share|improve this question


















  • 2




    it seems the inner map is more of a filter (as you seem to only return it in case it differs from the given id) The reason the outer key disappears is because you are returning Object.values( item ).map, so in essence, you loop over all the properties, and only return the values. I personally don't see the need for spreading the array, since you map over all anyhow (and thus updatedTasks is anyhow already a complete copy)
    – Icepickle
    Nov 11 at 23:16










  • Expected return value of maps is an object, but you are returning an array (the mapped Object.values array).
    – ibrahim mahrir
    Nov 11 at 23:18








  • 1




    If you have full control over your data structure, you may find solving these types of problems becomes much easier logically if you change from dynamic property names {'Day 1': [...]} to static property names {name: 'Day 1', tasks: [...]}
    – Paul S.
    Nov 11 at 23:20












  • By spreading the array ([...this.state.tasks]) you are thinking that you are copying the array. In reality you are shallow copying the array. You need to deep copy the array in order to have exact clone of the array. Otherwise you will copy the reference of the deeper nested objects not the actual value. medium.com/@ziyoshams/…
    – Ziyo
    Nov 12 at 0:33













up vote
2
down vote

favorite









up vote
2
down vote

favorite











I have this object in state



 tasks: [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
],


and function that deletes object of array by given id



_deleteTask = (id) => {
const tasks = [...this.state.tasks];
const updatedTasks = tasks.map((item) =>
{ return Object.values(item).map((boxForTask) => {
return Object.values(boxForTask).map((eachTaskBox => {
if (eachTaskBox.id !== id) return eachTaskBox

}));
})}
);
this.setState({ tasks: updatedTasks });
}


it deletes the task containing the id, but also deletes the outer key that marks day. I can't seem to find the answer why actions nested deeply affect the outer key










share|improve this question













I have this object in state



 tasks: [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
],


and function that deletes object of array by given id



_deleteTask = (id) => {
const tasks = [...this.state.tasks];
const updatedTasks = tasks.map((item) =>
{ return Object.values(item).map((boxForTask) => {
return Object.values(boxForTask).map((eachTaskBox => {
if (eachTaskBox.id !== id) return eachTaskBox

}));
})}
);
this.setState({ tasks: updatedTasks });
}


it deletes the task containing the id, but also deletes the outer key that marks day. I can't seem to find the answer why actions nested deeply affect the outer key







javascript reactjs






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 23:10









justreacting

132




132








  • 2




    it seems the inner map is more of a filter (as you seem to only return it in case it differs from the given id) The reason the outer key disappears is because you are returning Object.values( item ).map, so in essence, you loop over all the properties, and only return the values. I personally don't see the need for spreading the array, since you map over all anyhow (and thus updatedTasks is anyhow already a complete copy)
    – Icepickle
    Nov 11 at 23:16










  • Expected return value of maps is an object, but you are returning an array (the mapped Object.values array).
    – ibrahim mahrir
    Nov 11 at 23:18








  • 1




    If you have full control over your data structure, you may find solving these types of problems becomes much easier logically if you change from dynamic property names {'Day 1': [...]} to static property names {name: 'Day 1', tasks: [...]}
    – Paul S.
    Nov 11 at 23:20












  • By spreading the array ([...this.state.tasks]) you are thinking that you are copying the array. In reality you are shallow copying the array. You need to deep copy the array in order to have exact clone of the array. Otherwise you will copy the reference of the deeper nested objects not the actual value. medium.com/@ziyoshams/…
    – Ziyo
    Nov 12 at 0:33














  • 2




    it seems the inner map is more of a filter (as you seem to only return it in case it differs from the given id) The reason the outer key disappears is because you are returning Object.values( item ).map, so in essence, you loop over all the properties, and only return the values. I personally don't see the need for spreading the array, since you map over all anyhow (and thus updatedTasks is anyhow already a complete copy)
    – Icepickle
    Nov 11 at 23:16










  • Expected return value of maps is an object, but you are returning an array (the mapped Object.values array).
    – ibrahim mahrir
    Nov 11 at 23:18








  • 1




    If you have full control over your data structure, you may find solving these types of problems becomes much easier logically if you change from dynamic property names {'Day 1': [...]} to static property names {name: 'Day 1', tasks: [...]}
    – Paul S.
    Nov 11 at 23:20












  • By spreading the array ([...this.state.tasks]) you are thinking that you are copying the array. In reality you are shallow copying the array. You need to deep copy the array in order to have exact clone of the array. Otherwise you will copy the reference of the deeper nested objects not the actual value. medium.com/@ziyoshams/…
    – Ziyo
    Nov 12 at 0:33








2




2




it seems the inner map is more of a filter (as you seem to only return it in case it differs from the given id) The reason the outer key disappears is because you are returning Object.values( item ).map, so in essence, you loop over all the properties, and only return the values. I personally don't see the need for spreading the array, since you map over all anyhow (and thus updatedTasks is anyhow already a complete copy)
– Icepickle
Nov 11 at 23:16




it seems the inner map is more of a filter (as you seem to only return it in case it differs from the given id) The reason the outer key disappears is because you are returning Object.values( item ).map, so in essence, you loop over all the properties, and only return the values. I personally don't see the need for spreading the array, since you map over all anyhow (and thus updatedTasks is anyhow already a complete copy)
– Icepickle
Nov 11 at 23:16












Expected return value of maps is an object, but you are returning an array (the mapped Object.values array).
– ibrahim mahrir
Nov 11 at 23:18






Expected return value of maps is an object, but you are returning an array (the mapped Object.values array).
– ibrahim mahrir
Nov 11 at 23:18






1




1




If you have full control over your data structure, you may find solving these types of problems becomes much easier logically if you change from dynamic property names {'Day 1': [...]} to static property names {name: 'Day 1', tasks: [...]}
– Paul S.
Nov 11 at 23:20






If you have full control over your data structure, you may find solving these types of problems becomes much easier logically if you change from dynamic property names {'Day 1': [...]} to static property names {name: 'Day 1', tasks: [...]}
– Paul S.
Nov 11 at 23:20














By spreading the array ([...this.state.tasks]) you are thinking that you are copying the array. In reality you are shallow copying the array. You need to deep copy the array in order to have exact clone of the array. Otherwise you will copy the reference of the deeper nested objects not the actual value. medium.com/@ziyoshams/…
– Ziyo
Nov 12 at 0:33




By spreading the array ([...this.state.tasks]) you are thinking that you are copying the array. In reality you are shallow copying the array. You need to deep copy the array in order to have exact clone of the array. Otherwise you will copy the reference of the deeper nested objects not the actual value. medium.com/@ziyoshams/…
– Ziyo
Nov 12 at 0:33












2 Answers
2






active

oldest

votes

















up vote
1
down vote



accepted










Perhaps something like the following would work for you? This approach achieves the delete/filtering behaviour based on Array#reduce(), Array#map() and Object#entries():






var state = { tasks : [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
}
]
};


const _deleteTask = (id) => {

const tasks = state.tasks.map(task => {

return Object.entries(task).reduce((t, entry) => {

const dayKey = entry[0];
const dayArray = entry[1].filter(dayItem => dayItem.id !== id);

t[ dayKey ] = dayArray;

return t;

}, {});
});

state.tasks = tasks;
// this.setState({ tasks: updatedTasks });
};

console.log('Before', state);
_deleteTask(12235);
console.log('After', state);








share|improve this answer























  • I know ; is optional, but it bugs me every time when I don't see them :)
    – Icepickle
    Nov 11 at 23:34










  • Fair enough! ; added - let me know if I've missed any :-)
    – Dacre Denny
    Nov 11 at 23:36










  • Well you obviously didn't miss any before, it is just my personal view :) Any reason why you suggest Object.entries instead of map? (since you ask, the const declaration of _deleteTask is missing a ;) :D
    – Icepickle
    Nov 11 at 23:40












  • Thanks - if performance isn't a big issue, I'll tend to use Object.entries in this way so that the core delete/filtering work can be done solely in scope of the Object.entries callback, rather than this logic relying on context data (ie task) that's "passed in" via surrounding closure.
    – Dacre Denny
    Nov 11 at 23:45






  • 1




    cool :) it saves an extra lookup for the property
    – Icepickle
    Nov 11 at 23:48


















up vote
0
down vote













Your code as it is, isn't doing what you are expecting it to do, or it does to much (eg, the unneccessary copy of the state.tasks into updatedTasks). This copy is not necessary, because map will already produce a new array for you, so in a sense you are copying it twice.



You are removing the outer property when you are returning



return Object.values(item).map((boxForTask) => { /*...*/ } );


as this will go only into the values of each of these properties, you don't have a clue what your properties might be afterwards.



Another interesting piece of code would be the inner map, where you should probably use filter (otherwise, you would have some undefined in the resulting output). A filter would just return the matching items, whereas map would return all items



To update your current code, you could simply do it in the following way



function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => {
return Object.keys(task).map(key => {
return {
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
};
});
});
}


The result will be a copy of the tasks array, with a matching outer property and the tasks that should be removed will be deleted. It will not mutate the original input, so that would fit your needs in react as well (for this reason, I also print the original array after the filtered one in the below snippet)






const tasks = [{
'Day 1': [{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
];

function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => Object.keys(task).map(key => ({
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
})
)
);
}

console.log(copyOfTasksWithoutId(tasks, 12234));
console.log(tasks);








share|improve this answer



















  • 1




    Thank you! This explanation is exactly what I needed, now the mess in my head is getting clearer
    – justreacting
    Nov 11 at 23:43











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254175%2fdeleting-object-from-state-removes-key-of-parent-object%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote



accepted










Perhaps something like the following would work for you? This approach achieves the delete/filtering behaviour based on Array#reduce(), Array#map() and Object#entries():






var state = { tasks : [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
}
]
};


const _deleteTask = (id) => {

const tasks = state.tasks.map(task => {

return Object.entries(task).reduce((t, entry) => {

const dayKey = entry[0];
const dayArray = entry[1].filter(dayItem => dayItem.id !== id);

t[ dayKey ] = dayArray;

return t;

}, {});
});

state.tasks = tasks;
// this.setState({ tasks: updatedTasks });
};

console.log('Before', state);
_deleteTask(12235);
console.log('After', state);








share|improve this answer























  • I know ; is optional, but it bugs me every time when I don't see them :)
    – Icepickle
    Nov 11 at 23:34










  • Fair enough! ; added - let me know if I've missed any :-)
    – Dacre Denny
    Nov 11 at 23:36










  • Well you obviously didn't miss any before, it is just my personal view :) Any reason why you suggest Object.entries instead of map? (since you ask, the const declaration of _deleteTask is missing a ;) :D
    – Icepickle
    Nov 11 at 23:40












  • Thanks - if performance isn't a big issue, I'll tend to use Object.entries in this way so that the core delete/filtering work can be done solely in scope of the Object.entries callback, rather than this logic relying on context data (ie task) that's "passed in" via surrounding closure.
    – Dacre Denny
    Nov 11 at 23:45






  • 1




    cool :) it saves an extra lookup for the property
    – Icepickle
    Nov 11 at 23:48















up vote
1
down vote



accepted










Perhaps something like the following would work for you? This approach achieves the delete/filtering behaviour based on Array#reduce(), Array#map() and Object#entries():






var state = { tasks : [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
}
]
};


const _deleteTask = (id) => {

const tasks = state.tasks.map(task => {

return Object.entries(task).reduce((t, entry) => {

const dayKey = entry[0];
const dayArray = entry[1].filter(dayItem => dayItem.id !== id);

t[ dayKey ] = dayArray;

return t;

}, {});
});

state.tasks = tasks;
// this.setState({ tasks: updatedTasks });
};

console.log('Before', state);
_deleteTask(12235);
console.log('After', state);








share|improve this answer























  • I know ; is optional, but it bugs me every time when I don't see them :)
    – Icepickle
    Nov 11 at 23:34










  • Fair enough! ; added - let me know if I've missed any :-)
    – Dacre Denny
    Nov 11 at 23:36










  • Well you obviously didn't miss any before, it is just my personal view :) Any reason why you suggest Object.entries instead of map? (since you ask, the const declaration of _deleteTask is missing a ;) :D
    – Icepickle
    Nov 11 at 23:40












  • Thanks - if performance isn't a big issue, I'll tend to use Object.entries in this way so that the core delete/filtering work can be done solely in scope of the Object.entries callback, rather than this logic relying on context data (ie task) that's "passed in" via surrounding closure.
    – Dacre Denny
    Nov 11 at 23:45






  • 1




    cool :) it saves an extra lookup for the property
    – Icepickle
    Nov 11 at 23:48













up vote
1
down vote



accepted







up vote
1
down vote



accepted






Perhaps something like the following would work for you? This approach achieves the delete/filtering behaviour based on Array#reduce(), Array#map() and Object#entries():






var state = { tasks : [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
}
]
};


const _deleteTask = (id) => {

const tasks = state.tasks.map(task => {

return Object.entries(task).reduce((t, entry) => {

const dayKey = entry[0];
const dayArray = entry[1].filter(dayItem => dayItem.id !== id);

t[ dayKey ] = dayArray;

return t;

}, {});
});

state.tasks = tasks;
// this.setState({ tasks: updatedTasks });
};

console.log('Before', state);
_deleteTask(12235);
console.log('After', state);








share|improve this answer














Perhaps something like the following would work for you? This approach achieves the delete/filtering behaviour based on Array#reduce(), Array#map() and Object#entries():






var state = { tasks : [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
}
]
};


const _deleteTask = (id) => {

const tasks = state.tasks.map(task => {

return Object.entries(task).reduce((t, entry) => {

const dayKey = entry[0];
const dayArray = entry[1].filter(dayItem => dayItem.id !== id);

t[ dayKey ] = dayArray;

return t;

}, {});
});

state.tasks = tasks;
// this.setState({ tasks: updatedTasks });
};

console.log('Before', state);
_deleteTask(12235);
console.log('After', state);








var state = { tasks : [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
}
]
};


const _deleteTask = (id) => {

const tasks = state.tasks.map(task => {

return Object.entries(task).reduce((t, entry) => {

const dayKey = entry[0];
const dayArray = entry[1].filter(dayItem => dayItem.id !== id);

t[ dayKey ] = dayArray;

return t;

}, {});
});

state.tasks = tasks;
// this.setState({ tasks: updatedTasks });
};

console.log('Before', state);
_deleteTask(12235);
console.log('After', state);





var state = { tasks : [
{
'Day 1': [
{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [
{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
}
]
};


const _deleteTask = (id) => {

const tasks = state.tasks.map(task => {

return Object.entries(task).reduce((t, entry) => {

const dayKey = entry[0];
const dayArray = entry[1].filter(dayItem => dayItem.id !== id);

t[ dayKey ] = dayArray;

return t;

}, {});
});

state.tasks = tasks;
// this.setState({ tasks: updatedTasks });
};

console.log('Before', state);
_deleteTask(12235);
console.log('After', state);






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 11 at 23:42

























answered Nov 11 at 23:30









Dacre Denny

9,5834929




9,5834929












  • I know ; is optional, but it bugs me every time when I don't see them :)
    – Icepickle
    Nov 11 at 23:34










  • Fair enough! ; added - let me know if I've missed any :-)
    – Dacre Denny
    Nov 11 at 23:36










  • Well you obviously didn't miss any before, it is just my personal view :) Any reason why you suggest Object.entries instead of map? (since you ask, the const declaration of _deleteTask is missing a ;) :D
    – Icepickle
    Nov 11 at 23:40












  • Thanks - if performance isn't a big issue, I'll tend to use Object.entries in this way so that the core delete/filtering work can be done solely in scope of the Object.entries callback, rather than this logic relying on context data (ie task) that's "passed in" via surrounding closure.
    – Dacre Denny
    Nov 11 at 23:45






  • 1




    cool :) it saves an extra lookup for the property
    – Icepickle
    Nov 11 at 23:48


















  • I know ; is optional, but it bugs me every time when I don't see them :)
    – Icepickle
    Nov 11 at 23:34










  • Fair enough! ; added - let me know if I've missed any :-)
    – Dacre Denny
    Nov 11 at 23:36










  • Well you obviously didn't miss any before, it is just my personal view :) Any reason why you suggest Object.entries instead of map? (since you ask, the const declaration of _deleteTask is missing a ;) :D
    – Icepickle
    Nov 11 at 23:40












  • Thanks - if performance isn't a big issue, I'll tend to use Object.entries in this way so that the core delete/filtering work can be done solely in scope of the Object.entries callback, rather than this logic relying on context data (ie task) that's "passed in" via surrounding closure.
    – Dacre Denny
    Nov 11 at 23:45






  • 1




    cool :) it saves an extra lookup for the property
    – Icepickle
    Nov 11 at 23:48
















I know ; is optional, but it bugs me every time when I don't see them :)
– Icepickle
Nov 11 at 23:34




I know ; is optional, but it bugs me every time when I don't see them :)
– Icepickle
Nov 11 at 23:34












Fair enough! ; added - let me know if I've missed any :-)
– Dacre Denny
Nov 11 at 23:36




Fair enough! ; added - let me know if I've missed any :-)
– Dacre Denny
Nov 11 at 23:36












Well you obviously didn't miss any before, it is just my personal view :) Any reason why you suggest Object.entries instead of map? (since you ask, the const declaration of _deleteTask is missing a ;) :D
– Icepickle
Nov 11 at 23:40






Well you obviously didn't miss any before, it is just my personal view :) Any reason why you suggest Object.entries instead of map? (since you ask, the const declaration of _deleteTask is missing a ;) :D
– Icepickle
Nov 11 at 23:40














Thanks - if performance isn't a big issue, I'll tend to use Object.entries in this way so that the core delete/filtering work can be done solely in scope of the Object.entries callback, rather than this logic relying on context data (ie task) that's "passed in" via surrounding closure.
– Dacre Denny
Nov 11 at 23:45




Thanks - if performance isn't a big issue, I'll tend to use Object.entries in this way so that the core delete/filtering work can be done solely in scope of the Object.entries callback, rather than this logic relying on context data (ie task) that's "passed in" via surrounding closure.
– Dacre Denny
Nov 11 at 23:45




1




1




cool :) it saves an extra lookup for the property
– Icepickle
Nov 11 at 23:48




cool :) it saves an extra lookup for the property
– Icepickle
Nov 11 at 23:48












up vote
0
down vote













Your code as it is, isn't doing what you are expecting it to do, or it does to much (eg, the unneccessary copy of the state.tasks into updatedTasks). This copy is not necessary, because map will already produce a new array for you, so in a sense you are copying it twice.



You are removing the outer property when you are returning



return Object.values(item).map((boxForTask) => { /*...*/ } );


as this will go only into the values of each of these properties, you don't have a clue what your properties might be afterwards.



Another interesting piece of code would be the inner map, where you should probably use filter (otherwise, you would have some undefined in the resulting output). A filter would just return the matching items, whereas map would return all items



To update your current code, you could simply do it in the following way



function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => {
return Object.keys(task).map(key => {
return {
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
};
});
});
}


The result will be a copy of the tasks array, with a matching outer property and the tasks that should be removed will be deleted. It will not mutate the original input, so that would fit your needs in react as well (for this reason, I also print the original array after the filtered one in the below snippet)






const tasks = [{
'Day 1': [{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
];

function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => Object.keys(task).map(key => ({
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
})
)
);
}

console.log(copyOfTasksWithoutId(tasks, 12234));
console.log(tasks);








share|improve this answer



















  • 1




    Thank you! This explanation is exactly what I needed, now the mess in my head is getting clearer
    – justreacting
    Nov 11 at 23:43















up vote
0
down vote













Your code as it is, isn't doing what you are expecting it to do, or it does to much (eg, the unneccessary copy of the state.tasks into updatedTasks). This copy is not necessary, because map will already produce a new array for you, so in a sense you are copying it twice.



You are removing the outer property when you are returning



return Object.values(item).map((boxForTask) => { /*...*/ } );


as this will go only into the values of each of these properties, you don't have a clue what your properties might be afterwards.



Another interesting piece of code would be the inner map, where you should probably use filter (otherwise, you would have some undefined in the resulting output). A filter would just return the matching items, whereas map would return all items



To update your current code, you could simply do it in the following way



function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => {
return Object.keys(task).map(key => {
return {
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
};
});
});
}


The result will be a copy of the tasks array, with a matching outer property and the tasks that should be removed will be deleted. It will not mutate the original input, so that would fit your needs in react as well (for this reason, I also print the original array after the filtered one in the below snippet)






const tasks = [{
'Day 1': [{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
];

function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => Object.keys(task).map(key => ({
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
})
)
);
}

console.log(copyOfTasksWithoutId(tasks, 12234));
console.log(tasks);








share|improve this answer



















  • 1




    Thank you! This explanation is exactly what I needed, now the mess in my head is getting clearer
    – justreacting
    Nov 11 at 23:43













up vote
0
down vote










up vote
0
down vote









Your code as it is, isn't doing what you are expecting it to do, or it does to much (eg, the unneccessary copy of the state.tasks into updatedTasks). This copy is not necessary, because map will already produce a new array for you, so in a sense you are copying it twice.



You are removing the outer property when you are returning



return Object.values(item).map((boxForTask) => { /*...*/ } );


as this will go only into the values of each of these properties, you don't have a clue what your properties might be afterwards.



Another interesting piece of code would be the inner map, where you should probably use filter (otherwise, you would have some undefined in the resulting output). A filter would just return the matching items, whereas map would return all items



To update your current code, you could simply do it in the following way



function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => {
return Object.keys(task).map(key => {
return {
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
};
});
});
}


The result will be a copy of the tasks array, with a matching outer property and the tasks that should be removed will be deleted. It will not mutate the original input, so that would fit your needs in react as well (for this reason, I also print the original array after the filtered one in the below snippet)






const tasks = [{
'Day 1': [{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
];

function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => Object.keys(task).map(key => ({
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
})
)
);
}

console.log(copyOfTasksWithoutId(tasks, 12234));
console.log(tasks);








share|improve this answer














Your code as it is, isn't doing what you are expecting it to do, or it does to much (eg, the unneccessary copy of the state.tasks into updatedTasks). This copy is not necessary, because map will already produce a new array for you, so in a sense you are copying it twice.



You are removing the outer property when you are returning



return Object.values(item).map((boxForTask) => { /*...*/ } );


as this will go only into the values of each of these properties, you don't have a clue what your properties might be afterwards.



Another interesting piece of code would be the inner map, where you should probably use filter (otherwise, you would have some undefined in the resulting output). A filter would just return the matching items, whereas map would return all items



To update your current code, you could simply do it in the following way



function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => {
return Object.keys(task).map(key => {
return {
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
};
});
});
}


The result will be a copy of the tasks array, with a matching outer property and the tasks that should be removed will be deleted. It will not mutate the original input, so that would fit your needs in react as well (for this reason, I also print the original array after the filtered one in the below snippet)






const tasks = [{
'Day 1': [{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
];

function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => Object.keys(task).map(key => ({
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
})
)
);
}

console.log(copyOfTasksWithoutId(tasks, 12234));
console.log(tasks);








const tasks = [{
'Day 1': [{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
];

function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => Object.keys(task).map(key => ({
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
})
)
);
}

console.log(copyOfTasksWithoutId(tasks, 12234));
console.log(tasks);





const tasks = [{
'Day 1': [{
id: 1234,
task: 'Task 1',
created: 'somedate'
},
{
id: 1235,
task: 'Task 2',
created: 'somedate'
},
{
id: 1225,
task: 'Task 3',
created: 'somedate'
}
],
},
{
'Day 2': [{
id: 12234,
task: 'Task 4',
created: 'somedate'
},
{
id: 12235,
task: 'Task 5',
created: 'somedate'
},
],
},
];

function copyOfTasksWithoutId(tasks, id) {
return tasks.map(task => Object.keys(task).map(key => ({
[key]: task[key]
.filter(taskWithId => taskWithId.id !== id)
})
)
);
}

console.log(copyOfTasksWithoutId(tasks, 12234));
console.log(tasks);






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 11 at 23:43

























answered Nov 11 at 23:29









Icepickle

8,59032035




8,59032035








  • 1




    Thank you! This explanation is exactly what I needed, now the mess in my head is getting clearer
    – justreacting
    Nov 11 at 23:43














  • 1




    Thank you! This explanation is exactly what I needed, now the mess in my head is getting clearer
    – justreacting
    Nov 11 at 23:43








1




1




Thank you! This explanation is exactly what I needed, now the mess in my head is getting clearer
– justreacting
Nov 11 at 23:43




Thank you! This explanation is exactly what I needed, now the mess in my head is getting clearer
– justreacting
Nov 11 at 23:43


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254175%2fdeleting-object-from-state-removes-key-of-parent-object%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Florida Star v. B. J. F.

Error while running script in elastic search , gateway timeout

Adding quotations to stringified JSON object values