Create new instance of class that has dependencies, not understanding factory provider

You can provide a factory function. This is different from a simple useFactory: ... provider like

{ 
    provide: 'TestModelFactory', 
    useFactory: () => {
        return (http, config) => { 
            return new TestModel(http, config);
        };
    },
    deps: [Http, CONFIG];
}

and then use it like

@Injectable()
export class TestService {

   constructor(@Inject('TestModelFactory' testModelFactory) {}

   getTestsModels(): Observable<TestModel[]> {
        let url = this.config.apiUrl + "test";
        return this.http.get(url)
                        .map( (response) => response.json() )
                        .map( (results) => {
                            return results.map( (current) => {
                                let tm = testModelFactory();
                                tm.xxx // assign data
                            })
                        })
                        .catch(this.handleError);
    }
}

You can also support per instance parameters like

{ 
    provide: 'TestModelFactory', 
    useFactory: (json) => {
        return (http, config) => { 
            return new TestModel(http, config, json);
        };
    },
    deps: [Http, CONFIG];
}

and then use it like

@Injectable()
export class TestService {

   constructor(@Inject('TestModelFactory' testModelFactory) {}

   getTestsModels(): Observable<TestModel[]> {
        let url = this.config.apiUrl + "test";
        return this.http.get(url)
                        .map( (response) => response.json() )
                        .map( (results) => {
                            return results.map( (current) => {
                                let tm = testModelFactory(result);
                            })
                        })
                        .catch(this.handleError);
    }
}

But you don’t need to use DI. You already inject Http and CONFIG into your TestService. You can just

@Injectable()
export class TestService {

    constructor(private http: Http, @Inject(CONFIG) private config) {}

    getTestsModels(): Observable<TestModel[]> {

        let url = this.config.apiUrl + "test";

        return this.http.get(url)
                        .map( (response) => response.json() )
                        .map( (results) => {
                            return results.map( (current) => {
                                return new TestModel(http, config);
                            })
                        })
                        .catch(this.handleError);

    }

    private handleError(err): Observable<any> {

        let errMessage = err.message ? err.message : err.status ? `${err.status} - ${err.statusText}` : 'Server Error';

        return Observable.throw(new Error(errMessage));

    }
}

In every case you need to provide some way to initialize TestModel from result for example by passing the JSON to the constructor and initialize the members of TestModel from the passed JSON.

See also Angular2: How to use multiple instances of same Service?

Leave a Comment

techhipbettruvabetnorabahisbahis forumu