NgLet [](https://github.com/nigrosimone/ng-let/actions/workflows/node.js.yml) [](https://www.npmjs.com/package/ng-let)
July 25, 2026 · View on GitHub
Angular structural directive for sharing data as local variable into html component template.
Description
Sometime there is a need to share data into component template as local variable. This structural directive create local context of variable that can be used into html template.
See the stackblitz demo, or its sources.
Features
✅ Observable support
✅ Async pipe support
✅ NgModel support
✅ Type casting
✅ Renders falsy values
Unlike *ngIf, *ngLet never hides its content: 0, '', false, null, undefined and NaN
are all bound and rendered, so a template guarded by *ngLet shows up exactly once whatever the
expression evaluates to.
Because of that, *ngLet does not narrow the type of what you bind to it, and a nullable
expression stays nullable inside the template:
<!-- time is `number | null`: the template renders before the first value arrives -->
<ng-container *ngLet="timer$ | async as time">{{ time?.toFixed(2) }}</ng-container>
<!-- bind a non-nullable expression when you would rather not guard every use -->
<ng-container *ngLet="(timer$ | async) ?? 0 as time">{{ time.toFixed(2) }}</ng-container>
Get Started
Install ng-let
npm i ng-let
Usage, eg.:
import { Component } from '@angular/core';
import { NgLetDirective } from 'ng-let';
@Component({
selector: 'app-root',
template: `
<ng-container *ngLet="(num1 + num2) as total"> <!-- single computation -->
<div>
1: {{ total }} <!-- 3 -->
</div>
<div>
2: {{ total }} <!-- 3 -->
</div>
</ng-container>
`,
imports: [NgLetDirective]
})
export class AppComponent {
num1: number = 1;
num2: number = 2;
}
or with the implicit syntax:
import { Component } from '@angular/core';
import { NgLetDirective } from 'ng-let';
@Component({
selector: 'app-root',
template: `
<ng-container *ngLet="(num1 + num2); let total"> <!-- single computation -->
<div>
1: {{ total }} <!-- 3 -->
</div>
<div>
2: {{ total }} <!-- 3 -->
</div>
</ng-container>
`,
imports: [NgLetDirective]
})
export class AppComponent {
num1: number = 1;
num2: number = 2;
}
Examples
Below there are some examples of use case.
Example: observable
Example of use with observable, eg.:
import { Component } from '@angular/core';
import { defer, Observable, timer } from 'rxjs';
import { NgLetDirective } from 'ng-let';
@Component({
selector: 'app-root',
template: `
<ng-container *ngLet="timer$ | async as time"> <!-- single subscription -->
<div>
1: {{ time }}
</div>
<div>
2: {{ time }}
</div>
</ng-container>
`,
imports: [NgLetDirective]
})
export class AppComponent {
timer$: Observable<number> = defer(() => timer(3000, 1000));
}
or with the implicit syntax:
import { Component } from '@angular/core';
import { defer, Observable, timer } from 'rxjs';
import { NgLetDirective } from 'ng-let';
@Component({
selector: 'app-root',
template: `
<ng-container *ngLet="timer$ | async; let time"> <!-- single subscription -->
<div>
1: {{ time }}
</div>
<div>
2: {{ time }}
</div>
</ng-container>
`,
imports: [NgLetDirective]
})
export class AppComponent {
timer$: Observable<number> = defer(() => timer(3000, 1000));
}
Example: signal
Example of use with signal, eg.:
import { Component, signal } from '@angular/core';
import { NgLetDirective } from 'ng-let';
@Component({
selector: 'app-root',
template: `
<ng-container *ngLet="mySignal() as time"> <!-- single computation -->
<div>
1: {{ time }}
</div>
<div>
2: {{ time }}
</div>
</ng-container>
`,
imports: [NgLetDirective]
})
export class AppComponent {
mySignal = signal(1);
constructor() {
setInterval(() => this.mySignal.update(value => value + 1), 1000)
}
}
or with the implicit syntax:
import { Component, signal } from '@angular/core';
import { NgLetDirective } from 'ng-let';
@Component({
selector: 'app-root',
template: `
<ng-container *ngLet="mySignal(); let time"> <!-- single computation -->
<div>
1: {{ time }}
</div>
<div>
2: {{ time }}
</div>
</ng-container>
`,
imports: [NgLetDirective]
})
export class AppComponent {
mySignal = signal(1);
constructor() {
setInterval(() => this.mySignal.update(value => value + 1), 1000)
}
}
Support
This is an open-source project. Star this repository, if you like it, or even donate. Thank you so much!
My other libraries
I have published some other Angular libraries, take a look:
- NgSimpleState: Simple state management in Angular with only Services and RxJS or Signal
- NgHttpCaching: Cache for HTTP requests in Angular application
- NgGenericPipe: Generic pipe for Angular application for use a component method into component template.
- NgForTrackByProperty: Angular global trackBy property directive with strict type checking