- CLI
- Decorators
- Components
- Modules
- Directives
- Data Binding
- Local Templates
<ng-template>
- Pipes
- Forms
- Services
- HTTP
- Routing
- Deep Dive
ng serve --port <port no> --host <host name>
ng g c mymodule/<component name> -m <module name>
ng g m <module name> --routing
-d
reports actions without writing results.-it
inline template-is
inline css--style=
css|scss|sass|less|styl-S
do not create spec files--flat=true
do not create a folder-c OnPush
change detection strategyng add
- adds npm package to your workspace
- and configures the project to use that library
- as specified by the library's schematic.
Metadata about the actual code
https://angular.io/api/core/Component
imports
- to import another modules to use.
declarations
- Declares what is inside this module (Components, Pipes)
bootsrap
- Which componet is the first one that should displayed in the UI. I.e., the startup component
exports
- Make sure anyone else imports this module, gets access to these exported components.
providers
- providing services (like exporting components)
- any modules that load under the root module, will have access to the providers (publicly available)
dependency injection in angular. https://angular.io/api/core/Injectable
ngOnInit
The place where we initialize the component with data
Group of related components.
Any components need to be declared in a module.
The root module needs to know about child modules.
Make a shared module if you have shared features e.g., components, pipes, directives, that you may reuse throughout the app.
BrowserModule
- The place where directives live.
- imported in the root module.
CommonModule
- Imported into child modules, instead of
BrowserModule
- Imported into child modules, instead of
FormsModule
- ngFor
<div *ngFor="let one of many"> {{ one.name }}</div>
- ngIf
- a way to add or remove an element form the DOM
<div *ngIf="data">{{ data.title }}</div>
else
https://angular.io/api/common/NgIf#showing-an-alternative-template-using-else
- ngClass
- add or remove multiple css classes
<div [ngClass]="{active: isActive, empty:isEmpty}"></div>
- ngStyle
- ngModel
- Use with elements that accept the user input
<input type="text" [(ngModel)]="title" name="title" />
- Always set the
name
property wherever you usengModel
Get data moved from code into tamplate and also handle events.
- interpolation to write a value
- {{ x.name }}
- property binding
- binding to a DOM property
[hidden]="!isVisible"
[disabled]="!isEnabled"
[class.active]="isActive"
[style.color]="textColor"
[innerHtml]="details"
- the same as {{ details }}
- event binding
(click)="toggleVisible()"
- or
on-click="toggleVisible()"
- or
- Two-way binding
[(ngModel)]="post.title"
- it will also handle input event and update
post.title
- it will also handle input event and update
a way to pass a property value into a child component. make the child accepts input form the parent. get data from a parent down into a child
- Use ngOnChanges if we have a lot of properties we want to monitor when that data changes for these props,
@Input() data: Any[]; ngOnChanges(changes: SimpleChanges) {/* check for changes*/} // https://angular.io/api/core/OnChanges
- getters and setters another technique that can be used if we only have one property to check
// child.component.ts private _posts: Post[] = []; // only put the @Input() decorator on one of (get or set) @input() get posts(): Post[] { return this._posts; } // a way to capture when it is being set to value set posts(value: Post[]) { if(value) { _posts = value; /* do something */ } }
<!-- parent.component.html --> <app-posts [posts]="blogPosts"></app-posts>
emit data from a child back up to a parent.
EventEmitter<T>
a way for a child to send data to a parent
// child.component.ts
@Component({
selector:'app-search',
template:`
// <input type="text" [value]="search" (input)="$event.target.value />
<input type="text" [(ngModel)]="search name="search"" /> <!-- Easier way. from FormsModule -->
`
})
private _search: string;
get search() { return this._search }
set search(value: string) {
this.value = value;
this.changed.emit(this.search); // emit search value up to the parent
}
@output changed = new EventEmitter<string>();
<!-- parent.component.html -->
<!-- angular automatically extract the data from $event and pass it to the function -->
<app-search (changed)="myFun($event)"></app-search>
Local template variable: With it, we can reference a particular DOM element in the rest of the component template.
<h1 *ngIF="selection; else elseBlock">{{selection}}</h1>
<!-- a way to declare a local template variable is by using (#) #myVar -->
<ng-template #elseBlock>Please select</ng-template>
Format the data as we bind it out to the UI.
https://angular.io/api?type=pipe
price | currency:'USD':<'symbol', 'code'>
- if currency code is not passed, the browser default will be used
we need
@Pipe({ name: echo})
decoratorname
which you use in the view
- implement
PipeTransform
interface- implement
transform(value: any){ return value; }
function
- implement
- register it in a module
declarations: [EchoPipe], exports: [EchoPipe]
When dealing with a form, start with an empty object that you can bind to, until you have a selected object that you're going to edit.
Template forms versus reactive forms -> https://angular.io/guide/forms-overview#choosing-an-approach
create a local template variable =ngForm
- When we create a form element, Under the hood,
- Angular will create a form control to monitor what is happening with the form
- (keep track of the values of the form and valid state of it)
When using a submit button, bind to the form submit event <form (sumbit)="save()">
,
instead of binding to that button click event.
A singleton. Introduction to services and dependency injection
Inject services into components. https://angular.io/guide/dependency-injection
Instruct Angular to inject the dependencies of a component into its constructor.
When we set an access modifier on a parameter in a constructor of a class, TypeScript will automatically assign it to a memebr of that class.
Calling the server with HttpClient. https://angular.io/guide/http
https://angular.io/api/common/http/HttpClient
- https://angular.io/guide/observables-in-angular
- Create observable, and subscribe to it
- and once the data comes back from the server,
then the subscription will end - and we can unsubscribe.
- NOTICE Web socets differs.
- We can convert observables to promises.
- Using observables to pass values
- Practical observable usage
catchError
- put catchError(myErrorHandler) operator inside
.pipe()
to handle errors
- put catchError(myErrorHandler) operator inside
map
,reduce
- We can operate, select, filter, the response data.
debounceTime
takeUntil
- Common operators
// DataService.ts
@Injectable()
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable<any[]> {
return this.http.get<any[]>('data/')
.pipe(
map(data => data.rows || []),
catchError(Observable.throw)
);
}
}
// component.ts
data: any[];
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.getData()
.subsrcibe((data: any[]) => this.data = data);
}
[ Optinal ] helps us avoid typos as we define our routes.
- path
path: ''
match the root of the websitepath: '**'
match anything
- pathMatch
pathMatch: 'full'
match on everything after the domain
- redirectTo
redirectTo: '/app-route'
- component
{ path: 'products', component: ProductsComponent }
- pass data to the component
-
//producs-routing.module.ts const routes: Routes = [ { path: 'products', component: ProductsComponent, data: {...data} } ];
-
// products.component.ts data$: Observable<any>; constructor(private route: ActivatedRoute) {} ngOnInit() { this.data$ = this.route.data; }
-
To register routes
imports: [ RouterModule.forRoot(myRoutes) ]
forRoot
is called one time in the app.
imports: [ RouterModule.forChild(routes) ]
another option for children.
Use it to get URL/query parameters.
paramMap
- to subscribe to the parameters. It would notify us any time that the ParamMap changes.
- Tip: Can be used if our components stay visible on the screen while the URL changes.
snapshot.paramMap
- If we want to grap the parameter once.
Use with anchor tags <a>
to link to a route.
<a [routerLink]="['/orders', order.id]">{{order.title}}</a>
['/orders', order.id]
mapped to'/orders/:id'
routerLinkActive="css-class"
- Detect and attach a CSS class to the element that is attached to the active route.
// header.component.ts
// template: `<button (click)="logout()">Logout</button>`
constructor(private router: Router) {}
logout() {
// logic
this.router.navigateByUrl('/login');
}
-
RouterModule.
forRoot(myRoutes)
vsforChild(myRoutes)
- We want to have only a single routing service to handle the application routes
foorRoot
will load the routing service besides all of the routes.- Inside child routing modules, for lazy loading childs, we want to use
forChild
,
because it is not going to load the routing servive, so we won't to override the routing service.
-
loadChildren
: Creating a separate bundle for a particular module and lazy loading it into the application- use
loadChildren
, it performs asynchronous call to load whatever we give to it. e.g., a module// app-routing.module.ts -> root routing module const routes: Routes = [ { /*route 1*/ }, { path: 'user', loadChildren: () => import('./user.module').then(module => module.UserModule) }, // {...}, ];
// user-routing.module.ts -> child routing module // NOTE: paths here will be relative the the parent (root) routing module. // And every child inside this (user) routing module will treat it as its root const routes: Routes = [ { path: '', component: UserComponent }, ];
- use
- Constructor vs ngOnInit
- [(ngModel)] vs [ngModel]
- What is the difference between Promises and Observables?
- Difference between [] and {{}} for binding state to property?
- Hooking into the component lifecycle
- Loading indication in Angular
- Simple state management in Angular with only Services and RxJS
- BehaviorSubject vs Observable?
- Preventing Memory Leaks in Angular Observables with ngOnDestroy
- Understanding Change Detection Strategy in Angular
- Angular CLI: Custom webpack Config
- Using Tailwind CSS Framework with Angular (custom webpack config in practice)
- How and when to unsubscribe in a component
- RxJS: Don’t Unsubscribe
- Build-specific configuration options: Configure target-specific file replacements