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.

sahosoft-Tutorials-FactoryProvider-useFactory

download demo source code

Factory Provider: useFactory