Reputation: 1223
Basically I have a table with rows of items. These rows have 4 cells with text in. You can delete cells/text from the rows from right -> left. So "1 2 3 4" can be "1 2 3 -" for example, if you delete cells/text from right -> left.
Here's my reducer code in which I'll have to delete the entire row as well, as the "1" in the above example is deleted as well. It's just so that I don't want a row visible with "- - - -" for example, it can just delete the entire row by that point. So here's my code:
case DELETE_SITE: {
return {
...state,
siteRows: state.siteRows.map((s) => {
if (s.siteLevel2Id && s.siteLevel2Id == action.payload.id)
//return {...s, siteLevel2Id: null, siteLevel2Name: null, canDeleteLevel2: null};
return state.siteRows.slice(0, 1);
if (s.siteLevel3Id && s.siteLevel3Id == action.payload.id)
return {...s, siteLevel3Id: null, siteLevel3Name: null, canDeleteLevel3: null};
if (s.siteLevel4Id && s.siteLevel4Id == action.payload.id)
return {...s, siteLevel4Id: null, siteLevel4Name: null, canDeleteLevel4: null};
if (s.siteLevel5Id && s.siteLevel5Id == action.payload.id)
return {...s, siteLevel5Id: null, siteLevel5Name: null, canDeleteLevel5: null};
return s;
}),
}
}
As you can see, as long as 3, 2 are deleted, 1 will still be filled in and it will look like this "1 - - -". Now if we delete the "1" as well, here named "siteLevel2...", it would show "- - - -" but I just want to remove the entire row from "state.siteRows".
I've tried the line that's in comment right now, but it just adds a "null" value to the array that is "siteRows", like this: {null, [siteRow1]} so it crashes in my screen because it's trying to do things like "null.id".
I've tried on the second line splicing the first element from the array (removing it) but it doesn't seem to work either.
Can anyone help me with this please?
Upvotes: 1
Views: 157
Reputation: 39280
You can try the following:
const DELETE_SITE = 'DELETE_SITE';
const testReducer = (state, action) => {
switch (action.type) {
case DELETE_SITE: {
const keys = [
['siteLevel2Id', 2],
['siteLevel3Id', 3],
['siteLevel4Id', 4],
['siteLevel5Id', 5],
];
const reset = (num, item) => ({
...item,
[`siteLevel${num}Id`]: null,
[`siteLevel${num}Name`]: null,
[`canDeleteLevel${num}`]: null,
});
const recurCheck = (id) => (row) => {
const recur = (index) => {
const [currentKey, num] = keys[index];
//nothing to do, no match
if (index >= keys.length - 1) {
return row;
}
//row siteLevelNId matches id, reset this row
if (row[currentKey] && row[currentKey] == id) {
return reset(num, row);
}
//recur try the next index
return recur(index + 1);
};
return recur(0);
};
return {
...state,
siteRows: state.siteRows
.map(recurCheck(action.payload?.id))
//if any of these keys return true
// do not remove this row
.filter((row) => keys.some(([key]) => row[key])),
};
}
default: {
return state;
}
}
};
console.log(
'no rows',
testReducer(
{ siteRows: [] },
{ type: DELETE_SITE, payload: { id: 1 } }
).siteRows
);
const createItem = (num) => ({
[`siteLevel${num}Id`]: num,
[`siteLevel${num}Name`]: num,
[`canDeleteLevel${num}`]: num,
});
console.log(
'id 3',
testReducer(
{ siteRows: [createItem(3)] },
{ type: DELETE_SITE, payload: { id: 3 } }
).siteRows
);
console.log(
'id 2',
testReducer(
{ siteRows: [{ ...createItem(2), siteLevel3Id: 3 }] },
{ type: DELETE_SITE, payload: { id: 2 } }
).siteRows
);
I tried to clean up repeating logic but you could leave it as is, the thing that solves your problem is the filter function after the map function.
Upvotes: 1