2

I'm using angular-cli with Angular 5. I am trying to create a service that uses another service itself.

However, I keep getting alternating errors of "Can't resolve all parameters for [service name]: (?)." and "Can't resolve all parameters for e: (?, ?, ?, ?)."

Here is my setup:

MyLoggerService

import { Injectable, Inject, forwardRef } from "@angular/core";
import { OtherLoggerService } from "@A/AServices";
// OtherLoggerService is from a package I installed via npm, so I won't include it here.

// I thought I was missing this @Injectable decorator, but adding it to my
//code gives me the e: (?, ?, ?, ?) error
//Without this @Injectable() line, I get the MyLoggerService: (?) error.
@Injectable() 
export class DMLoggerService extends {
    constructor(
        @Inject(forwardRef(() => OtherLoggerService)) private otherLoggerService: OtherLoggerService
    ) { }

    public logEvent(): void {
        this.otherLoggerService.logEvent();
    }
    public trackPageView(): void {
        this.otherLoggerService.trackPageView();
    }
}

MyComponent

import { Component, Inject, forwardRef} from "@angular/core";
import { OtherLoggerService} from "@A/AServices";
import { MyLoggerService } from "../../common/services/mylogger.service";
import { AnotherService } from "@A/AServices";

@Component({
    selector: "my-component",
    templateUrl: "./my-component.component.html"
})
export class MyComponent{
    constructor(
        @Inject(forwardRef(() => MyLoggerService)) private myLoggerService: MyLoggerService,
        private anotherService: AnotherService
    ) {
        this.myLoggerService.trackPageView();
        this.anotherService.someFunc();
    }
}

MyModule

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { CommonModule } from "@angular/common";
import { OtherLoggerService} from "@A/AServices"; // Just added this per comments, but still receive the same errors
import { MyLoggerService } from "../../common/services/mylogger.service";
import { AnotherService } from "@A/AServices";

@NgModule({
    imports: [
        CommonModule
        BrowserModule
    ],
    declarations: [],
    providers: [OtherLoggerService, MyLoggerService, AnotherService]
    // Added OtherLoggerService to this array but still received errors
})
export class MyModule { }

The problem is something related to the Injectors somewhere, but I'm unsure where to go. I have been moving in circles alternating the same two errors.

I am not using any Barrels, as I understand it, so ideally it shouldn't be an import-ordering problem.

I've seen the similar topics but have yet to find any working solution.

Edit: Both "OtherLoggerService" and "AnotherService" are services brought in from a package I installed with npm, so I won't post their contents here. However, if there is something I can learn from or need to keep in mind as a result of using them, please share your comments.

Edit: Added an import for OtherLoggerService on MyModule but still receiving errors.

Edit: Tried adding OtherLoggerService into the Providers array on MyModule, still receiving errors.

user2465164
  • 917
  • 4
  • 15
  • 29
  • 1
    Can you add the `OtherLoggerService` as well please? – user184994 Jun 12 '18 at 21:56
  • @user184994 OtherLoggerService is a service in a package I didn't write; something that was installed via npm. – user2465164 Jun 12 '18 at 21:58
  • 3
    If the `OtherLoggerService` is from a third party, is it in an Angular module? If so, did you import that module in the *app.module*, or some other module you wrote? – R. Richards Jun 12 '18 at 22:02
  • @R.Richards yes it's an Angular module from a third party. My code initially looked how it did above. I figured since no where else was using `OtherLoggerService` that I did not need to import it. I just imported it in `MyModule`, but I am still receiving the same errors. – user2465164 Jun 12 '18 at 22:07
  • 1
    Does this `@A` library include something like an `@A/ServiceModule`? *That* is what you would need to import into a module you wrote? You may not need to add the `@A/AServices` import in the module if the library offers a real module to use. – R. Richards Jun 12 '18 at 22:14
  • @R.Richards I'm not finding any type of Module in `@A`. Just a collection of classes and their functions. – user2465164 Jun 12 '18 at 22:20
  • That is unfortunate. Care to share where this library came from? Is it a public library? I assume it is if you installed it with npm; unless you are hosting your own npm repo. – R. Richards Jun 12 '18 at 22:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/173022/discussion-between-user2494584-and-r-richards). – user2465164 Jun 12 '18 at 22:24

1 Answers1

1

I have figured it out!

Similar to the responses and comments on this question: Angular DI Error - EXCEPTION: Can't resolve all parameters

it seems I've created a circular dependency within my code with the different services I have included in my providers array for MyModule.

The service I refer to as AnotherService I import from @A/AServices is actually included at the root module level in my case, off in a file I did not personally write or view in this instance. (In my case, all services from @A/AServices have been included at the root module.) To solve my problem, I simply removed AnotherService from my providers array.

Similarly, I also didn't need to include OtherLoggerService since it is also a part of @A/AServices.

Even though I removed them from the providers array at the module level, and also removed the import statements in MyModule, I still was able to use them in MyComponent, and still needed to import them in MyComponent, like normal.

Here is my updated code:

MyLoggerService (unchanged)

import { Injectable, Inject, forwardRef } from "@angular/core";
import { OtherLoggerService } from "@A/AServices";

@Injectable() 
export class DMLoggerService extends {
    constructor(
        @Inject(forwardRef(() => OtherLoggerService)) private otherLoggerService: OtherLoggerService
    ) { }

    public logEvent(): void {
        this.otherLoggerService.logEvent();
    }
    public trackPageView(): void {
        this.otherLoggerService.trackPageView();
    }
}

MyComponent (removed OtherLoggerService import since I inject that into MyLoggerService, so it's already included by the MyLoggerService import)

import { Component, Inject, forwardRef} from "@angular/core";
import { AnotherService} from "@A/AServices";
import { MyLoggerService } from "../../common/services/mylogger.service";

@Component({
    selector: "my-component",
    templateUrl: "./my-component.component.html"
})
export class MyComponent{
    constructor(
        private myLoggerService: MyLoggerService,
        @Inject(forwardRef(() => AnotherService)) private anotherService: AnotherService
    ) {
        this.myLoggerService.trackPageView();
        this.anotherService.someFunc();
    }
}

MyModule (removed references to AnotherService and OtherLoggerService since they are included in the root module. Also made some small changes to the @NgModule attributes)

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { CommonModule } from "@angular/common";
import { MyLoggerService } from "../../common/services/mylogger.service";

@NgModule({
    imports: [
        CommonModule
        BrowserModule
    ],
    declarations: [MyComponent],
    providers: [MyLoggerService], // removed the services here that were causing the circular dependency
    exports: [MyComponent]
})
export class MyModule { }

I'd also like to note for any future readers that my use of @Inject(forwardRef(() => ServiceName)) when outlining parameters in the constructor of both MyLoggerService and MyComponent is due to a technical requirement with the services I'm using from my npm package @A/AServices, and for any services I'm creating myself, I don't need to use this forwardRef method when I include the service in the constructor.

user2465164
  • 917
  • 4
  • 15
  • 29