10

I am using FormGroup and FormControls toghether with ngrx to build a reactive form. Also I'm using the Inspector of the Chrome redux redux dev-tools. I want to properly render the history of actions while skipping some form change actions. Currently skipping any form action before the last one will not project as if that specific form change was not made. The form sends a full object with all the fields applied. Thus any change from previous actions is obscured because each actions replaces all previous properties of the form's state.

A bit of context: I am stashing in state store a person object while the user fills up a form inside a modal. Then on submit I send the person data to the server.

The form component

// Emit events when form changes
this.personForm.valueChanges
    .debounceTime(500)
    .subscribe(person => {

        // Block @Input person update from triggering a form change
        if (this._personFormInputUpdated === true) {

            // Reset @Input safe-guard
            this._personFormInputUpdated = false;

            return;
        }

        // Ignore unchaged form
        if (!this.personForm.dirty) { return; }

        debug('Person form changed');
        this.personChange.emit(Object.assign({}, person));
    });

The reducer:

    case AccountsDataActions.STASH_ACCOUNT_PERSON:
        newState = Object.assign({}, state, {
            stashedAccountPerson: Object.assign({}, state.stashedAccountPerson, action.payload)
        });
        debug('STASH_ACCOUNT_PERSON:', [newState.stashedAccountPerson]);
        return newState;

I am considering using some diff-checking library in order to select only the changed fields for the next STASH_ACCOUNT_PERSON action. Is there a simpler method that doesn't require an additional library? Something built-in into ng2 forms?

Thanks!

Edit ngOnChanges() has a similar effect for @Input decorators. Is there something similar for forms?

Adrian Moisa
  • 3,923
  • 7
  • 41
  • 66

2 Answers2

3

Yes. try to use distinctUntilChanged method. Returns an observable sequence that contains only distinct contiguous elements according to the keySelector and the comparer.

this.personForm.valueChanges
    .debounceTime(500)
    .distinctUntilChanged()
    .subscribe(person => {
       // only what changed!
    });
Shlomi Levi
  • 3,114
  • 1
  • 23
  • 35
  • 1
    Well, that seems this is not the necessary solution. I'm looking for something that compares previous object with new object and renders a list of changes between the two. Altough, I'm glad that I learned something new. https://www.learnrxjs.io/operators/filtering/distinctuntilchanged.html – Adrian Moisa Feb 12 '17 at 14:48
  • Thanks :) for your solution you can see that distinctUntilChanged give you the old value and new value as function params. now, how to get only the “changed” values from two JSON objects: http://stackoverflow.com/questions/31295545/how-to-get-only-the-changed-values-from-two-json-objects. then return by using `map` or `switchMap` operator. hope that helpful! – Shlomi Levi Feb 12 '17 at 15:42
1

You can have look at KeyValueDiffers and KeyValueDiffer in the @angular/core

Tuong Le
  • 18,533
  • 11
  • 50
  • 44