I have a web component created with Angular 19 prerelease version. It has a liked
signal input, which can be set from a parent but can't be modified from within because signal inputs are read only. To manage toggling the state, I introduced a local signal _liked
, which I can toggle and emit its value to the parent. This feels like an overkill, I'm not sure if this is a good way of handling the state.
I need to transform the input value into a boolean, because when the custom element is used outside Angular context, say in a Vue app, the resulting html will render my input as a string and strings are always truthy.
Do you have any suggestions on improving the following code?
export class LikeButtonComponent {
liked = input(false, { transform: booleanAttribute });
_liked = signal(this.liked());
likedChange = output<boolean>({ alias: 'likedchange' });
constructor() {
effect(() => {
this._liked.set(this.liked());
});
}
toggleLike() {
this._liked.update(value => !value);
this.likedChange.emit(this._liked());
}
}
I looked into the model()
and it doesn't seem to be suitable here because it doesn't expose a transform option. The problem is that when values are passed into a web component they are passed as strings, like this <like-button liked="true"></like-button>
.
Since Angular 19 you can use the new linkedSignal()
function which is basically a computed
that is writable at the same time. It allows you to skip the effect:
export class LikeButtonComponent {
liked = input(false, { transform: booleanAttribute });
_liked = linkedSignal(() => this.liked());
likedChange = output<boolean>({ alias: 'likedchange' });
toggleLike() {
this._liked.update(value => !value);
this.likedChange.emit(this._liked());
}
}
As of Angular v19,
linkedSignal
is in developer preview and might change before becoming stable