Sponsor
Star

Created With

linkKey Tracking

When you have an array of objects, it often happens that you are interested on a particular entity based on some identifier, regardless of its position within the array:

1linkimport { state } from 'rxdeep';

2link

3linkconst s = state([

4link { id: 101, name: 'Jack', age: 32 },

5link { id: 102, name: 'Jill', age: 67 },

6link ...

7link]);


In this example, you might want a reactive state object that reflects state of Jack, independent of where Jack sits in the array. The keyed() method (or KeyedState class) allows you to track entities of an array using some key function which helps identify each entitiy:

1linkimport { state, keyed } from 'rxdeep';

2link

3linkconst k = keyed(state([

4link { id: 101, name: 'Jack', age: 32 },

5link { id: 102, name: 'Jill', age: 67 },

6link ...

7link ]),

8link person => person.id

9link);

10link

11linkk.key(101).subscribe(console.log);


In this example, the key function is person => person.id, i.e. each person is identified by their .id property. .key() method behaves like State.sub() method, except that it represents state of the entity matching given key instead of the entity on given index / property:

1linkk.value = [{ id: 103, name: 'James', age: 21 }, // --> no changes

2link ...state.value]; // --> no changes

3linkk.value = [{ id: 103, name: 'James', age: 21}, // --> no changes

4link { id: 101, name: 'Jack', age: 32 }]; // --> no changes

5linkk.value = [{ id: 101, name: 'Jack', age: 33 }]; // --> change!!

6link

7link// Logs only for the initial value and the last change:

8link// > { id: 101, name: 'Jack', age: 32 }

9link// > { id: 101, name: 'Jack', age: 33 }


The .key() method returns a typical State, so you can similarly use them to set values:

1linkk.key(101).sub('age').value = 34;

2link

3link// Logs:

4link// > { id: 101, name: 'Jack', age: 34 }

touch_app NOTE

Similar to a sub-state, it is highly recommended to keep a keyed substate (result of .key() method) subscribed (having called its .subscribe() method) before issueing changes to it, to ensure that the state is in sync with the change history.

info NOTE

Also you could use KeyedState constructor for creating keyed states:

1linkconst k = new KeyedState(new State(...), ...);


linkIndex Tracking

You can also track the index of a particular key within the array using .index() method:

1linkimport { keyed, state } from 'rxdeep';

2link

3linkconst k = keyed(state([

4link { id: 101, name: 'Jack', age: 32 },

5link { id: 102, name: 'Jill', age: 67 },

6link ]),

7link person => person.id

8link);

9link

10linkk.index(101).subscribe(console.log);

11link

12linkk.value = [{ id: 103, name: 'James', age: 21 },

13link ...state.value];

14linkk.value = [{ id: 103, name: 'James', age: 21},

15link { id: 101, name: 'Jack', age: 32 }];

16linkk.value = [{ id: 101, name: 'Jack', age: 33 }];

17link

18link// Logs:

19link// > 0

20link// > 1

21link// > 0


linkDetailed Array Changes

The KeyedState class also comes with .changes() method which provides a detailed change profile of the array in terms of additions, deletions and moved items:

1linkimport { state, keyed } from '../src';

2link

3linkconst k = keyed(state([

4link { id: 101, name: 'Jack', age: 32 },

5link { id: 102, name: 'Jill', age: 67 },

6link ]),

7link person => person.id

8link);

9link

10linkk.changes().subscribe(console.log);

11link

12linkk.value = [{ id: 103, name: 'James', age: 21 },

13link ...k.value];

14link// Logs:

15link// > {

16link// > additions: [{index: 0, item: {id: 103, name: 'James', age: 21}}],

17link// > deletions: [],

18link// > moves: [

19link// > {oldIndex: 0, newIndex: 1, item: {id: 101, name: 'Jack', age: 32}},

20link// > {oldIndex: 1, newIndex: 2, item: {id: 102, name: 'Jill', age: 67}}

21link// > ]

22link// > }

23link

24linkk.value = [{ id: 103, name: 'James', age: 21}, // --> no changes

25link { id: 101, name: 'Jack', age: 32 }]; // --> no changes

26link// Logs:

27link// > {

28link// > additions: [],

29link// > deletions: [{index: 2, item: {id: 102, name: 'Jill', age: 67}}],

30link// > moves: []

31link// > }

32link

33linkk.value = [{ id: 101, name: 'Jack', age: 33 }]; // --> change!!

34link// Logs:

35link// > {

36link// > additions: [],

37link// > deletions: [{index: 0, item: {id: 103, name: 'James', age: 21}}],

38link// > moves: [{oldIndex: 1, newIndex: 0, item: {id: 101, name: 'Jack', age: 32}}]

39link// > }

40link

41linkk.key(101).sub('age').value = 34;

42link// Logs:

43link// > {

44link// > additions: [],

45link// > deletions: [],

46link// > moves: []

47link// > }

Key TrackingIndex TrackingDetailed Array Changes

Home How to Install State Key Tracking Change Verification Change Performance Precision