I have an app that has a list that when an item is clicked, populates another list with data that is in a sub-category of the selected list item. When a list item is clicked in the parent list, an API call goes and retrieves data to populate the child list. Multiple items result in multiple API calls.
When multiple items in the parent list are clicked, I need to add multiple children from each respective parent to the child list. I am trying to limit the number of dependencies in my app and therefore I am using as much ES6+ as possible.
I am using the spread operator to make multiple shallow copies of my nested state. The state slice I am struggling with looks like this:
{
tables: {
tablesLoading: false,
error: null,
selectedTables: [],
tables: {
byId: {
'9311fe20-dea9-11e9-ba2f-4fe2a4bdbda0': {
id: '9311fe20-dea9-11e9-ba2f-4fe2a4bdbda0',
value: 'Sample_1a',
fields: []
},
'9311fe21-dea9-11e9-ba2f-4fe2a4bdbda0': {
id: '9311fe21-dea9-11e9-ba2f-4fe2a4bdbda0',
value: 'Sample_1b',
fields: []
},
'93ea35b0-dea9-11e9-ba2f-4fe2a4bdbda0': {
id: '93ea35b0-dea9-11e9-ba2f-4fe2a4bdbda0',
value: 'Sample_2a',
fields: []
}
},
allIds: [
'9311fe20-dea9-11e9-ba2f-4fe2a4bdbda0',
'9311fe21-dea9-11e9-ba2f-4fe2a4bdbda0',
'93ea35b0-dea9-11e9-ba2f-4fe2a4bdbda0'
]
}
}
}
The initial API call pulls the data corresponding to the first two ID's ( '9311fe20-dea9-11e9-ba2f-4fe2a4bdbda0' and '9311fe21-dea9-11e9-ba2f-4fe2a4bdbda0') from a server. I then click another item in the parent list and want to add the third item to the tables.byId object and then add the corresponding ID to the tables.allIds array. My code for that is:
const tableRequestSuccess = (state, action) => {
const tableVals = action.tableVals;
const datasetName = action.datasetName;
const tableUUIDs = tableVals[datasetName].map(val=>(uuidv1()));
let addedtablesById = {};
for (let i = 0; i<tableUUIDs.length; i++){
let tableId = tableUUIDs[i];
addedtablesById[tableId]={
id: tableId,
value: tableVals[datasetName][i],
fields: []
}
}
**const updatedTablesById = updateObject(state.tables.byId, addedtablesById)**
const updatetableAllIds = [...state.tables.allIds, ...tableUUIDs]
const updatedProperties = {
byId: updatedTablesById,
allIds: updatetableAllIds
};
return updateObject(state, {
tablesLoading: false,
error: null,
tables: updateObject(state.tables, updatedProperties)
});
}
My problem is that I am not sure how to do a copy on the part of my state tree where the individual objects are stored, i.e. state.tables.byId.THE_RESPECTIVE_IDS. This leaves me with the inner most objects having a reference to the original objects and therefore the state won't be updated immutably. But because the ID's will vary and the number will constantly change, I am not sure how to copy those last objects. I suspect all the state up to that point has been cloned over.
I have created a helper function for readability:
export const updateObject = (oldObject, updatedProperties) => {
return {
...oldObject,
...updatedProperties
}
}
Any pointers on how to get this done using the spread operator?