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
javascript reactjs
add a comment |
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
javascript reactjs
2
it seems the inner map is more of a filter (as you seem to only return it in case it differs from the givenid
) The reason the outer key disappears is because you are returningObject.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 thusupdatedTasks
is anyhow already a complete copy)
– Icepickle
Nov 11 at 23:16
Expected return value ofmap
s is an object, but you are returning an array (the mappedObject.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
add a comment |
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
javascript reactjs
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
javascript reactjs
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 givenid
) The reason the outer key disappears is because you are returningObject.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 thusupdatedTasks
is anyhow already a complete copy)
– Icepickle
Nov 11 at 23:16
Expected return value ofmap
s is an object, but you are returning an array (the mappedObject.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
add a comment |
2
it seems the inner map is more of a filter (as you seem to only return it in case it differs from the givenid
) The reason the outer key disappears is because you are returningObject.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 thusupdatedTasks
is anyhow already a complete copy)
– Icepickle
Nov 11 at 23:16
Expected return value ofmap
s is an object, but you are returning an array (the mappedObject.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
map
s 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
map
s 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
add a comment |
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);
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 suggestObject.entries
instead ofmap
? (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 useObject.entries
in this way so that the core delete/filtering work can be done solely in scope of theObject.entries
callback, rather than this logic relying on context data (ietask
) 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
add a comment |
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);
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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);
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 suggestObject.entries
instead ofmap
? (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 useObject.entries
in this way so that the core delete/filtering work can be done solely in scope of theObject.entries
callback, rather than this logic relying on context data (ietask
) 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
add a comment |
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);
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 suggestObject.entries
instead ofmap
? (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 useObject.entries
in this way so that the core delete/filtering work can be done solely in scope of theObject.entries
callback, rather than this logic relying on context data (ietask
) 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
add a comment |
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);
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);
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 suggestObject.entries
instead ofmap
? (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 useObject.entries
in this way so that the core delete/filtering work can be done solely in scope of theObject.entries
callback, rather than this logic relying on context data (ietask
) 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
add a comment |
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 suggestObject.entries
instead ofmap
? (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 useObject.entries
in this way so that the core delete/filtering work can be done solely in scope of theObject.entries
callback, rather than this logic relying on context data (ietask
) 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
add a comment |
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);
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
add a comment |
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);
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
add a comment |
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);
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);
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 returningObject.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 thusupdatedTasks
is anyhow already a complete copy)– Icepickle
Nov 11 at 23:16
Expected return value of
map
s is an object, but you are returning an array (the mappedObject.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