How to Declare a Variable in a Template in Angular

How to declare a variable in a template in Angular

Update

We can just create directive like *ngIf and call it *ngVar

ng-var.directive.ts

@Directive({
selector: '[ngVar]',
})
export class VarDirective {
@Input()
set ngVar(context: unknown) {
this.context.$implicit = this.context.ngVar = context;

if (!this.hasView) {
this.vcRef.createEmbeddedView(this.templateRef, this.context);
this.hasView = true;
}
}

private context: {
$implicit: unknown;
ngVar: unknown;
} = {
$implicit: null,
ngVar: null,
};

private hasView: boolean = false;

constructor(
private templateRef: TemplateRef<any>,
private vcRef: ViewContainerRef
) {}
}

with this *ngVar directive we can use the following

<div *ngVar="false as variable">
<span>{{variable | json}}</span>
</div>

or

<div *ngVar="false; let variable">
<span>{{variable | json}}</span>
</div>

or

<div *ngVar="45 as variable">
<span>{{variable | json}}</span>
</div>

or

<div *ngVar="{ x: 4 } as variable">
<span>{{variable | json}}</span>
</div>

Plunker Example Angular4 ngVar

See also

  • Where does Angular 4 define "as local-var" behavior for *ngIf?

Original answer

Angular v4

  1. div + ngIf + let


    {{variable.a}}
    {{variable.b}}

  2. div + ngIf + as

view

<div *ngIf="{ a: 1, b: 2, c: 3 + x } as variable">
<span>{{variable.a}}</span>
<span>{{variable.b}}</span>
<span>{{variable.c}}</span>
</div>

component.ts

export class AppComponent {
x = 5;
}

  1. If you don't want to create wrapper like div you can use ng-container

view

<ng-container *ngIf="{ a: 1, b: 2, c: 3 + x } as variable">
<span>{{variable.a}}</span>
<span>{{variable.b}}</span>
<span>{{variable.c}}</span>
</ng-container>

As @Keith mentioned in comments

this will work in most cases but it is not a general solution since it
relies on variable being truthy

See update for another approach.

How to declare and assigning a variable in html template in Angular

Thanks to you I finaly founded a solution to my problem.
In the ts file a property category and a method:

categories: string[];
...
getCats(data: Menu[]): string[]{
return [...new Set(data.map((item) => <string>item.foodCategory?.description))];
}

and in the Html file this loop:

<div class="title" *ngFor="let category of categories">
<h2>Les <span>{{category}}</span></h2>
<div *ngFor="let m of menu">
<div *ngIf="m.foodCategory?.description == category">
<ul>
<li class="wow fadeInUp" data-wow-duration="300ms" data-wow-delay="300ms">
<div class="item">
<div class="item-title">
<span>{{m.price}} €</span>
<h3>{{m.title}}</h3>
<div class="border-bottom"></div>
</div>
<p>{{m.ingredients}}</p>
</div>
</li>
</ul>
</div>
</div>

Thanks to both of you for your help.

How to declare variable in template of Angular?

You can declare variable in template using let that will evaluate the function and get the result , using ngIf to actually check if the value is there and assign to the variable

<div *ngIf="getActualData(); let actual" > 
<div *ngIf="getVirtualData(); let virtual" >
{{actual - virtual}}
</div>

DEMO

Assign a value to a variable in the template - Angular7

Figured out. It is a bit of a hack. But works perfectly

<div *ngIf="true; let showEditBtn">
<div> {{ showEditBtn }} </div>
<button (click)="showEditBtn = false" *ngIf="showEditBtn"> Edit</button>
<button (click)="showEditBtn = true" *ngIf="!showEditBtn">Submit</button>
</div>

Is it possible to assign a value to a variable with let in an angular component template?

you could try using the let-* directive:

<ng-template let-variable="statByType('Users')?.count"> 
{{variable}}
</ng-template>

and then simply use the template.

If you need more help read the Angular Docs

How can I change the value of an Angular template variable?

Template Variables

For your main question, your elements can only see the the template variables of their parents.

For example, this will fail to compile:

<ng-container *ngIf="'later' as myVar">
<div>{{myVar}}</div>
</ng-container>
<div>{{myVar}}</div> <!-- No parent TV or reference in component.ts -->

So your conclusion is right, in that it is a different value, although it isn't all that weird if you think of it as living on that DOM-Element. They are more so meant as references to that particular element, and are indeed less useful for logic. For that you're better off binding to your component.ts file.

In short, I don't think reassigning of Template Variables is possible. You will just get the value of the closest parent.

Second Question

For your second question, this is a little shorter (but /w same result):

<ng-container *ngIf="'first' as myVar">
<ng-container *ngIf="(myVar == 'first' ? 'later' : '') as myVar">
<div>{{myVar}}</div>
</ng-container>
<div>{{myVar}}</div>
</ng-container>

You could also (ab)use ngTemplateOutlet to achieve something similar:

<ng-template #s [ngTemplateOutlet]="s" let-a [ngTemplateOutletContext]="{ $implicit: 'first' }">
{{a}}
<ng-template #t [ngTemplateOutlet]="t" let-b [ngTemplateOutletContext]="{ $implicit: a == 'first' ? 'later' : '' }">
{{b}}
</ng-template>
</ng-template>

Here's a Stackblitz for you.

Presentation Logic in Component.ts

It is actually perfectly fine to have logic for presentation in your component. In fact it is pretty much the only thing that should be in your presentation components.

It is a best practice to use the approach of Container & Presentation Components.

Container component

  • Manages the state by interacting with service/store
  • Contains only minor presentation, like for example a header/title
  • Passes state to presentation components using input properties

Presentation component

  • Presents/renders the data, but does not directly interact with state
  • Communicates with container component using output properties


Related Topics



Leave a reply



Submit