Search code examples
angulartypescriptangular-signals

Angular error using new input signal transform to update other property in component


I have an angular 18 app and I have a form in a component that needs to get its value updated when an input property for the component changes.

The "old" way I would do this by defining setters and getters for the input property like this:

  private _shiftUpdate: ShiftUpsert | null = null;

  @Input()
  set shiftUpdate(value: ShiftUpsert | null) {
    this._shiftUpdate = value;
    if (value) {
      this.shiftForm.patchValue({ shiftId: value.shiftId, shiftGuid: value.shiftGuid });
    }
  }

  get shiftUpdate(): ShiftUpsert | null {
    return this._shiftUpdate;
  }

You can see that the form value is patched when this property is changed from the parent component.

My question is how to do this with the "new" signal input type. When I try the following:

updatedShift = input<ShiftUpsert, ShiftUpsert>({ shiftId: 0 }, {
    transform(value: ShiftUpsert) {
      if (value) {
        this.shiftForm.patchValue(value);
      }
      return value;
    }
  });

I get an error on the this.shiftForm saying:

Property 'shiftForm' does not exist on type 'Required<Pick<InputOptions<ShiftUpsert, ShiftUpsert>, "transform">> & InputOptions<ShiftUpsert, ShiftUpsert>'.

So I can see that the context of the inner input transform does not have access to the component properties.

Is there a way to do this with the new signal inputs or is the fact that I can't do it telling me its an anti pattern?

Thanks


Solution

  • It's an anti-pattern, input transforms should not be used to sync changes of an input with other parts of the application. You should use an effect instead:

    updatedShift = input<ShiftUpsert, ShiftUpsert>({ shiftId: 0 });
    constructor() {
      effect(() => this.shiftForm.patchValue(value));
    }