In a previous post, we explored the starter files & tried understanding the concepts of what Angular2 modules, components & Bootstrapper are. In this post, we’ll try to create our first component, which will list employee details such as “empId”, “name”, “phone”, “email”, “salary” & “photo” & “appraisalRating”. To proceed, we’ll have to create a new folder named “emp” inside our Application root folder (i.e. inside app folder). “Emp” folders, which helps us achieve modularity (within our application) between the root application level items and “employee” items. Inside our emp folder, I’ve created a new file named “emp-list.component.ts”.
Note
In Angular2, it’s a naming convention to use “.component”, if you are creating a component. Similarly, if you are creating a directive, then the file name is appended with “.directive”.
Now, we are ready with the employee-list component declaration. The properties defined inside the class are pageTitle (for setting the page title when this component loads) & employees (which will hold dummy employee details). For now, I’ve set the employee type as “any” type, since I don’t have a model defined for it. There are various problems; if we define our model with TypeScript “any” type. Some of them are given below.
- No TypeScript IDE support for employee properties (empId, name, E-mail, phone etc.)
- No type checking; since the type is of any (any data is valid for all the properties).
- No compile time error support, when there is typo, while referencing properties in HTML markup or inside the TypeScript file.
In order to address the issue given above, we’ll create a model. Our model will have attributes “EmpId”, “name”, “E-mail”, “phone”, “salary”, “photo” & “appraisalRating”. The code snapshot is given below for the same. I’ve created a file named “employee.ts” and defined our first model i.e. IEmployee.
Note
- In TypeScript, by default, file name becomes the module/namespace name for the class/interface declared. In our case; IEmployee interface is declared inside “employee” namespace/module.
- Typescript is there to allow the class/interface to be accessible outside the namespace, which we need to export it due to which export keyword is used at our interface declaration.
Now, we are done with defining our model and we can set the type of our “employees” variable to IEmployee[] instead of “any” type in emp-list.component.ts file. For doing this, we need to import the exported IEmployee interface from its namespace. The syntax for doing this is given below.
- import {Class/Interface name} from ‘namespace name’;
In order to use IEmployee in our emp-list.component.ts file, we will do an import statement, as shown below.
- import {IEmployee} from ‘employee’;
The updated employee-list.component.ts file is given below.
- import {
- Component
- } from '@angular/core';
- import {
- IEmployee
- } from './employee';
- @Component({
- selector: 'emp-list',
- templateUrl: './emp/emp-list.component.html'
- })
- export class EmployeeListComponent {
- pageTitle: string = "Employee Details";
- imageWidth: number = 50;
- imageHeight: number = 50;
- employees: IEmployee[] = [{
- "empId": "E001",
- "name": "Leanne Graham",
- "email": "[email protected]",
- "phone": "1-770-736-8031 x56442",
- "photo": "./app/assets/imgs/face1.jpg",
- "salary": 50000,
- "appraisalRating": 4
- }, {
- "empId": "E002",
- "name": "Ervin Howell",
- "email": "[email protected]",
- "phone": "210.067.6132",
- "photo": "./app/assets/imgs/face2.jpg",
- "salary": 65000,
- "appraisalRating": 3.5
- }, {
- "empId": "E003",
- "name": "Clementine Bauch",
- "email": "[email protected]",
- "phone": "1-477-935-8478 x6430",
- "photo": "./app/assets/imgs/face3.jpg",
- "salary": 62500,
- "appraisalRating": 3.75
- }, {
- "empId": "E004",
- "name": "Patricia Lebsack",
- "email": "[email protected]",
- "phone": "(254)954-1289",
- "photo": "./app/assets/imgs/face4.png",
- "salary": 49500,
- "appraisalRating": 4.25
- }, {
- "empId": "E005",
- "name": "Chelsey Dietrich",
- "email": "[email protected]",
- "phone": "493-170-9623 x156",
- "photo": "./app/assets/imgs/face5.jpg",
- "salary": 25000,
- "appraisalRating": 3.25
- }, {
- "empId": "E006",
- "name": "Mrs. Dennis Schulist",
- "email": "[email protected]",
- "phone": "1-463-123-4447",
- "photo": "./app/assets/imgs/face6.ico",
- "salary": 100000,
- "appraisalRating": 4.5
- }, {
- "empId": "E007",
- "name": "Kurtis Weissnat",
- "email": "[email protected]",
- "phone": "010-692-6593 x09125",
- "photo": "./app/assets/imgs/face7.png",
- "salary": 36900,
- "appraisalRating": 4
- }];
- }
Now, we are done with our component; it’s time for us to define HTML markup for the same i.e. emp-list.component.html. Here, the code snippet is given for the same.
emp-list.component.html
- <div class="col-md-10 text-center">
- <table class="table table-stripped">
- <thead class="thead-inverse">
- <tr>
- <td>Emp Id</td>
- <td>Name</td>
- <td>Email</td>
- <td>Phone</td>
- <td>Salary</td>
- <td>Photo</td>
- <td>Appraisal Rating</td>
- </tr>
- </thead>
- <tbody>
- <tr *ngIf="employees.length==0">
- <td colspan="7"> No Records Found... </td>
- </tr>
- <tr *ngFor="let emp of employees">
- <td>{{emp.empId}}</td>
- <td>{{emp.name|uppercase}}</td>
- <td>{{emp.email|lowercase}}</td>
- <td>{{emp.phone}}</td>
- <td>{{emp.salary|currency:'INR':true:'1.2-2'}}</td>
- <td> <img [src]="emp.photo" [style.width.px]='imageWidth' [style.height.px]='imageHeight' /> </td>
- <td>{{emp.appraisalRating|number}}</td>
- </tr>
- </tbody>
- </table>
- </div>
Inside our emp-list.component.html we are simply displaying the employee details in a tabular format using some bootstrap css classes. For displaying employee photo we’ve used HTML element “img” & we are specifying the SRC attribute of it to the emp.photo. This way we are binding our Typescript class property to the SRC attribute of an img element. In Angular2, we call it “Property Binding”. This is the 2nd way of binding. The first way was using {{}} (i.e. interpolation). For property binding, the left hand side HTML attribute has to be enclosed in the box brackets. For applying image width & height, we’ve used the style attribute enclosed in box brackets and set to the property of imageWidth & imageHeight respectively.
Also, for iterating over the employees[] defined in our TypeScript class, we’ve used *ngFor structural Directive of Angular2. It will create a local emp variable for each element inside the employees[]. To make it look like real environment, we can check whether the employee details contains any record or not; if not then display “No Records Found” message on the screen. To do this, we make use of another Angular2 structural directive i.e. *ngIf, which is similar to Angular 1.x ng-if Directive.
We’ll use “emp-list” (i.e. selector defined in @Component({}) of emp-list.component.ts) inside our app.component.ts. Here, the updated code for app.component.ts is given below.
- import {
- Component
- } from '@angular/core';
- @Component({
- selector: 'my-app',
- template: `<emp-list></emp-list>`
- })
- export class AppComponent {}
To run & test our newly created emp-list component, we are still left with registering it with the @NgModule({}) in our app.module.ts. To register, we simply need to import the “EmployeeListComponent” in our app.module.ts file and add it inside the declarations[] of @NgModule({}). The updated code of app.module.ts file is given below.
-
- import {
- NgModule
- } from '@angular/core';
- import {
- BrowserModule
- } from '@angular/platform-browser';
-
- import {
- AppComponent
- } from './app.component';
- import {
- EmployeeListComponent
- } from './emp/emp-list.component';
- @NgModule({
- imports: [BrowserModule],
- declarations: [AppComponent, EmployeeListComponent],
- bootstrap: [AppComponent]
- })
- export class AppModule {}
Now, we are in a position to run the Application and test how the component loads. To run it, press “CTRL+SHIFT+C”. This command will open the command prompt. Type “npm start” on it.
You’ll get the below output.
Our data is displayed correctly although it’s not formatted well. To format it, we can make use of Angular pipes or filters. Angular2 comes with in-built pipes and some of them are DatePipe, UpperCasePipe, LowerCasePipe, CurrencyPipe & PercentPipe. These all pipes can be used in any template, wherever required. Some of these pipes accept input parameters. For example, date pipe allows you to provide date format, while applying the date filter on the data.
- {{ birthday | date:"MM/dd/yy" }}
We’ll format our employee name in upper case, E-mail in lower case & salary in currency. Below are the changes made in emp-list.component.html.
For currency filter, we are passing the input parameters. If you don’t pass these parameters, it will display currency in $, which is the default one, but to localize it, we need to tell Angular by passing the input parameters. For passing multiple parameters, we make use of “:”. Syntax
- {{emp.salary|currency:'INR':true:'1.2-2'}}
Here,
INR
denotes the currency.
‘true’ (which is 2nd parameter separated by “:” ) to display the currency symbol instead of abbreviation INR.
‘1.2-2’ (which is 3rd parameter separated by “:” ) for telling Angular that before decimal, we need at-least one digit and after decimal, the max & min no of digits could be at-least 2.
Here is our update output.
Our desired output is achieved.
In our next post, we’ll continue further. Until that time, you can download the solution and test it locally at your end. I’m uploading the solution with this post; but I won’t be able to upload the node_modules folder cz of heavy size. Hence, it is requested that you do npm install before you run the application after downloading the solution.