'Angular what is the best practice for adding providers to component
I have built an Angular application which uses lazy loading. Throughout the application if there is a 1:1 relationship between a component and service I have structured my code as below:
@Injectable()
export class ContactFormService {
....stuff...
}
@Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.scss'],
providers: [ ContactFormService ]
})
export class ContactComponent {
....stuff...
}
As you can see I've directly added the service as one of the providers, rather than using @Injectable({ providedIn: 'root' }).
At the time I thought it would help any potential issues around using a singleton, should this service be used in a different component and lose that 1:1 relationship.
The side effect that I have noticed is that when writing unit tests I have to add overrideComponent() to the configuration
I have to do this (NOTE: I have to override the provided service):
TestBed.configureTestingModule({
declarations: [ContactComponent]
})
.overrideComponent(ContactComponent,
{ set: { providers: [{ provide: ContactFormService, useValue: contactFormServiceSpyObj }] }})
.compileComponents();
Instead of this:
await TestBed.configureTestingModule({
providers: [
{ provide: ContactFormService, useValue: contactFormServiceSpyObj }
],
declarations: [ ContactComponent ]
}).compileComponents();
This has made me wonder am I following a really bad practice? and if so, what circumstances would be suitable to inject a service in the way that I am doing so?
I understand that @Injectable({ providedIn: 'root' }) helps with the tress shaking process when building the application
Solution 1:[1]
I see nothing wrong with what you're doing - I also add services to component providers when I want them to be exclusive to the component instance (and possibly the children).
You should remember though to clean up resources on ngOnDestroy method in the service. (Yes, angular calls ngOnDestroy on services).
In situations where only one component instance is displayed at once I prefer a different approach to component provider.
I use a singleton service provided in root and call an initialization method of the service on the component ngOnInit. In that method I clean up any resources left over from previous component instance. That comes really handy when I'm using a single application wide state tree and I don't want to generate keys for each component separately.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
