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