How can I inject ViewContainerRef into a service?
Asked Answered
D

2

7

I'm attempting to inject ViewContainerRef into a service, but am receiving error No provider for ViewContainerRef!. I found this PR, which addresses exactly what I'm after and it appears to have been merged.

Note that I am aware of how to achieve this by using a placeholder using this.

Delsiedelsman answered 16/11, 2016 at 16:7 Comment(3)
ViewContainerRef belongs to current component. A service is a singleton that can belong to current component's injector or parent injector. If it were instantiated by parent component and then injected into child component, it would have wrong view container reference. This doesn't make much sense. If you're already aware of a workaround, why asking this question?Estabrook
I understand where you're coming from. I made mention of the PR for this exact reason because it appeared to accomplish what my initial approach was.Delsiedelsman
I'm not sure how PR is supposed to address this, because it would hit the same design problem. And I don't think that this.modalService.viewContainerRef = this.viewContainerRef workaround is a good choice for the same reason. Considering that service may be singleton, this definitely shouldn't be managed via DI. What exactly is your case?Estabrook
R
8

Services are meant to be completely agnostic to any view. If you are trying to have a service associated with a particular view, then you should add it to the providers list within a specific parent component/directive and pass the ViewContainerRef as an argument into one of the service's methods.

Risorgimento answered 22/3, 2018 at 15:28 Comment(0)
J
6

Make the service that you need the viewContainerRef in a singleton by adding it as a provider in app.module (and only app module); Inject that service into the component you need the containerRef of's constructor and have it call a setter method in the service that sets its containerRef to a variable in the service for future use.

The component you want to pass its ref

export class PrintPortalComponent {

  constructor(
    private printPortalService: PrintPortalService, 
    public viewContainerRef: ViewContainerRef
  ) {
    this.printPortalService.printPortalRef = this.viewContainerRef;
  }

}

Your singleton service

export class PrintPortalService {

  public viewContainerRef: ViewContainerRef;

  set printPortalRef(vcr: ViewContainerRef) {
    this.viewContainerRef = vcr;
  }
}

I struggled with this for hours until i found this: How do I create a singleton service in Angular 2?

Jemima answered 2/4, 2019 at 9:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.