Factory Provider: useFactory
As we know that Angular provides different types of providers such as class provider
,
alias provider
, value provider
and factory provider
.
So in this article we will learn about Factory provider step by step with
example.
useFactory
configures a factory provider that returns object for dependency
injection. It is used as follows.
providers: [ CourseService, { provide: Course, useValue: Course_BOOK }, { provide: Prefered_Courses, useFactory: preferredCoursesFactory(4), deps: [Course, CourseService] } ]
Find the definition of the attribute used in the previous code snippet.
provide: configure the token that will be used in dependency injection.
useFactory: configures a factory method that can return objects, string, array, etc.
deps: configures the token that the injector will use to provide the dependency injection required by the factory method.
Now we will create an example for Factory Provider: useFactory and Folder structure for this example as shown below.
src ├── app │ ├── course.ts │ ├── course.service.ts │ ├── course.component.ts │ ├── preferred-courses.ts │ ├── app.component.ts │ ├── app.module.ts
course.ts
export class Course { constructor(public name: string, public category: string){} }
course.service.ts
import { Injectable } from '@angular/core'; import { Course } from './course' const Courses: Course[] = [ {"name": "Angular 7", "category": "Angular"}, {"name": "Node Js", "category": "Node js"}, {"name": "Angular 6", "category": "Angular"}, {"name": "Sql Server 2008 r2", "category": "Sql Server"}, {"name": "Angular 5", "category": "Angular"}, {"name": "Angular 4", "category": "Angular"}, {"name": "Html 5", "category": "Html"}, {"name": "Angular 2", "category": "Angular"}, ]; @Injectable() export class CourseService { getAllCourses(): Course[] { return Courses; } }
course.component.ts
import { Component, OnInit, InjectionToken, Inject } from '@angular/core'; import { Course } from './course'; import { CourseService } from './course.service'; import { Prefered_Courses, preferredCoursesFactory } from './preferred-courses' const Course_Book = new Course('Angular js', 'Angular'); @Component({ selector: 'course', providers: [ CourseService, { provide: Course, useValue: Course_Book }, { provide: Prefered_Courses, useFactory: preferredCoursesFactory(4), deps: [Course, CourseService] } ], template: ` <h3>Preferred Courses</h3> {{preferredCourses}} ` }) export class CourseComponent implements OnInit { constructor(@Inject(Prefered_Courses) private preferredCourses: string) { } ngOnInit() { } }
preferred-courses.ts
import { InjectionToken } from '@angular/core'; import { Course } from './course'; import { CourseService } from './course.service'; export const Prefered_Courses = new InjectionToken<string>('course name'); export function preferredCoursesFactory(count: number) { return (myCourse: Course, courseService: CourseService): string => { return courseService .getAllCourses() .filter( course => course.category === myCourse.category) .map(course => course.name) .slice(0, Math.max(0, count)) .join(' | '); }; };
The dependency injection of Course and CourseService arguments in factory method is picked up by injector from deps configuration given below.
{ provide: Prefered_Courses, useFactory: preferredCoursesFactory(4), deps: [Course, CourseService] }
The value passed in preferredCoursesFactory() as argument is the count of courses returned by our factory method.app.component.ts
app.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <course></course> ` }) export class AppComponent { }
app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { CourseComponent } from './course.component'; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent, CourseComponent, ], providers: [ ], bootstrap: [ AppComponent ] }) export class AppModule { }
when you run the application, you will get the output as shown below.
download demo source code
Factory Provider: useFactory