3

I have a directive in angular 11 with the following inputs :

@Directive({
  selector: "[appHasToken]",
})
export class HasTokenDirective implements OnInit, OnDestroy {
  @Input("appHasToken") fallback: TemplateRef<any>;
  @Input("showWarning") showWarning = false;
//...
}

I call it in my code like this :

<ng-container *appHasToken="noToken">

Now in a single place, I want the showWarning to true, so I did

<ng-container *appHasToken="noToken;" [showWarning]="true">

but I am prompted with

Can't bind to 'showWarning' since it isn't a known property of 'ng-container'

now, I know I can rename the input with a different name than the directive and do

<ng-container appHasToken [templateRef]="noToken" [showWarning]="true">

but what about keeping the same stuff I was doing, is there a fix ?

2 Answers 2

3

When you write a directive with * (structural directive), angular adds an ng-template around your element, so <ng-container *appHasToken="noToken"> gets translated to:

<ng-template [appHasToken]="noToken">
  <ng-container></ng-container>
</ng-template>

When you have another input, the second input remains on the ng-container, and since the directive isn't there anymore, angular throws because the now ng-container doenst have a known property showWarning. To overcome this, there is microsyntax in angualr which allows passing more than one input to the structural directive - you add the directive name in the input naming before the input's name, so showWarning becomes appHasTokenShowWarning (notice the uppercase in the first word), and then can be accessed in the following way:

<ng-container *appHasToken="noToken; showWarning true">

if this reminds you of ngFor its because ngFor also uses this! here is the source code

Here is a stackblitz, and note your inputs should look like the following:

export class HasTokenDirective implements OnInit, OnDestroy { @Input("appHasToken") fallback: TemplateRef; @Input("appHasTokenShowWarning") showWarning = false; //... }

Sign up to request clarification or add additional context in comments.

5 Comments

Hi, thanks, I tried to do this before : *appHasToken="noToken; showWarning: true" but it makes the whole thing invalid >Property binding appHasTokenShowWarning not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations".
while *appHasToken="noToken" alone works, I don7t know why the addition breaks the whjole thing.
and you also changed the input name in the directive?
the inputs names are like the main post.
you have to change the input for the second parameter, read my answer again, I will add a stackblitz in a couple of minutes
0

<ng-container> isn't rendered in the DOM. It is mainly used as Javascript curly braces in the template for *ngFor and *ngIf. Check the documentation https://angular.io/guide/structural-directives#ng-container-to-the-rescue

Instead, use a plain div or any other component.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.