frontend: updating list through reducer is now supported

This commit is contained in:
Mose Müller 2023-08-02 12:06:20 +02:00
parent cc0397b23e
commit ce1442b354

View File

@ -1,9 +1,7 @@
import { useEffect, useReducer } from 'react'; import { useEffect, useReducer } from 'react';
import { socket } from './socket'; import { socket } from './socket';
import { import { DataServiceComponent } from './components/DataServiceComponent';
DataServiceComponent, import { DataServiceJSON } from './components/GenericComponent';
DataServiceJSON
} from './components/DataServiceComponent';
type ValueType = boolean | string | number | object; type ValueType = boolean | string | number | object;
@ -19,6 +17,16 @@ type NotificationElement = {
* A function to update a specific property in a deeply nested object. * A function to update a specific property in a deeply nested object.
* The property to be updated is specified by a path array. * The property to be updated is specified by a path array.
* *
* Each path element can be a regular object key or an array index of the
* form "attribute[index]", where "attribute" is the key of the array in
* the object and "index" is the index of the element in the array.
*
* For array indices, the element at the specified index in the array is
* updated.
*
* If the property to be updated is an object or an array, it is updated
* recursively.
*
* @param {Array<string>} path - An array where each element is a key in the object, * @param {Array<string>} path - An array where each element is a key in the object,
* forming a path to the property to be updated. * forming a path to the property to be updated.
* @param {object} obj - The object to be updated. * @param {object} obj - The object to be updated.
@ -36,13 +44,39 @@ function updateNestedObject(path: Array<string>, obj: object, value: ValueType)
// of the path. // of the path.
const [first, ...rest] = path; const [first, ...rest] = path;
// Return a new object that copies all properties of the original object, but updates // Check if 'first' is an array index.
// the property specified by 'first'. const indexMatch = first.match(/^(\w+)\[(\d+)\]$/);
// The updated property is an object that copies all properties of the original nested
// object, but updates the 'value' property. // If 'first' is an array index of the form "attribute[index]", then update the
// The new 'value' property is the result of a recursive call to updateNestedObject, // element at the specified index in the array. Otherwise, update the property
// with the rest of the path, the value of the nested object as the object to be // specified by 'first' in the object.
// updated, and the new value. if (indexMatch) {
const attribute = indexMatch[1];
const index = parseInt(indexMatch[2]);
if (Array.isArray(obj[attribute]?.value)) {
return {
...obj,
[attribute]: {
...obj[attribute],
value: obj[attribute].value.map((item, i) =>
i === index
? {
...item,
value: updateNestedObject(rest, item.value || {}, value)
}
: item
)
}
};
} else {
throw new Error(
`Expected ${attribute}.value to be an array, but received ${typeof obj[
attribute
]?.value}`
);
}
} else {
return { return {
...obj, ...obj,
[first]: { [first]: {
@ -51,6 +85,7 @@ function updateNestedObject(path: Array<string>, obj: object, value: ValueType)
} }
}; };
} }
}
const reducer = (state: State, action: Action): State => { const reducer = (state: State, action: Action): State => {
switch (action.type) { switch (action.type) {