Service: No provider for Renderer2
Solution 1:
Possibly duplicating with Using Renderer in Angular 4
You cannot inject Renderer2
, but we can run RendererFactory2
to get Renderer2
instance inside @Injectable()
service.
There are two different ways of solving this issue.
Get an instance of Renderer2 inside Service
There is the way which Angular using internally in webworkers, for example. I've solved the problem with the code below:
import { Injectable, Renderer2, RendererFactory2 } from '@angular/core';
@Injectable()
class Service {
private renderer: Renderer2;
constructor(rendererFactory: RendererFactory2) {
this.renderer = rendererFactory.createRenderer(null, null);
}
}
In your particular case, it will be
@Injectable()
class Service {
private renderer: Renderer2;
constructor(rendererFactory: RendererFactory2, @Inject(DOCUMENT) private document){
this.renderer = rendererFactory.createRenderer(null, null);
}
loadScript(src:string){
const script = this.renderer.createElement('script');
this.renderer.appendChild(this.document.body,script);
script.src = src;
}
}
Parameters of RendererFactory2.createRenderer
method are:
-
hostElement
with typeany
-
type
with typeRendererType2|null
You can see that (null, null)
parameters are here:
https://github.com/angular/angular/blob/e3140ae888ac4037a5f119efaec7b1eaf8726286/packages/core/src/render/api.ts#L129
Pass Renderer2 from component
// declare public property in your service
@Injectable()
class Service {
renderer: Renderer;
}
// pass renderer to service in your component file
class App {
name:string;
constructor(service: Service, renderer: Renderer2) {
service.renderer = renderer;
}
}
Solution 2:
You can initialize service with an instance of Renderer2
in root component
@Injectable()
class MyService {
renderer : Renderer2;
}
...
class App {
name:string;
constructor(service: MyService, renderer: Renderer2) {
service.renderer = renderer;
}
}
See also
- Using Renderer in Angular 4
Solution 3:
I tried to implement this using render2, but in a service - leading to 'StaticInjectorError(AppModule)[Renderer2]'-Error, as injecting Renderer2-Instance seems to not be possible. Solution was to inject RendererFactory2 and manullay create the reference within the service, like:
@Injectable({
providedIn: 'root'
})
export class FgRendererService {
/** Reference to render-instance */
public renderer: Renderer2;
/** CONSTRUCTOR */
constructor(
private _renderer: RendererFactory2
) {
this.renderer = _renderer.createRenderer(null, null);
}
/** Add class to body-tag */
addBodyClass( classToAdd: string ): void {
this.renderer.addClass( document.body, classToAdd );
}
/** Remove class from body-tag */
removeBodyClass( classToRemove: string ): void {
this.renderer.removeClass( document.body, classToRemove );
}
}