manuelkue
manuelkue

Reputation: 122

Is there a way to react to an input-signal's value as soon as it is set / changed without having to wait for ngAfterViewInit?

Usually you would use effect(() => ...) to react to a signal change.

Unfortunately it seems like effects only run as soon as the component is fully initialized and therefore during/after ngAfterViewInit.

In our case we have to sync component's input data to a scoped service as soon as the input is set and want to use it inside ngAfterViewInit already which does not work with signal-inputs.

The way with "classic" @Inputs has been to create a setter that runs before/during ngOnChanges. Therefore the data is already available during ngAfterViewInit.

Lifecycle order:

So far, I have not been able to think of a better way to transport the data of a signal input to the service than using effect.

However, this will execute only after ngAfterViewInit.

Regarding (mis)using a signal's transform-method it would feel totally wrong. Nevertheless it would be executed at the expected time on setting the input. However, this is likely to cause problems with a risk that I cannot currently assess and it might also be not comprehensible for future development.

Using the @Input setter, on the other hand, is a tried and tested variant that processes data at the earliest possible point in time. However, deviating from the signal input for this is of course annoying.

I have not yet found a source online as to whether the problem should be approached differently. Unfortunately, an effect cannot be configured in this respect.

Converting a signal into an Observable + Subscribe does not change anything, as an effect is also used by the toObservable under the hood.

What are other people's thoughts on this? Should I just rely on the "classic" @Input + set or is there an unknown approach with signals?

Upvotes: 2

Views: 1273

Answers (1)

manuelkue
manuelkue

Reputation: 122

As commented by @m-g the way to go with signals seems to be falling back to ngOnChanges. It's maybe just a little less concise than Input-setters but should not have any negative effects on performance.

See also https://dev.to/angular/angular-setters-vs-ngonchanges-which-one-is-better-4f2b

So the final solution for propagating signals' changes apart from the (for the usecase of propagating data) unrecommended effect would look like this:

myData = input<ValueType>();

ngOnChanges({ myData } : {myData?: SimpleChange & { currentValue: ValueType }}){
  if (myData !== undefined){
    this.service.sync(myData.currentValue)
  }
}

Upvotes: 2

Related Questions