Services
- The logic for calling http service should not be included in component
- The logic will be tightly coupled to httpendpoint
- Unable to test the logic
- Code duplication when required in another component
- Component should not include logic other than presentation logic
Creating Service
Create a class with export keyword
Suffix the class name with service
eg courses.service.ts
export class CoursesService {
getCourses() {
return ["course1", "course 2", "course 3"];
}
}
- With the service we can resuse the logic in multiple places in our application
- It will decouple the component from the logic
- Allow us to unit test the class without the dependency upon httpclient
- While unit testing we can provide the fake implementation of the class
Dependency Injection
- Consuming the service
- Tightly Coupling
constructor() {
let service = new CourseServices()
this.courses = service.getCourses();
}
- Creating the instance of the service with new keyword in the constructor will lead to tight coupling
- In future if the service constructor changes, it should be updated in all places
De-coupling
- Specify the service as depenedency in the parameter of constructor
- When angular create the component - sees the dependency - Angular will take care of instantiating the service and passing it to the component
- If the constructor of service changes no need to change in multiple places
- This will be useful when testing by passing fake implementation service
- This way component is decoupled to the service
constructor(service: CoursesService) {
service.getCourses();
}
- Dependency Injection is injecting or providing the dependencies of the class into its constructor
- Instructing angular to inject the dependencies of the component into its constructor
- Angular has dependency injection framework built in
- Register all the dependencies of the component in the providers of app module
- In app.module.ts
providers: [CoursesService]
- Register the service as a provider in this module
- If you miss this step, you will get error - No provider for CoursesService or
- In CoursesService use
@Injectable({
providedIn: 'root'
})
- Angular will create a single instance of the class in the memory for the entire module.
- Angular will pass the same instance to all the components - Singleton Pattern
Generating service using CLI
ng generate service email
ng g s email
@Injectable()
: Injectable decoration function is needed only if the service has dependency in the constructor
@Injectable()
export class EmailService {
constructor(logService: LogService){}
}
- For components, the component decorator internally includes the injectable decorator