How to detect change in Angular signal input function?
Asked Answered
D

3

5

I have a component that takes two inputs, user and userList I wonder should i detect the change with the ngOnChanges lifecycle hook? What's the best practice for that?

  // Note: Old approach
  // @Input() user: User; // For editing a user
  // @Input({ alias: "userList" }) _userList: User[] = [];
  // @Output() addUser = new EventEmitter<User>();

  // Note: New approach
  user = input<User>();
  _userList = input<User[]>([], { alias: "userList" });
  addUser = output<User>();

  constructor(private userService: UserService) { }

  ngOnInit(): void {
    this.getRoleList();
  }

  ngOnChanges(changes: SimpleChanges): void {
    const { user, _userList } = changes;
    console.log(changes);

    if (user && user.currentValue) {
      this.userModel = user.currentValue;
      this.initializeForm(user.currentValue);
    }

    if (_userList) {
      this.userList.set(_userList.currentValue);
    }
  }

I tried the ngOnChanges lifecycle hook and it works fine but I don't know if it's ok or not for my signal-based component.

Dominican answered 12/4 at 10:38 Comment(1)
input() returns a signal. You can use this signal to track updates.Brockington
U
6

The new signal inputs defined by signal() or signal.required() return signals.

As any other signal you can use effect() to track and subscribe to changes that may happen.

effect(() => {
  console.log(this.user);
  // will be call when `this.user` changes
})

There is also another alternative that is RxJS based. Angular provides an interop to convert signals to observables via the toObservable() function.

toObservable(this.user).subscribe((newUser) => /* when user changes */);

Ununa answered 12/4 at 20:48 Comment(4)
Hi Matthieu How can I assign a new value to my signal variable when my input signal changes? I know we can't use effectDominican
You'll likely need to use an effect et enable signal writes.Ununa
I wouldn't recommend using effect. Effect has a few rare cases, in which it could be used. Usually you should stick to computed()Birthwort
Yes, effect should be only used for side effects and prefer computed() for anything that can be derived.Ununa
S
4

"Avoid using effects for propagation of state changes" says Angular documentation. You can read for effect() method use cases and more here

computed() method is perfect for keeping track of changes. Here is a simple example:

TS:

someDataToKeepTrack = input.required<number>();

//Whenever someDataToKeepTrack  field updates, someRelatedData will be re-computed
someRelatedData = computed(() => {
    console.log('Data has changed. Here is the new value : ' + this.someDataToKeepTrack() )
    return this.someDataToKeepTrack() * 2;
});

HTML:

<p> Here is updated-data: {{someRelatedData() }} </p>

Where we call the component - HTML:

<some-component [someDataToKeepTrack]="inputData"></some-component>  
<input type="text" name="inputData" [(ngModel)]="inputData" />

Where we call the component - TS :

inputData = 10; //Initial Data
Separative answered 22/7 at 10:52 Comment(0)
L
-1

For detect changes of signal you can use effect().

https://angular.io/guide/signals#effects

Here is an example:

https://stackblitz.com/edit/angular-yxrzwb

Layette answered 12/4 at 10:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.