Suggested Videos
Part 22 - Angular component output properties | Text | Slides
Part 23 - Interfaces in Angular 2 | Text | Slides
Part 24 - Angular component lifecycle hooks | Text | Slides
In this video we will discuss
Why do we need a service in Angular
A service in Angular is generally used when you need to reuse data or logic across multiple components. Anytime you see logic or data-access duplicated across multiple components, think about refactoring that piece of logic or data-access code into a service. Using a service ensures we are not violating one of the Software principles - DRY ((Don't repeat yourself). The logic or data access is implemented once in a service, and the service can be used across all the components in our application.
Without the service you would have to repeat your code in each component. Imagine the overhead in terms of time and effort required to develop, debug, test and maintain the duplicated code across multiple places instead of having that duplicated code at one central place like a service and reusing that service where required.
Creating a service in Angular : We will be working with the same example that we have been working with so far in this video series. Add a new TypeScript file to the "employee" folder and name it employee.service.ts. Copy and paste the following code. At the moment we have the data hard-coded in the service method. In a later video we will discuss retrieving data from a remote server using HTTP.
Injecting and using the service : We need the employee service we created above in EmployeeListComponent. So let's import, register and use the Employee service in EmployeeListComponent as shown below.
Please do not forget to use the EmployeeListComponent selector (list-employee) as a directive in the root component - AppComponent (app.component.ts) as shown below.
At this point, run the application and notice it works exactly the same way as before.
The following line of code which calls the service, can be placed even in the constructor and the application still works exactly the same way as before. So what is the difference between a constructor and ngOnInit life cycle hook, and when to use one over the other.
this.employees = this._employeeService.getEmployees();
Difference between constructor and ngOnInit
A class constructor is automatically called when an instance of the class is created. It is generally used to initialise the fields of the class and it's sub classes.
ngOnInit is a life cycle hook method provided by Angular. ngOnInit is called after the constructor and is generally used to perform tasks related to Angular bindings. For example, ngOnInit is the right place to call a service method to fetch data from a remote server. We can also do the same using a class constructor, but the general rule of thumb is, tasks that are time consuming should use ngOnInit instead of the constructor. As fetching data from a remote server is time consuming, the better place for calling the service method is ngOnInit.
So coming back to our example, the dependency injection is done using the class constructor and the actual service method call is issued from ngOnInit life cycle hook as shown below
constructor(private _employeeService: EmployeeService) { }
ngOnInit() {
this.employees = this._employeeService.getEmployees();
}
In our next video we will discuss retrieving data from a remote server using HTTP.
Part 22 - Angular component output properties | Text | Slides
Part 23 - Interfaces in Angular 2 | Text | Slides
Part 24 - Angular component lifecycle hooks | Text | Slides
In this video we will discuss
- Why we need a service in Angular
- Creating a service in Angular
- Injecting and using the service
- Difference between constructor and ngOnInit
Why do we need a service in Angular
A service in Angular is generally used when you need to reuse data or logic across multiple components. Anytime you see logic or data-access duplicated across multiple components, think about refactoring that piece of logic or data-access code into a service. Using a service ensures we are not violating one of the Software principles - DRY ((Don't repeat yourself). The logic or data access is implemented once in a service, and the service can be used across all the components in our application.
Without the service you would have to repeat your code in each component. Imagine the overhead in terms of time and effort required to develop, debug, test and maintain the duplicated code across multiple places instead of having that duplicated code at one central place like a service and reusing that service where required.
Creating a service in Angular : We will be working with the same example that we have been working with so far in this video series. Add a new TypeScript file to the "employee" folder and name it employee.service.ts. Copy and paste the following code. At the moment we have the data hard-coded in the service method. In a later video we will discuss retrieving data from a remote server using HTTP.
import { Injectable } from '@angular/core';
import { IEmployee } from './employee';
// The
@Injectable() decorator is used to inject other dependencies
// into
this service. As our service does not have any dependencies
// at the
moment, we may remove the @Injectable() decorator and the
//
service works exactly the same way. However, Angular recomends
// to
always use @Injectable() decorator to ensures consistency
@Injectable()
export class
EmployeeService {
getEmployees(): IEmployee[] {
return [
{
code: 'emp101', name: 'Tom', gender: 'Male',
annualSalary: 5500,
dateOfBirth: '6/25/1988'
},
{
code: 'emp102', name: 'Alex', gender: 'Male',
annualSalary: 5700.95, dateOfBirth: '9/6/1982'
},
{
code: 'emp103', name: 'Mike', gender: 'Male',
annualSalary: 5900,
dateOfBirth: '12/8/1979'
},
{
code: 'emp104', name: 'Mary', gender: 'Female',
annualSalary: 6500.826,
dateOfBirth: '10/14/1980'
},
{
code: 'emp105', name: 'Nancy', gender: 'Female',
annualSalary: 6700.826,
dateOfBirth: '12/15/1982'
},
{
code: 'emp106', name: 'Steve', gender: 'Male',
annualSalary: 7700.481,
dateOfBirth: '11/18/1979'
},
];
}
}
Injecting and using the service : We need the employee service we created above in EmployeeListComponent. So let's import, register and use the Employee service in EmployeeListComponent as shown below.
// Import
OnInit Life Cycle Hook interface
import { Component, OnInit } from '@angular/core';
import { IEmployee } from './employee';
// Import
EmployeeService
import { EmployeeService } from './employee.service';
@Component({
selector: 'list-employee',
templateUrl: 'app/employee/employeeList.component.html',
styleUrls: ['app/employee/employeeList.component.css'],
// Register
EmployeeService in this component by
// declaring it
in the providers array
providers: [EmployeeService]
})
// Make
the class implement OnInit interface
export class
EmployeeListComponent implements OnInit {
employees: IEmployee[];
selectedEmployeeCountRadioButton: string = 'All';
// Inject
EmployeeService using the constructor
// The private
variable _employeeService which points to
//
EmployeeService singelton instance is then available
// throughout
this class
constructor(private
_employeeService: EmployeeService) {
}
// In
ngOnInit() life cycle hook call the getEmployees()
// service
method of EmployeeService using the private
// variable
_employeeService
ngOnInit() {
this.employees = this._employeeService.getEmployees();
}
getTotalEmployeesCount(): number {
return this.employees.length;
}
getTotalMaleEmployeesCount(): number {
return this.employees
.filter(e => e.gender === 'Male').length;
}
getTotalFemaleEmployeesCount(): number {
return this.employees.filter(e
=> e.gender === 'Female').length;
}
onEmployeeCountRadioButtonChange(selectedRadioButtonValue: string): void {
this.selectedEmployeeCountRadioButton = selectedRadioButtonValue;
}
}
Please do not forget to use the EmployeeListComponent selector (list-employee) as a directive in the root component - AppComponent (app.component.ts) as shown below.
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `<list-employee></list-employee>`
})
export class
AppComponent {
}
At this point, run the application and notice it works exactly the same way as before.
The following line of code which calls the service, can be placed even in the constructor and the application still works exactly the same way as before. So what is the difference between a constructor and ngOnInit life cycle hook, and when to use one over the other.
this.employees = this._employeeService.getEmployees();
Difference between constructor and ngOnInit
A class constructor is automatically called when an instance of the class is created. It is generally used to initialise the fields of the class and it's sub classes.
ngOnInit is a life cycle hook method provided by Angular. ngOnInit is called after the constructor and is generally used to perform tasks related to Angular bindings. For example, ngOnInit is the right place to call a service method to fetch data from a remote server. We can also do the same using a class constructor, but the general rule of thumb is, tasks that are time consuming should use ngOnInit instead of the constructor. As fetching data from a remote server is time consuming, the better place for calling the service method is ngOnInit.
So coming back to our example, the dependency injection is done using the class constructor and the actual service method call is issued from ngOnInit life cycle hook as shown below
constructor(private _employeeService: EmployeeService) { }
ngOnInit() {
this.employees = this._employeeService.getEmployees();
}
In our next video we will discuss retrieving data from a remote server using HTTP.
I am getting following error. Please help
ReplyDeleteERROR TypeError: _co.getMaleEmployeesCount is not a function
at Object.eval [as updateDirectives] (EmployeeListComponent.html:2)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13093)
at checkAndUpdateView (core.es5.js:12270)
at callViewAction (core.es5.js:12638)
at execComponentViewsAction (core.es5.js:12570)
at checkAndUpdateView (core.es5.js:12276)
at callViewAction (core.es5.js:12638)
at execComponentViewsAction (core.es5.js:12570)
at checkAndUpdateView (core.es5.js:12276)
at callWithDebugContext (core.es5.js:13493)
Issue resolved. Just restarted vs code.
ReplyDelete