This section provides an overview of how to install and configure Angular2+ for use in various environments and IDE's using tools like the community developed angular-cli.
The previous version of Angular is AngularJS or also named Angular 1. See here the documentation.
This topic covers Angular2 Pipes, a mechanism for transforming and formatting data within HTML templates in an Angular2 application.
There are a few more tricks we can do with the router (such as restricting access), but those can be covered in a separate tutorial.
If you need a new route, simply modify app.routes.ts
and follow the following steps:
routes
array. Make sure to include a new path
and component
.What we do with HttpServiceLayer class is extend the Http class from angular and add our own logic to it.
We then inject that class in the bootstrap class of the application and tell angular that were we import the Http class, in the back to insert the HttpServiceLayer.
Anywhere in the code we can simply import
import { Http } from '@angular/http';
But our class will be used for each call.
The main source of information about Angular 2 directives is the official documentation https://angular.io/docs/ts/latest/guide/attribute-directives.html
It is possible to install other libraries following, this approach, however, there might be a need to specify the module type, main file, and default extension.
'lodash': {
format: 'cjs',
defaultExtension: 'js',
main: 'index.js'
}
'moment': {
main: 'moment.js'
}
AfterViewInit
and AfterViewChecked
are only available in Components, and not in Directives.
OnChanges
(multiple times)OnInit
(once)DoCheck
(multiple times)AfterContentInit
(once)AfterContentChecked
(multiple times)AfterViewInit
(once) (Component only)AfterViewChecked
(multiple times) (Component only)OnDestroy
(once)Making API requests with Angular 2 Http service and RxJS is very similar to working with promises in Angular 1.x.
Use the Http class to make requests. The Http class exposes the methods for issuing HTTP requests GET
, POST
, PUT
, DELETE
, PATCH
, HEAD
requests via corresponding methods. It also exposes a generic request
method for issuing any kind of HTTP request.
All methods of the Http
class return an Observable<Response>
, to which you can apply RxJS operations. You call the .subscribe()
method and pass in a function to be called when data is returned in the Observable stream.
The Observable stream for a request contains only one value - the Response
, and completes/settles when the HTTP request is completed succesfully, or errors/faults if an error is thrown.
Note, the observables returned by the Http
module are cold, which means if you subscribe to the observable multiple times, the originating request will be executed once for each subscription. This can happen if you want to consume the result in multiple components of your application. For GET requests this might just cause some extra requests, but this can create unexpected results if subscribe more than once to PUT or POST requests.
Angular 2 allow to access the ngForm instance by creating a local template variable. Angular 2 exposes directive instances like ngForm by specifying exportAs property of the directive metadata. Now, the advantage here is without much coding you can access the ngForm instance and use it to access submitted values or to check if all the fields are valid using properties (valid, submitted, value etc).
#f = ngForm (creates local template instance "f")
ngForm emits the event "ngSubmit" when it's submitted (Check @Output documentation for more details of event emitter)
(ngSubmit)= "login(f.value,f.submitted)"
"ngModel" creates a Form Control in combination with input "name" attribute.
<input type="text" [(ngModel)]="username" placeholder="enter username" required>
When form is submitted, f.value has the JSON object representing the submitted values.
{ username: 'Sachin', password: 'Welcome1' }
Remember that Angular 2 is all about singular responsibility. No matter how small your component is, dedicate a separate logic for each and every component. Be it a button, a fancy anchor link, a dialog header or even a sidenav's sub item.
Using Pipes relegates you to only changing attribute values like so :
<tag [attribute]="expression or variable reference | pipeName">
you are not able to use pipes this way :
<tag attribute="expression or variable reference | pipeName">
or this way
<tag attribute={{expression or variable reference | pipeName}}
this.myForm = this.formBuilder.group
creates a form object with user's configuration and assigns it to this.myForm variable.
'loginCredentials': this.formBuilder.group
method creates a group of controls which consist of a formControlName eg. login
and value ['', Validators.required],
where the first parameter is the initial value of the form input and the secons is a validator or an array of validators as in 'email': ['', [Validators.required, customValidator]],
.
'hobbies': this.formBuilder.array
Creates an array of groups where the index of the group is formGroupName in the array and is accessed like :
<div *ngFor="let hobby of myForm.find('hobbies').controls; let i = index">
<div formGroupName="{{i}}">...</div>
</div>
onAddHobby() {
(<FormArray>this.myForm.find('hobbies')).push(new FormGroup({
'hobby': new FormControl('', Validators.required)
}))
}
this sample method adds new formGroup to the array.
Currently accessing requires specifing the type of control we want to access, in this example this type is : <FormArray>
removeHobby(index: number){
(<FormArray>this.myForm.find('hobbies')).removeAt(index);
}
same rules as above apply to removing a specific form control from the array
The *ngFor
structural directive runs as a loop in a collection and repeats a piece of html for each element of a collection.
@View
decorator is now deprecated. Developers should be using template
or 'templateUrl' properties for @Component
decorator.
I mainly requested this topic because I could not find any information on setting up multiple API routes with the Angular2-In-Memory-Web-Api. Ended up figuring it out myself, and figured this might be helpful to others.
When you use a web component in your Angular 2 template, angular will try to find a component with a selector matching the custom tag of the web component - which it of course can't and will throw an error.
The solution is to import a "custom elements schema" in the module that holds the component. This will make angular accept any custom tag, that doesn't match any ng component selector.
Observer is a generic, but must be of type any
to avoid unit testing complexity. The reason for this complexity, is that Store's constructor expects Observer arguments with different generic types. Using any
avoids this complication.
It's possible to pass null values into StoreMock's super constructor, but this restricts the number of assertions that can be used to test the class further down the road.
The Component being used in this example is just being used as context for how one would go about injecting Store as a provide in the test setup.
Because Angular 2 is so modular and encapsulated you can pretty much just copy over all of your components, services, pipes, directives and then fill out the NgModule as it was in the old project.