HI WELCOME TO SIRIS
Showing posts with label angular. Show all posts
Showing posts with label angular. Show all posts

How routing works in angular

Leave a Comment

As you have seen in our previous video, there are many small steps that you have to remember, to implement routing correctly in an angular application. Let's quickly recap those steps.


Step 1 : Set <base href> in index.html.

Step 2 : Import the RouterModule into the application root module AppModule.

Step 3 : Configure the application routes. 

Step 4 : Specify where you want the routed component view template to be displayed using the <router-outlet> directive

Step 5 : Create a navigation menu and tie the configured routes with the menu using the routerLink directive. Optionally, use the routerLinkActive directive to style the current route that is active, so the user knows the page that he is on, in the application.

Now, let's connect all these small steps and see how routing actually works.

1. We have built the "Home" and "Employees" links using the RouterLink directive. The RouterLink directive  tells the angular router where to navigate when the respective links are clicked. So for example, when we click on the "Home" link, the angular Router includes '/home' in the URL.

2. When the URL changes the angular router looks for the corresponding route in the route configuration. In this case the URL changed to /home, so the router looks for the home route. We have the 'home' route already configured. In the route configuration, we have specified to use the HomeComponent.

3. So the angular router knows to display the HomeComponent view template, but the question is where should the HomeComponent view template be displayed.

4. At this point, the Angular router looks for the <router-outlet> directive. The home component view template is then displayed at the location where we have the <router-outlet> directive. In our case, we placed the <router-outlet> directive in the root component (AppComponent) because that is the top level component where we want our routed component templates to be displayed.

5. We specified 'app-root' as the selector for the root component (AppComponent). This selector (app-root) is used as a directive in the application host page i.e index.html. So along with the navigation menu HTML that we already have in the root component, the HomeComponent view template is also display in index.html page.

6 . Now when we click on the "Employees" link, Steps 1 to 5 happen in the order specified and the HomeComponent view template is replaced with the EmployeesComponent view template.

Hope you are now able to connect all the dots and have a good understanding of all the small steps of implementing routing in an angular application.

Please note : When configuring routes in our previous video, we imported Routes type from '@angular/router'. If you look at the definition of Routes type, it is actually an array of Route objects. This Routes type is not required for the application to work. Even if we remove the Routes type declaration from appRoutes as shown below, the application routing works exactly the same way as before. However, using it provides us compile time checking if we mis-spell the properties of the Route object.

Notice the type declaration : Routes is removed from appRoutes constant
const appRoutes = [
  { path: 'home', component: HomeComponent },
  { path: 'employees', component: EmployeesComponent },
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

At the moment routing is implemented in the root AppModule. However, for separation of concerns and maintainability, it is better to implement routing in a separate Routing module and then import that routing module in the AppModule. In our next video, we will discuss how to move routing into a separate routing module. 

Angular Routing

Leave a Comment

Implementing routing in an Angular application involves many small steps. Angular CLI does a pretty good job in having some of these routing steps implemented out of the box by just using --routing option.


Before we discuss, how we can use Angular CLI to implement routing let's setup routing manually so we understand all the moving parts as far as implementing routing is concerned.

Using the following command, first create a brand new Angular project using the Angular CLI. 
ng new employeeManagement

We named it employeeManagement. Let's assume we are using this application to manage employees. Out of the box, Angular CLI has created the root component - AppComponent. In addition let's create the components in the table below. The table shows the component name, it's purpose and the routes we are going to use to get to these components.
ComponentPurposeRoute
homeThis is the home component/home
employeesThis component displays the list of employees/employees
pageNotFoundThis component is used when a user tries to navigate to a route that does not exist/nonExistingRoute

Let's generate the above components using Angular CLI. Use the following commands to generate the components. Angular CLI not only generates these components, it also imports and registers the components in the root module.
ComponentCommand
homeng g c home
employeesng g c employees
pageNotFoundng g c pageNotFound

At this point execute the following Angular CLI command
ng serve --open

This builds and launches the application and you will see the following page.
angular routing explained

Here are the steps to implement routing in Angular
Step 1 : Set <base href> in the application host page which is index.html. The <base href> tells the angular router how to compose navigation URLs. This is already done for us by the Angular CLI, when we created this project.

<base href="/">

Step 2 : Import the RouterModule into the application root module AppModule. The Router Module contains the Router service and Router directives such as (RouterLink, RouterLinkActive, RouterOutlet etc). So for us to be able to implement routing, we first need to import the Router Module in our AppModule. So in app.module.ts make the following 2 changes

// Import RouterModule
import { RouterModule } from '@angular/router';

// Include RouterModule in the "imports" array of the @NgModule() decorator
@NgModule({
  declarations: [...
  ],
  imports: [
    BrowserModule,
    RouterModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Step 3 : Configure the application routes. 

To configure routes, we first need to import Routes type from '@angular/router'. If you look at the definition of Routes type, it is actually an array of Route objects. This Routes type is not required for the application to work. However, using it provides us intellisense and compile time checking. For example, mis-spelled properties of the Route object will be reported as errors.

import { RouterModuleRoutes } from '@angular/router';

// Each route maps a URL path to a component
// The 3rd route specifies the route to redirect to if the path
// is empty. In our case we are redirecting to /home
// The 4th route (**) is the wildcard route. This route is used
// if the requested URL doesn't match any other routes already defined
const appRoutesRoutes = [
  { path: 'home'component: HomeComponent },
  { path: 'employees'component: EmployeesComponent },
  { path: ''redirectTo: '/home'pathMatch: 'full' },
  { path: '**'component: PageNotFoundComponent }
];

// To let the router know about the routes configured above,
// pass "appRoutes" constant to forRoot(appRoutes) method
// We also have forChild() method. We will discuss the difference
// and when to use one over the other in our upcoming videos
@NgModule({
declarations: [...
],
imports: [
  BrowserModule,
  RouterModule.forRoot(appRoutes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Step 4 : Specify where you want the routed component view template to be displayed using the <router-outlet> directive. In our case we want them to be displayed in the root component AppComponent. So in the root component view template i.e in app.component.html, replace all the existing HTML with <router-outlet></router-outlet>

At this point we should have routing working in our application. Build and run the application using the Angular CLI command : ng serve --open
  • Notice the URL in the browser. We have /home in the URL and we see 'home works'! displayed.
  • Now in the URL remove '/home', and type '/employees' and press the enter key. Notice the message 'employees works!' is displayed.
  • Now in the URL remove '/employees', and type '/abc' and press the enter key. '/abc' is not a valid route so the message 'page-not-found works!' is displayed.
  • Now remove '/abc' from the URL and press the enter key. Notice we are redirected to '/home' (the default route) and 'home works'! is displayed.
Step 5 : Tie the routes to application menu. Routing is working as expected, but we have to manually type the URL in the address bar. Instead let's include links to our home and employees routes. Let's do this in the Root component(AppComponent). Include the following HTML in app.component.html.

The routerLink directive tells the router where to navigate when the user clicks the link.
The routerLinkActive directive is used to add the active bootstrap class to the HTML navigation element whose route matches the active route.

<div style="padding:5px">
    <ul class="nav nav-tabs">
        <li routerLinkActive="active">
            <a routerLink="home">Home</a>
        </li>
        <li routerLinkActive="active">
            <a routerLink="employees">Employees</a>
        </li>
    </ul>
    <br/>
    <router-outlet></router-outlet>
</div>

We are using Bootstrap nav component to create the menu. We discussed Bootstrap nav component in Part 27 of Bootstrap tutorial. To install bootstrap execute the following npm command
npm install bootstrap@3 --save

Once Bootstrap is installed, open .angular-cli.json file and specify the path to the Bootstrap stylesheet in the styles property as shown below.
"styles": [
  "../node_modules/bootstrap/dist/css/bootstrap.min.css",
  "styles.css"]

At this point build and run the application using the following Angular CLI command. Routing should be working as expected.

ng serve --open

The following are the directives provided by the RouterModule

routerLink
Tells the router where to navigate when the user clicks the navigation link

routerLinkActive 
  • When a route is active the routerLinkActive directive adds the active CSS class. When a route becomes inactive, the routerLinkActive directive removes the active CSS class. 
  • The routerLinkActive directive can be applied on the link element itself or it's parent. In this example, for the active route styling to work correctly, routerLinkActive directive must be applied on the <li> element and not the <a> element.
router-outlet
Specifies the location at which the routed component view template should be displayed 

At the moment routing is implemented in the root module - AppModule. However, for separation of concerns and maintainability, it is better to implement routing in a separate Routing module and then import that routing module in the AppModule. In a later video, we will discuss how to move routing into it's own routing module. 

As we have seen throughout this video, there are many moving parts that we have to remember, to implement routing correctly in an angular application. In our next video, we will discuss, the routing workflow and how routing actually works in Angular, by connecting all these little moving parts.

TSLint in Visual Studio Code

Leave a Comment


At the moment, our editor Visual Studio Code does not show linting errors. It would be nice if Visual Studio Code can display these linting errors so we can fix them as we are writing code. To achieve this install Visual Studio Code extension - TSLint.


To install this extension
  1. Click on the "View" menu in "Visual Studio Code" and select "Extensions" from the context menu
  2. In the "Search Extensions in Marketplace" textbox type TSLint install tslint in visual studio code
  3. Click the "install" button
  4. Once installed, restart Visual Studio Code to activate TSLint
At this point, in Visual Studio Code we will be able to see linting errors and we have the opportunity to fix them as we are developing our application.
visual studio code lint plugin

Once you click on the line where you see a linting error, a light bulb appears on the left margin and when you click on the light bulb you will see 1 to 3 options
visual studio code typescript lint

You can click on the respective options
  1. To have the linting errors fixed automatically depending on whether the issue supports automatic fix or not
  2. To disable that specific rule
  3. To get documentation of the rule
To disable linting in VS code
  1. Click on the "View" menu in "Visual Studi Code" and select "Extensions" from the context menu
  2. In the "EXTENSIONS" window, expand "INSTALLED" section
  3. Click the "SETTINGS" icon against TSLint extension
  4. Select "Disable (Always)" option disable vs code linting
  5. Restart Visual Studio Code

Angular tslint rules

Leave a Comment

In this video we will discuss some of the common angular linting rules in tslint.json file. You may modify these rules depending on your project requirements.


Here are some of the common linting rules
  • quotemark rule specifies whether you want single or double quotes
  • no-trailing-whitespace rule disallows trailing whitespace at the end of a line
  • semicolon rule specifies that a line should be terminated with a semicolon
  • comment-format rule specifies that all single-line comments must begin with a space
  • component-class-suffix rule enforces that a component class should end with the suffix Component
  • use-life-cycle-interface rule enforces that you add the implements keyword for every lifecycle hook you use

Some of the linting errors support automatic fix. To have these linting errors fixed automatically, run ng lint command with the --fix option.
ng lint --fix

To see the options that can be used with ng lint command, use
ng lint --help

At the moment, Visual Studio Code is not able to show any linting rule violations. In our next video, we will discuss how to display linting errors in Visual Studio Code so we can fix them as we are writing code.

Linting TypeScript

Leave a Comment

Angular has a linting tool that checks our TypeScript code for programmatic and stylistic errors as well as non-adherence to coding standards and conventions. tslint.json is the configuration file for linting. This file contains all the default rules for linting our code.



For the purpose of this demo I have created a brand new Angular project using the following command.
ng new AngularProject

Use the following command to lint the code
ng lint


Since we have just generated a new angular project and all the code in the project is auto-generated, we do not have any linting errors and we get the message - All files pass linting.

We also see the following warning
Warning: The 'no-use-before-declare' rule requires type checking

Basically this warning is saying, if 'no-use-before-declare' rule is enabled we need to use --type-check option with the ng lint command
ng lint --type-check

'no-use-before-declare' rule is enabled out of the box and it disallows usage of variables before their declaration. To understand what this means, place the following sayHello() function in AppComponent class in app.component.ts file.

sayHello() {
  var message = 'Hello';
  message = message + ' Pragim';
  console.log(message);
}

At this point, execute ng lint command again with --type-check option. 

ERROR: C:/AngularProject/src/app/app.component.ts[12, 17]: variable 'message' used before declaration
ERROR: C:/AngularProject/src/app/app.component.ts[13, 5]: Forbidden 'var' keyword, use 'let' or 'const' instead

Lint errors found in the listed files.

Out of the box, "no-var-keyword" rule is also enabled by default. Turn this rule off by setting it's value to false in tslint.json
"no-var-keyword"true

Run ng lint command again with --type-check option

Notice, now we only get 1 linting error
variable 'message' used before declaration

Now modify the code in sayHello() function as shown below.

sayHello() {
  var message = 'Hello';
  message = message + ' Pragim';
  console.log(message);
}

Run ng lint command again with --type-check option. Notice now we do not get any linting errors.

Variables declared with let keyword are not accessible before they are declared. So this rule 'no-use-before-declare' can be safely disabled, if you have 'no-var-keyword' rule enabled. 

When 'no-use-before-declare' rule is disabled and when we run ng lint command without --type-check option, we will no longer get the below warning 
The 'no-use-before-declare' rule requires type checking

Angular cli generate class, interface and enum

Leave a Comment

So far we have discussed generating angular features like components, services, directives etc. We can use the Angular CLI to generate TypeScript features as well. In this video we will discuss generating TypeScript features like classes, interfaces and enumerations using the Angular CLI.


As you have seen throughout this course, Angular CLI provides consistent set of commands for generating features. 

To generate a class use
ng generate class className or ng g cl className

For example, to generate an employee class use
ng g cl employee

The above command places the employee class directly in the "app" folder. Instead if you want the employee class in a different folder, simply prefix the name of the folder. The command below creates a folder with name "employee" and then creates the "employee" class in it.
ng g cl employee/employee

By default, a spec file is not created for the class. If you want a spec file to be generated set --spec option to true.
ng g cl employee/employee --spec=true

To generate an interface use
ng generate interface interfaceName or ng g i interfaceName

To generate an enum use
ng generate enum enumName or ng g e enumName

angular cli generate directives, pipes and routing guards

Leave a Comment

In this video we will discuss generating directives, pipes and routing guards using the Angular CLI.


Generating directives, pipes, routing guards and other angular features is very similar to generating component and services. We discussed generating components and services using the Angular CLI in our previous videos in this course.

Angular FeatureComplete CommandAlias
Directiveng generate directive directiveNameng g d directiveName
Pipeng generate pipe pipeNameng g p pipeName
Routing Guardng generate guard guardNameng g g guardName

Please note : When you try to generate a directive, pipe or a component, and if you have multiple modules in your angular project you may get the following error
More than one module matches. Use skip-import option to skip importing the component into the closest module.

The reason we are getting this error is we have more than one module in our angular project, so Angular CLI does not know with which module the newly generated directive, pipe or component should be registered. So we have 2 options here.
  1. Use --skip-import option to tell Angular CLI not to import and register the generated component, directive or pipe 
    ng g d directiveName --skip-import -d
  2. Use --module option or it's alias -m to tell Angular CLI the module with which we want our newly generated component, directive or pipe should be registered. 
    ng g d directiveName -m=app.module -d
If you have just one module in your Angular project, then you wouldn't get this error, as the angular cli will automatically import and register the newly generated component, directive or pipe with that one existing module.

When generating certain angular features like services or routing guards, you will not get this error, even when you have multiple modules in your project, because by default, Angular CLI does not try to import and register these features.

Please note that we can always use the following options along with ng generate command to customize the generation of directives, pipes and routing guards using the Angular CLI.

OptionPurpose
flatSpecifies if a dedicated folder should be created
moduleSpecifies the module with which the newly generated angular feature should be registered
specSpecifies if a spec file should be generated

Angular cli generate module

Leave a Comment

In this video we will discuss generating modules using the Angular CLI. 


To generate a module use
ng generate module moduleName OR ng g m moduleName

For example to generate a students module we could use 
ng generate module students -d OR ng g m students -d

Please note : Since we are using the --dry-run flag, the module file and folder is not actually created. We only get the report of the files and folders that will be created.

The above command generates the students module inside students folder. Remember for us to be able to use this newly generated module, we must import it in the root module.

We can do it manually after creating the module or we can tell Angular CLI to import our newly generated module into the root module using --module option. We can also use it's alias -m

The following command not only generates students module, it also imports it into the root module (AppModule)
ng g m students -d -m=app.module

By default a spec file is not generated. If you also want a spec file to be generated use the --spec option
ng g m students -d -m=app.module --spec=true

When generating a module, Angular CLI by default creates a folder for the module and places the module files in that folder. If you do not want a dedicated folder for the module you are generating, use --flat option.
ng g m students -d -m=app.module --spec=true --flat=true

Unitil now, we have been using the --dry-run option. Now let's remove the -d option and execute the command so the module is actually created.
ng g m students -m=app.module --spec=true --flat=true

The above command not only creates the students module, it also imports it into the root module (AppModule). If we look inside app.module.ts file, notice
  1. The required import statement to import students module is included
  2. The students module is also included in the "imports" array

Angular cli generate service

Leave a Comment

In this video we will discuss generating services using the Angular CLI. Generating services is similar to generating components.


To generate a component we use
ng generate component componentName OR ng g c componentName 

Similarly to generate a service we use
ng generate service serviceName OR ng g s serviceName

For example, to generate a customer service we use the following command. 
ng generate service customer

The above command generates the service and the spec file. What it does not do is register the service. Remember for us to be able to use the service, we must register the service. 

We can do it manually after creating the service or we can tell Angular CLI to register our service with a module, using --module option. We can also use it's alias -m

The following command not only generates employee service, it also registers our service witht the AppModule
ng generate service employee -module=app.module

The above command can also be rewritten using aliases
ng g s employee -m=app.module

We can also use the --dry-run flag or it's alias -d to see what Angular CLI generates. Notice in the following command we are using -d option, so Angular CLI simply report the files it is going to generate

ng g s student -d

The above command generates the service and the spec file. If you do not want the spec file, simply set --spec=false

ng g s student -d --spec=false

When generating a component, Angular CLI by default creates a folder for the component and places all the component files in that folder. A service on the other hand will not have it's own folder. If you want a folder of it's own for a service that the Angular CLI is generating, set --flat option to false as shown below.

ng g s student -d --spec=false --flat=false