Search code examples
angularangular2-di

Angular2 - when both services requires each other


This is my main component (the root component). Here I declare some services which are supposed to be accessible through whole application.

@Component({
    ...
    providers: [
      WebSocketService,
      ...
      AuthenticationService,
    ]
})
export class MainComponent { ... }

And - to be sure that evrybody understand - I'm doing:

bootstrap(MainComponent, [...]);

Both of WebSocketService and AuthenticationService are annotated with @Injectable(). Everything worked fine until I found that both services requires each other. AuthenticationService needs WebSocketService to communicate with backend server and WebSocketService needs AuthenticationService to check whether user is logged etc.

As a result I'm receiving that error message:

EXCEPTION: Cannot resolve all parameters for 'AuthenticationService'(undefined). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'AuthenticationService' is decorated with Injectable.

Here is the fragment of AuthenticationService. WebSocketService looks similiar.

@Injectable()
export class AuthenticationService implements OnInit {

    constructor(private webSocketService:WebSocketService) {
    }
    ...
}

I know, that there are different and maybe better solutions for this case (third service, etc) but this is not the point of my question. I would like to know if there is a way to inject two services into each other with Angular2 in similiar way that I had presented?


Solution

  • Update (not tested)

    bootstrap(AppComponent, [
      provide(WebSocketService, {useFactory: () => {
        let as = new AuthenticationService();
        let ws = new WebSocketService(as);
        as.webSocketService = ws;
        return ws;
      }}),
      provide(AuthenticationService, {useFactory: {(ws) => {
        return ws.authenticationService;
        }, deps: [WebSocketService]);
      })
    ]);
    

    Original (works only for type dependencies, not for instance dependencies)

    Circular referenced need to be resolved using forwardRef (needs to be imported from angular2/core

    constructor(@Inject(forwardRef(() => WebSocketService)) private webSocketService:WebSocketService) {