diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.ts index e24fcb66c4..fa4d27a6fd 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.ts @@ -1,5 +1,5 @@ import { DeepState } from "./deep-state"; -import { appendToFrozenArray } from "./append-to-frozen-array.method"; +import { pushToUniqueArray } from "./push-to-unique-array.method"; /** * @export @@ -28,8 +28,8 @@ export class ArrayState extends DeepState { * { key: 1, value: 'foo'}, * { key: 2, value: 'bar'} * ]; - * const mySubject = new ArrayState(data, (x) => x.key); - * mySubject.remove([1]); + * const myState = new ArrayState(data, (x) => x.key); + * myState.remove([1]); */ remove(uniques: unknown[]) { let next = this.getValue(); @@ -59,8 +59,8 @@ export class ArrayState extends DeepState { * { key: 2, value: 'bar'}, * { key: 3, value: 'poo'} * ]; - * const mySubject = new ArrayState(data, (x) => x.key); - * mySubject.filter((entry) => entry.key !== 1); + * const myState = new ArrayState(data, (x) => x.key); + * myState.filter((entry) => entry.key !== 1); * * Result: * [ @@ -75,8 +75,8 @@ export class ArrayState extends DeepState { } /** - * @method append - * @param {Partial} partialData - A object containing some of the data for this Subject. + * @method appendOne + * @param {T} entry - new data to be added in this Subject. * @returns ArrayState * @description - Append some new data to this Subject. * @example Example append some data. @@ -84,11 +84,17 @@ export class ArrayState extends DeepState { * { key: 1, value: 'foo'}, * { key: 2, value: 'bar'} * ]; - * const mySubject = new ArrayState(data); - * mySubject.append({ key: 1, value: 'replaced-foo'}); + * const myState = new ArrayState(data); + * myState.append({ key: 1, value: 'replaced-foo'}); */ appendOne(entry: T) { - this.next(appendToFrozenArray(this.getValue(), entry, this._getUnique)) + const next = [...this.getValue()]; + if(this._getUnique) { + pushToUniqueArray(next, entry, this._getUnique); + } else { + next.push(entry); + } + this.next(next); return this; } @@ -102,21 +108,22 @@ export class ArrayState extends DeepState { * { key: 1, value: 'foo'}, * { key: 2, value: 'bar'} * ]; - * const mySubject = new ArrayState(data); - * mySubject.append([ + * const myState = new ArrayState(data); + * myState.append([ * { key: 1, value: 'replaced-foo'}, * { key: 3, value: 'another-bla'} * ]); */ append(entries: T[]) { - // TODO: stop calling appendOne for each but make sure to handle this in one. - entries.forEach(x => this.appendOne(x)) - - /* - const unFrozenDataSet = [...this.getValue()]; - - this.next(unFrozenDataSet); - */ + if(this._getUnique) { + const next = [...this.getValue()]; + entries.forEach(entry => { + pushToUniqueArray(next, entry, this._getUnique!); + }); + this.next(next); + } else { + this.next([...this.getValue(), ...entries]); + } return this; } } diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/push-to-unique-array.method.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/push-to-unique-array.method.ts new file mode 100644 index 0000000000..35e4e3169c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/push-to-unique-array.method.ts @@ -0,0 +1,22 @@ +/** + * @export + * @method pushToUniqueArray + * @param {T[]} data - An array of objects. + * @param {T} entry - The object to insert or replace with. + * @param {getUniqueMethod: (entry: T) => unknown} [getUniqueMethod] - Method to get the unique value of an entry. + * @description - Append or replaces an item of an Array. + * @example Example append new entry for a Array. Where the key is unique and the item will be updated if matched with existing. + * const entry = {key: 'myKey', value: 'myValue'}; + * const newDataSet = pushToUniqueArray([], entry, x => x.key === key); + * mySubject.next(newDataSet); + */ +export function pushToUniqueArray(data: T[], entry: T, getUniqueMethod: (entry: T) => unknown): T[] { + const unique = getUniqueMethod(entry); + const indexToReplace = data.findIndex((x) => getUniqueMethod(x) === unique); + if (indexToReplace !== -1) { + data[indexToReplace] = entry; + } else { + data.push(entry); + } + return data; +}