I'm trying to remove an item from a childArray
that is nested into another Array.
This is How I'm trying.
const childArrayHandler = (childData, sub, questionId, data, btnId) => {
// Manage color change on click
const isInList = selectedBtnList.some((item) => item === btnId)
if (isInList) {
onSelectedBtnListChange(selectedBtnList.filter((item) => item !== btnId))
} else {
onSelectedBtnListChange([...selectedBtnList, btnId])
}
// Manage childData Array
// copy data to mutable object
const currentChildData = [...childData]
const hasId = currentChildData.find(({ id }) => sub.id === id)
if (!hasId) {
// add item to childArray if same index is not available in the childArray
const newChild = { id: sub.id, sub_question: sub.sub_question, weightage: sub.weightage }
currentChildData.push(newChild)
setChildDataOnChange((current) => [...current, newChild])
} else if (hasId) {
// remove item from childArray if same index is available in the childArray
const indexOfChild = currentChildData.indexOf(hasId)
// console.log('currentChildData', currentChildData, 'indexOfChild', indexOfChild)
currentChildData.slice(indexOfChild, 1)
setChildDataOnChange(currentChildData)
}
const newData = [...data]
// find parent of the child
const parent = newData.find(({ parentId }) => questionId === parentId)
// find index of parent
const indexOfParent = newData.indexOf(parent)
// update data with child related to parent
newData[indexOfParent].child = currentChildData
onDataChange(newData)
localStorage.setItem('deviceReport', JSON.stringify(newData))
}
The problem is in the else if
block, I want if there's an index of object available in the child then it should remove it from the array. As far as I can see I'm using the correct approach as other articles suggested to handle but missing something which I cant see right now. But not able to find the proper result. If I console it doesn't change anything. means don't remove any item from the array if the index is already is there.
So how can I fix this, or what might be doing wrong, is there any other way to do it please also mention it? Thanks
CodePudding user response:
You have the problem with this slice
currentChildData.slice(indexOfChild, 1)
It does not initialize a new array for you (React's immutability)
The fix could be
currentChildData = currentChildData.slice(0, indexOfChild).concat(currentChildData.slice(indexOfChild 1))
If you feel it's too complicating, you can use filter
instead
currentChildData = currentChildData.filter((item) => item !== hasId) //`hasId` is your found item with `find`
The 2nd problem here is
newData[indexOfParent].child = currentChildData
You cannot assign a value to a mutate object
The proper way should be
newData = newData.map((item) => item === parent ? {...item, child: currentChildData} : item)
The full code
const childArrayHandler = (childData, sub, questionId, data, btnId) => {
// Manage color change on click
const isInList = selectedBtnList.some((item) => item === btnId)
if (isInList) {
onSelectedBtnListChange(selectedBtnList.filter((item) => item !== btnId))
} else {
onSelectedBtnListChange([...selectedBtnList, btnId])
}
// Manage childData Array
// copy data to mutable object
let currentChildData = [...childData]
const hasId = currentChildData.find(({ id }) => sub.id === id)
if (!hasId) {
// add item to childArray if same index is not available in the childArray
const newChild = { id: sub.id, sub_question: sub.sub_question, weightage: sub.weightage }
currentChildData.push(newChild)
setChildDataOnChange((current) => [...current, newChild])
} else {
// console.log('currentChildData', currentChildData, 'indexOfChild', indexOfChild)
currentChildData = currentChildData.filter((item) => item !== hasId)
setChildDataOnChange(currentChildData)
}
//let newData = [...data]
// find parent of the child
//const parent = newData.find(({ parentId }) => questionId === parentId)
// update data with child related to parent
//newData = newData.map((item) => item === parent ? {...item, child: currentChildData} : item)
//shorter version
const newData = data.map((item) => item.parentId === questionId ? {...item, child: currentChildData} : item)
onDataChange(newData)
localStorage.setItem('deviceReport', JSON.stringify(newData))
}