sfaust
sfaust

Reputation: 2373

Angular Detect Object Property Change

I have a web portal written in Angular 7 that has a profile page where the user can edit their account data. The whole portal also has an account section in the top right that shows the logged in users username (and is how they get to the profile editing). I have the drop down menu subscribing to changes of user in the core auth handler so that if they log out and log someone else in it updates properly, etc. However, if the user edits their username on the profile page it doesn't update in the account dropdown until they log out and back in because it's looking for a full change of user, not just change of user data.

So the question is how do I subscribe to the changes in the properties of the current user so I can update the username display when they change it?

Upvotes: 0

Views: 1828

Answers (1)

Barr J
Barr J

Reputation: 10927

You can use observables:

<form #f="ngForm">
  <input type="text" name="firstName" [(ngModel)]="user.firstName">
  <input type="text" name="sureName" [(ngModel)]="user.sureName">
</form>

@ViewChild('f') f;

ngAfterViewInit() {
  this.f.form.valueChanges.subscribe((change) => {
   console.log(change)
  })
}

You can use ngModelChange:

<input type="text" (ngModelChange)="doSomething($event)" [ngModel]="user.firstName">

doSomething(event) {
  console.log(event); // logs model value
}

Or you can use KeyValueDiffers:

import { KeyValueChanges, KeyValueDiffer, KeyValueDiffers } from '@angular/core';

export class User {
  firstName: string;
  sureName: string;
}

@Component({
  selector: 'my-app',
  templateUrl: `./app.component.html`
})
export class AppComponent {
  private customerDiffer: KeyValueDiffer<string, any>;
  private customer: Customer;

  constructor(private differs: KeyValueDiffers) {}

  ngOnInit(): void {
    this.user = new User();
    this.userDiffer = this.differs.find(this.user).create();
  }

  userChanged(changes: KeyValueChanges<string, any>) {
    console.log('changes');
    /* If you want to see details then use
      changes.forEachRemovedItem((record) => ...);
      changes.forEachAddedItem((record) => ...);
      changes.forEachChangedItem((record) => ...);
    */
  }

  ngDoCheck(): void {
      const changes = this.userDiffer.diff(this.customer);
      if (changes) {
        this.userChanged(changes);
      }
  }
}

Upvotes: 1

Related Questions