Cheatsheet
A quick reference for AngularDart syntax and common patterns.
Component
@Component(
selector: 'my-component',
templateUrl: 'my_component.html',
// or template: '<p>Hello</p>',
styleUrls: ['my_component.css'],
// or styles: ['p { color: red; }'],
directives: [NgIf, NgFor, OtherComponent],
providers: [ClassProvider(MyService)],
changeDetection: ChangeDetectionStrategy.OnPush,
)
class MyComponent implements OnInit, OnDestroy {
// ...
}
@Input()
String? name;
@Input('alias')
String? internalName;
@Output()
final clickStream = StreamController<String>.broadcast();
void onClick() => clickStream.add('clicked');
Template Syntax
| Syntax |
Description |
{{ expr }} |
Interpolation |
[prop]="expr" |
Property binding |
(event)="handler()" |
Event binding |
[(ngModel)]="prop" |
Two-way binding |
#ref |
Template reference variable |
*ngIf="cond" |
Conditional rendering |
*ngFor="let x of list" |
Loop rendering |
[ngClass]="{}" |
CSS class binding |
[ngStyle]="{}" |
Style binding |
[ngSwitch]="val" |
Switch rendering |
Built-in Directives
<!-- Conditional -->
<div *ngIf="condition">Shown</div>
<div *ngIf="condition; else other">Shown</div>
<ng-template #other>Other</ng-template>
<!-- Loop -->
<li *ngFor="let item of items; let i = index">{{ i }}: {{ item }}</li>
<!-- Switch -->
<div [ngSwitch]="value">
<span *ngSwitchCase="'a'">A</span>
<span *ngSwitchCase="'b'">B</span>
<span *ngSwitchDefault>Other</span>
</div>
<!-- Class/Style -->
<div [ngClass]="{'active': isActive, 'disabled': isDisabled}">
<div [ngStyle]="{'color': color, 'font-size.px': size}">
<!-- Reference -->
<input #myInput>
<button (click)="myInput.focus()">Focus</button>
Lifecycle Hooks
| Hook |
When |
| Constructor |
Always first |
ngOnChanges |
Input changes |
ngOnInit |
After first ngOnChanges |
ngDoCheck |
Every change detection |
ngAfterContentInit |
Content projected |
ngAfterContentChecked |
Content checked |
ngAfterViewInit |
View initialized |
ngAfterViewChecked |
View checked |
ngOnDestroy |
Before destruction |
Dependency Injection
@Injectable()
class MyService {
// ...
}
@Component(
selector: 'my-component',
providers: [ClassProvider(MyService)],
template: '...',
)
class MyComponent {
final MyService _service;
MyComponent(this._service);
}
Provider Types
providers: [
ClassProvider(MyService),
ClassProvider(BaseService, useClass: RealService),
ValueProvider(API_URL, 'https://api.example.com'),
FactoryProvider(CONFIG, (i) => Config.fromEnv()),
ExistingProvider(Alias, MyService),
]
Routing
import 'package:angulardart/angular.dart';
import 'package:angulardart_router/angulardart_router.dart';
@Component(
selector: 'my-app',
template: '<a [routerLink]="[\'/\']">Home</a>'
'<a [routerLink]="[\'/about\']">About</a>'
'<router-outlet [routes]="routes"></router-outlet>',
directives: [routerDirectives],
)
class AppComponent implements OnInit {
final Router _router;
List<RouteDefinition> routes = [];
AppComponent(this._router);
@override
void ngOnInit() {
routes = [
RouteDefinition(path: '/', component: HomeComponentFactory, useAsDefault: true),
RouteDefinition(path: '/about', component: AboutComponentFactory),
RouteDefinition(path: '/users/:id', component: UserComponentFactory),
];
}
}
Route Parameters
class UserComponent implements OnInit {
String? userId;
final Router _router;
UserComponent(this._router);
@override
void ngOnInit() {
userId = _router.current?.queryParameters['id'] ??
_router.current?.path.split('/').last;
}
}
Navigation
final Router _router;
void navigateToUser(String userId) {
_router.navigate('/users/$userId');
}
void navigateWithQuery() {
_router.navigate('/search', NavigationParams(
queryParameters: {'q': 'dart'},
));
}
Template-Driven
@Component(
template: "
<form #f="ngForm" (ngSubmit)="onSubmit(f)">
<input ngModel name="name" required>
<button [disabled]="f.invalid">Submit</button>
</form>
",
directives: [formDirectives],
)
late final FormGroup form;
MyComponent() {
form = FormGroup({
'name': FormControl<String>('', Validators.required),
'email': FormControl<String>('', Validators.email),
});
}
Pipes
{{ value | date }}
{{ value | date:'fullDate' }}
{{ value | uppercase }}
{{ value | lowercase }}
{{ value | number }}
{{ value | number:'1.2-2' }}
{{ value | percent }}
{{ value | currency:'EUR' }}
{{ value | json }}
{{ value | slice:1:5 }}
{{ value | async }}
Host Bindings
@Directive(selector: '[highlight]')
class HighlightDirective {
@HostBinding('class.highlighted')
bool isHighlighted = false;
@HostBinding('style.backgroundColor')
String bgColor = 'yellow';
@HostListener('mouseenter')
void onEnter() => isHighlighted = true;
@HostListener('mouseleave')
void onLeave() => isHighlighted = false;
}
Queries
// Single child element
@ViewChild('myInput')
HtmlInputElement? inputRef;
// Multiple child elements
@ViewChildren(ChildComponent)
List<ChildComponent>? children;
// Projected content
@ContentChild(HeaderComponent)
HeaderComponent? header;
@ContentChildren(ItemDirective)
List<ItemDirective>? items;
Common Patterns
Async Data
<div *ngIf="data$ | async as data">
{{ data.name }}
</div>
Safe Navigation
{{ user?.name }}
{{ user?.address?.city }}
Non-null Assertion
{{ user!.name }}