angular: Combination of `HostBinding` and signals is not supported (input signals too)

Which @angular/* package(s) are relevant/related to the feature request?

core

Description

I am currentely trying to use new input signal api but I am unable to replace this code with DRY.

  @HostBinding('attr.title')
  @Input({ required: true, alias: 'appModalClose' })
  public closeBtnText!: string;

Proposed solution

Maybe it should be replaced by something like

public closeBtnText = input.required<string>({ alias: 'appModalClose', hostBinding: ['attr.title'] });

Alternatives considered

I was trying to find some solutions, but this is not working

@HostBinding('attr.title')
public closeBtnText = input.required<string>({ alias: 'appModalClose' });
  1. Host is stacked in memory leak
@Component({
  // eslint-disable-next-line @angular-eslint/no-host-metadata-property
  host: {
    '[title]': 'closeBtnText()',
  },
})
export class ModalCloseComponent {
  public closeBtnText = input.required<string>({ alias: 'appModalClose' });
}

About this issue

  • Original URL
  • State: open
  • Created 6 months ago
  • Reactions: 10
  • Comments: 22 (10 by maintainers)

Most upvoted comments

It’s also possible to split the two, and write:

appModalClose = input.required<string>();

@HostBinding('attr.title')
get title() { return this.appModalClose(); }

@devversion has a function in the constructor been considered?

constructor() {
  hostBinding('class.hidden', () => this.isHidden());
  hostBinding('class.hidden', this.isHidden); // alternative: isHidden is a signal
}

Oh, so we’re stuck with using a string expression with no IDE support? That’s unfortunate. Any plans to support Signal in a HostBinding?

The style guide will be updated as part of the upcoming v18 release. This is tracked by ##54284.

@dkimmich-onventis I use vscode. It would be nice if angular highlighted and syntax/error checked the host field in vscode. 😃

If this is going to be the recommended approach going forward, should this style guide rule be updated?

https://angular.io/guide/styleguide#style-06-03

Because bar in this context is not defined. this.bar is also not defined, as we are inside the decorator and not inside the class. It needs to be a string so TypeScript doesn’t throw errors.

My initial thought is that @HostBinding is expecting raw values. A Signal is not supported, even without signal inputs. In the host field of the component the signal can be read and used to e.g. bind attr.title. I will look more into this

Thanks for pointing it out but that was not my main point, merely a nudge in understanding the issue. Sorry if my message was misunderstood:

The problem I highlighted is that both the official Angular websites conflict on the recommendation of using host vs HostBinding/HostListener. That should be addressed on the angular repo 😃

There is no reference named bar in the scope the decorator.

@cyraid Which IDE do you use? I am using WebStorm, and it works like a charm, with code highlighting, suggestions and everything.

image

@k3nsei angular-eslint/angular-eslint#1772 I’ve suggested the change, thank you.

@nickdobson Yeah, we likely need to discuss this more with the team. Good point.

@devversion I have doubble checked

@Directive({
  standalone: true,
  selector: 'my-dirx',
  host: { '[attr.title]': 'bla()' },
})
export class MyDir {
  bla = input.required<string>();
}

and it is working right now