How to inject a service into a class that must be instantiated in app module in angular 7?












0















I am using ngxs in a project and I want to use the ngxs logger plugin, but I want to override the logger itself so that I am able to log to the backend. For this I need to inject my RestService in my logger class but I am not being able to do so. I have seen multiple questions where it is asked how to inject services into plain classes but those cases don't really answer the case where you have to manually instantiate the class at the app module. This, this and this are such answers that failed to help me or I failed to grasp their knowledge.



Here is what I have in my app module's imports:



export const APP_MODULE_IMPORTS = [
NgxsModule.forRoot([
NewsState,
NewsAdminState,
]),
NgxsReduxDevtoolsPluginModule.forRoot(),
NgxsLoggerPluginModule.forRoot({
collapsed: false,
logger: new Logger(/* Need somehow to have an instance of the RestService HERE without having to pass all other dependencies */)
}),
BrowserModule,
HttpClientModule,
FormsModule,
ReactiveFormsModule,
routing
];


And here's my logger class:



import { RestService } from 'my-angular-modules';

@Injectable()
export class Logger {

constructor(private restService: RestService) {
}

public log(title, color, payload): void {
console.log(title, 'title');
console.log(color, 'color');
console.log(payload, 'payload');
}

public groupCollapsed(message): void {
console.groupCollapsed(message);
}

public group(message): void {
console.group(message);
}

public groupEnd(): void {
console.groupEnd();
}
}


I cannot pass an instance of rest service directly because I would have to pass a cascade of dependencies.
I also tried using injection tokens and add { provide: LOGGER_INJECTION_TOKEN, useClass: RestService } to providers but I got to the same point. I don't know how to instantiate the Logger class at that point without having to pass these arguments that I don't have.



Is this even possible? If not, how should I do this? I want to be able to use the ngxs logger to store the logs of the actions instead of creating custom logging in the components but for that I need the logger to be able to use my rest service.










share|improve this question





























    0















    I am using ngxs in a project and I want to use the ngxs logger plugin, but I want to override the logger itself so that I am able to log to the backend. For this I need to inject my RestService in my logger class but I am not being able to do so. I have seen multiple questions where it is asked how to inject services into plain classes but those cases don't really answer the case where you have to manually instantiate the class at the app module. This, this and this are such answers that failed to help me or I failed to grasp their knowledge.



    Here is what I have in my app module's imports:



    export const APP_MODULE_IMPORTS = [
    NgxsModule.forRoot([
    NewsState,
    NewsAdminState,
    ]),
    NgxsReduxDevtoolsPluginModule.forRoot(),
    NgxsLoggerPluginModule.forRoot({
    collapsed: false,
    logger: new Logger(/* Need somehow to have an instance of the RestService HERE without having to pass all other dependencies */)
    }),
    BrowserModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule,
    routing
    ];


    And here's my logger class:



    import { RestService } from 'my-angular-modules';

    @Injectable()
    export class Logger {

    constructor(private restService: RestService) {
    }

    public log(title, color, payload): void {
    console.log(title, 'title');
    console.log(color, 'color');
    console.log(payload, 'payload');
    }

    public groupCollapsed(message): void {
    console.groupCollapsed(message);
    }

    public group(message): void {
    console.group(message);
    }

    public groupEnd(): void {
    console.groupEnd();
    }
    }


    I cannot pass an instance of rest service directly because I would have to pass a cascade of dependencies.
    I also tried using injection tokens and add { provide: LOGGER_INJECTION_TOKEN, useClass: RestService } to providers but I got to the same point. I don't know how to instantiate the Logger class at that point without having to pass these arguments that I don't have.



    Is this even possible? If not, how should I do this? I want to be able to use the ngxs logger to store the logs of the actions instead of creating custom logging in the components but for that I need the logger to be able to use my rest service.










    share|improve this question



























      0












      0








      0








      I am using ngxs in a project and I want to use the ngxs logger plugin, but I want to override the logger itself so that I am able to log to the backend. For this I need to inject my RestService in my logger class but I am not being able to do so. I have seen multiple questions where it is asked how to inject services into plain classes but those cases don't really answer the case where you have to manually instantiate the class at the app module. This, this and this are such answers that failed to help me or I failed to grasp their knowledge.



      Here is what I have in my app module's imports:



      export const APP_MODULE_IMPORTS = [
      NgxsModule.forRoot([
      NewsState,
      NewsAdminState,
      ]),
      NgxsReduxDevtoolsPluginModule.forRoot(),
      NgxsLoggerPluginModule.forRoot({
      collapsed: false,
      logger: new Logger(/* Need somehow to have an instance of the RestService HERE without having to pass all other dependencies */)
      }),
      BrowserModule,
      HttpClientModule,
      FormsModule,
      ReactiveFormsModule,
      routing
      ];


      And here's my logger class:



      import { RestService } from 'my-angular-modules';

      @Injectable()
      export class Logger {

      constructor(private restService: RestService) {
      }

      public log(title, color, payload): void {
      console.log(title, 'title');
      console.log(color, 'color');
      console.log(payload, 'payload');
      }

      public groupCollapsed(message): void {
      console.groupCollapsed(message);
      }

      public group(message): void {
      console.group(message);
      }

      public groupEnd(): void {
      console.groupEnd();
      }
      }


      I cannot pass an instance of rest service directly because I would have to pass a cascade of dependencies.
      I also tried using injection tokens and add { provide: LOGGER_INJECTION_TOKEN, useClass: RestService } to providers but I got to the same point. I don't know how to instantiate the Logger class at that point without having to pass these arguments that I don't have.



      Is this even possible? If not, how should I do this? I want to be able to use the ngxs logger to store the logs of the actions instead of creating custom logging in the components but for that I need the logger to be able to use my rest service.










      share|improve this question
















      I am using ngxs in a project and I want to use the ngxs logger plugin, but I want to override the logger itself so that I am able to log to the backend. For this I need to inject my RestService in my logger class but I am not being able to do so. I have seen multiple questions where it is asked how to inject services into plain classes but those cases don't really answer the case where you have to manually instantiate the class at the app module. This, this and this are such answers that failed to help me or I failed to grasp their knowledge.



      Here is what I have in my app module's imports:



      export const APP_MODULE_IMPORTS = [
      NgxsModule.forRoot([
      NewsState,
      NewsAdminState,
      ]),
      NgxsReduxDevtoolsPluginModule.forRoot(),
      NgxsLoggerPluginModule.forRoot({
      collapsed: false,
      logger: new Logger(/* Need somehow to have an instance of the RestService HERE without having to pass all other dependencies */)
      }),
      BrowserModule,
      HttpClientModule,
      FormsModule,
      ReactiveFormsModule,
      routing
      ];


      And here's my logger class:



      import { RestService } from 'my-angular-modules';

      @Injectable()
      export class Logger {

      constructor(private restService: RestService) {
      }

      public log(title, color, payload): void {
      console.log(title, 'title');
      console.log(color, 'color');
      console.log(payload, 'payload');
      }

      public groupCollapsed(message): void {
      console.groupCollapsed(message);
      }

      public group(message): void {
      console.group(message);
      }

      public groupEnd(): void {
      console.groupEnd();
      }
      }


      I cannot pass an instance of rest service directly because I would have to pass a cascade of dependencies.
      I also tried using injection tokens and add { provide: LOGGER_INJECTION_TOKEN, useClass: RestService } to providers but I got to the same point. I don't know how to instantiate the Logger class at that point without having to pass these arguments that I don't have.



      Is this even possible? If not, how should I do this? I want to be able to use the ngxs logger to store the logs of the actions instead of creating custom logging in the components but for that I need the logger to be able to use my rest service.







      angular angular7 ngxs angular-dependency-injection






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 6 '18 at 14:07









      Goncalo Peres

      1,3311318




      1,3311318










      asked Nov 22 '18 at 10:35









      António QuadradoAntónio Quadrado

      7071820




      7071820
























          1 Answer
          1






          active

          oldest

          votes


















          2














          You could try using a provider factory:




          export function createLoggerPluginOptions(httpClient: HttpClient) {
          return {
          logger: new Logger(httpClient)
          }
          }


          // and provide in the module:
          {
          provide: NGXS_LOGGER_PLUGIN_OPTIONS,
          useFactory: (createLoggerPluginOptions),
          deps: [HttpClient]
          }





          Here is a working example:
          https://stackblitz.com/edit/ngxs-custom-logger






          share|improve this answer


























          • What would I put in the logger plugin as the logger NgxsLoggerPluginModule.forRoot({ collapsed: false, logger: new Logger() })?

            – António Quadrado
            Nov 22 '18 at 13:59











          • {... logger: Logger ...} should do the job.

            – eranshmil
            Nov 22 '18 at 14:13











          • I am very sorry to say but it doesn't work. It expects an instance of the class Logger, if I pass the class directly even with your code in the providers it says that the logger.log is not a function.

            – António Quadrado
            Nov 22 '18 at 14:23











          • Updated my answer with a working example.

            – eranshmil
            Nov 22 '18 at 14:37






          • 1





            It works indeed! Thank you for your answer, it was of great help!

            – António Quadrado
            Nov 22 '18 at 15:04











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53428999%2fhow-to-inject-a-service-into-a-class-that-must-be-instantiated-in-app-module-in%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          You could try using a provider factory:




          export function createLoggerPluginOptions(httpClient: HttpClient) {
          return {
          logger: new Logger(httpClient)
          }
          }


          // and provide in the module:
          {
          provide: NGXS_LOGGER_PLUGIN_OPTIONS,
          useFactory: (createLoggerPluginOptions),
          deps: [HttpClient]
          }





          Here is a working example:
          https://stackblitz.com/edit/ngxs-custom-logger






          share|improve this answer


























          • What would I put in the logger plugin as the logger NgxsLoggerPluginModule.forRoot({ collapsed: false, logger: new Logger() })?

            – António Quadrado
            Nov 22 '18 at 13:59











          • {... logger: Logger ...} should do the job.

            – eranshmil
            Nov 22 '18 at 14:13











          • I am very sorry to say but it doesn't work. It expects an instance of the class Logger, if I pass the class directly even with your code in the providers it says that the logger.log is not a function.

            – António Quadrado
            Nov 22 '18 at 14:23











          • Updated my answer with a working example.

            – eranshmil
            Nov 22 '18 at 14:37






          • 1





            It works indeed! Thank you for your answer, it was of great help!

            – António Quadrado
            Nov 22 '18 at 15:04
















          2














          You could try using a provider factory:




          export function createLoggerPluginOptions(httpClient: HttpClient) {
          return {
          logger: new Logger(httpClient)
          }
          }


          // and provide in the module:
          {
          provide: NGXS_LOGGER_PLUGIN_OPTIONS,
          useFactory: (createLoggerPluginOptions),
          deps: [HttpClient]
          }





          Here is a working example:
          https://stackblitz.com/edit/ngxs-custom-logger






          share|improve this answer


























          • What would I put in the logger plugin as the logger NgxsLoggerPluginModule.forRoot({ collapsed: false, logger: new Logger() })?

            – António Quadrado
            Nov 22 '18 at 13:59











          • {... logger: Logger ...} should do the job.

            – eranshmil
            Nov 22 '18 at 14:13











          • I am very sorry to say but it doesn't work. It expects an instance of the class Logger, if I pass the class directly even with your code in the providers it says that the logger.log is not a function.

            – António Quadrado
            Nov 22 '18 at 14:23











          • Updated my answer with a working example.

            – eranshmil
            Nov 22 '18 at 14:37






          • 1





            It works indeed! Thank you for your answer, it was of great help!

            – António Quadrado
            Nov 22 '18 at 15:04














          2












          2








          2







          You could try using a provider factory:




          export function createLoggerPluginOptions(httpClient: HttpClient) {
          return {
          logger: new Logger(httpClient)
          }
          }


          // and provide in the module:
          {
          provide: NGXS_LOGGER_PLUGIN_OPTIONS,
          useFactory: (createLoggerPluginOptions),
          deps: [HttpClient]
          }





          Here is a working example:
          https://stackblitz.com/edit/ngxs-custom-logger






          share|improve this answer















          You could try using a provider factory:




          export function createLoggerPluginOptions(httpClient: HttpClient) {
          return {
          logger: new Logger(httpClient)
          }
          }


          // and provide in the module:
          {
          provide: NGXS_LOGGER_PLUGIN_OPTIONS,
          useFactory: (createLoggerPluginOptions),
          deps: [HttpClient]
          }





          Here is a working example:
          https://stackblitz.com/edit/ngxs-custom-logger






          export function createLoggerPluginOptions(httpClient: HttpClient) {
          return {
          logger: new Logger(httpClient)
          }
          }


          // and provide in the module:
          {
          provide: NGXS_LOGGER_PLUGIN_OPTIONS,
          useFactory: (createLoggerPluginOptions),
          deps: [HttpClient]
          }





          export function createLoggerPluginOptions(httpClient: HttpClient) {
          return {
          logger: new Logger(httpClient)
          }
          }


          // and provide in the module:
          {
          provide: NGXS_LOGGER_PLUGIN_OPTIONS,
          useFactory: (createLoggerPluginOptions),
          deps: [HttpClient]
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 22 '18 at 14:37

























          answered Nov 22 '18 at 13:43









          eranshmileranshmil

          564




          564













          • What would I put in the logger plugin as the logger NgxsLoggerPluginModule.forRoot({ collapsed: false, logger: new Logger() })?

            – António Quadrado
            Nov 22 '18 at 13:59











          • {... logger: Logger ...} should do the job.

            – eranshmil
            Nov 22 '18 at 14:13











          • I am very sorry to say but it doesn't work. It expects an instance of the class Logger, if I pass the class directly even with your code in the providers it says that the logger.log is not a function.

            – António Quadrado
            Nov 22 '18 at 14:23











          • Updated my answer with a working example.

            – eranshmil
            Nov 22 '18 at 14:37






          • 1





            It works indeed! Thank you for your answer, it was of great help!

            – António Quadrado
            Nov 22 '18 at 15:04



















          • What would I put in the logger plugin as the logger NgxsLoggerPluginModule.forRoot({ collapsed: false, logger: new Logger() })?

            – António Quadrado
            Nov 22 '18 at 13:59











          • {... logger: Logger ...} should do the job.

            – eranshmil
            Nov 22 '18 at 14:13











          • I am very sorry to say but it doesn't work. It expects an instance of the class Logger, if I pass the class directly even with your code in the providers it says that the logger.log is not a function.

            – António Quadrado
            Nov 22 '18 at 14:23











          • Updated my answer with a working example.

            – eranshmil
            Nov 22 '18 at 14:37






          • 1





            It works indeed! Thank you for your answer, it was of great help!

            – António Quadrado
            Nov 22 '18 at 15:04

















          What would I put in the logger plugin as the logger NgxsLoggerPluginModule.forRoot({ collapsed: false, logger: new Logger() })?

          – António Quadrado
          Nov 22 '18 at 13:59





          What would I put in the logger plugin as the logger NgxsLoggerPluginModule.forRoot({ collapsed: false, logger: new Logger() })?

          – António Quadrado
          Nov 22 '18 at 13:59













          {... logger: Logger ...} should do the job.

          – eranshmil
          Nov 22 '18 at 14:13





          {... logger: Logger ...} should do the job.

          – eranshmil
          Nov 22 '18 at 14:13













          I am very sorry to say but it doesn't work. It expects an instance of the class Logger, if I pass the class directly even with your code in the providers it says that the logger.log is not a function.

          – António Quadrado
          Nov 22 '18 at 14:23





          I am very sorry to say but it doesn't work. It expects an instance of the class Logger, if I pass the class directly even with your code in the providers it says that the logger.log is not a function.

          – António Quadrado
          Nov 22 '18 at 14:23













          Updated my answer with a working example.

          – eranshmil
          Nov 22 '18 at 14:37





          Updated my answer with a working example.

          – eranshmil
          Nov 22 '18 at 14:37




          1




          1





          It works indeed! Thank you for your answer, it was of great help!

          – António Quadrado
          Nov 22 '18 at 15:04





          It works indeed! Thank you for your answer, it was of great help!

          – António Quadrado
          Nov 22 '18 at 15:04


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53428999%2fhow-to-inject-a-service-into-a-class-that-must-be-instantiated-in-app-module-in%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          TypeError: fit_transform() missing 1 required positional argument: 'X'