@rx-angular/cdk
Version:
@rx-angular/cdk is a Component Development Kit for ergonomic and highly performant angular applications. It helps to to build Large scale applications, UI libs, state management, rendering systems and much more. Furthermore the unique way of mixing reacti
92 lines (91 loc) • 2.98 kB
TypeScript
import { ComparableData } from '../interfaces/comparable-data-type';
/**
* @description
* Updates or inserts (if does not exist) one or multiple items in an array T[].
* For comparison you can provide a key, an array of keys or a custom comparison function that should return true if
* items match.
* If no comparison is provided, an equality check is used by default.
* upsert is `pure` and `immutable`, your inputs won't be changed
*
*
* @example
* // Upsert (update) with key
*
* const creatures = [{id: 1, type: 'cat'}, {id: 2, type: 'dog'}];
*
* const newCat = {id: 1, type: 'lion'};
*
* const updatedCreatures = upsert(creatures, newCat, 'id');
*
* // updatedCreatures will be:
* // [{id: 1, type: 'lion'}, {id: 2, type: 'dog'}];
*
* @example
* // Upsert (insert) with key
*
* const creatures = [{id: 1, type: 'cat'}, {id: 2, type: 'dog'}];
*
* const newCat = {id: 3, type: 'lion'};
*
* const updatedCreatures = upsert(creatures, newCat, 'id');
*
* // updatedCreatures will be:
* // [{id: 1, type: 'cat'}, {id: 2, type: 'dog'}, {id: 3, type: 'lion'}];
*
* @example
* // Upsert (update) with array of keys
*
* const creatures = [{id: 1, type: 'cat', name: 'Bella'}, {id: 2, type: 'dog', name: 'Sparky'}];
*
* const newCat = {id: 1, type: 'lion', name: 'Bella'};
*
* const updatedCreatures = upsert(creatures, newCat, ['id', 'name']);
*
* // updatedCreatures will be:
* // [{id: 1, type: 'lion', name: 'Bella'}, {id: 2, type: 'dog', name: 'Sparky'}];
*
* @example
* // Update (insert) with comparison function
*
* const creatures = [{id: 1, type: 'cat'}, {id: 2, type: 'dog'}];
*
* const newCat = {id: 3, type: 'lion'};
*
* const updatedCreatures = upsert(creatures, newCat, (a, b) => a.id === b.id);
*
* // updatedCreatures will be:
* // [{id: 1, type: 'cat'}, {id: 2, type: 'dog'}, {id: 3, type: 'lion'}];
*
* @example
* // Usage with RxState
*
* export class ListComponent {
*
* // trigger which gets called on add/update (for reactive implementation)
* readonly addOrUpdateCreature = new Subject<Creature>();
*
* constructor(private state: RxState<ComponentState>) {
* const initialCreatures = [{id: 1, type: 'cat', name: 'Bella'}, {id: 2, type: 'dog', name: 'Sparky'}];
* state.set({ creatures: initialCreatures });
* // Reactive implementation
* state.connect(
* 'creatures',
* this.addOrUpdateCreature,
* ({ creatures }, creatureToUpsert) => {
* return upsert(creatures, creatureToUpsert, 'id');
* }
* );
* }
*
* // Imperative implementation
* updateCreature(creatureToUpdate: Creature): void {
* this.state.set({ creatures: upsert(this.state.get('creatures'), creatureToUpdate, 'id')});
* }
* }
*
* @returns T[]
*
* @docsPage upsert
* @docsCategory transformation-helpers
*/
export declare function upsert<T>(source: T[], update: Partial<T>[] | Partial<T>, compare?: ComparableData<T>): T[];