Skyler
Skyler

Reputation: 805

use angular service vs export class for multiple instances?

I'm having trouble understanding how to handle multiple instances of a service in Angular. In the example below, I want to create multiple instances of the type Person. Since Person is not a singleton, I don't inject it. Would it make more sense to simply import it as a Person class and skip doing it the Angular way?

person.service.ts

@Injectable()
export class Person {
  constructor(private name: string) { }
  talk() {
    console.log(`${this.name} is talking!`)
  }

}

app.component.ts

 export class AppComponent {
 ngOnInit() {
   let a = ['Bob','Amy','Joe']
   let instances = a.map(rec=> new Person(rec))
   instances.forEach(person=> person.talk())
 }

}

Output:
Bob is talking!
Amy is talking!
Joe is talking!

Upvotes: 1

Views: 1136

Answers (2)

Martin
Martin

Reputation: 16302

In the example given, Person is a type -- not really a service.

If the Person type is a simple type, say just a Plain Old JavaScript Object -- I would just new it up. A good example of this would be Ngrx actions. These are just simply types that do not need to be mocked for testing -- and can safely be newed up.

If this is more complex and you should mock it out for testing, use @estus answer.

Upvotes: 0

Estus Flask
Estus Flask

Reputation: 222578

The fact that Angular injector propagates singleton pattern with default provider type (useClass) is only one of benefits that DI provides.

It's possible to avoid singletons if they aren't desirable and still use DI, at least for testing reasons:

providers: [{ provide: Person, useValue: Person }]

and

export class AppComponent {
 constructor(@Inject(Person) private Person: typeof Person) {}
 ngOnInit() {
   ...
   let instances = a.map(rec=> new this.Person(rec))
   ...
 }

Otherwise a class cannot be mocked entirely in tests via TestBed. Currently Person constructor doesn't contain the code that would make it necessary to be mocked.

Upvotes: 1

Related Questions