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.
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 */);
"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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With