Using value inside .forRoot() from a Service

36 views Asked by At

I'm using NX environment to manage multiple projects and, as it doesn't have a default way to work with environments, I created a service that implements the environment variables and it's working as expected.

The issue for me is inside the libs. One of the libs I have is for checkout payment, which uses NgxStripe. This module requires the PublishKey, which I have stored in the environment variables that comes from a service.

So, right now my CheckoutModule looks like this:

@NgModule({
  imports: [
    CommonModule,
    ReactiveFormsModule,
    RouterModule.forChild(userRouting),
    [...]
    NgxStripeModule.forRoot(environment.stripe?.publishable_key),
    [...]
  ],
})

But I wonder if there is a way for me to use the publish key from my environment service, which loads data from the app that is running, instead of this mock environment I created to use only on this module. Something like this:

@NgModule({
  imports: [
    CommonModule,
    ReactiveFormsModule,
    RouterModule.forChild(userRouting),
    [...]
    NgxStripeModule.forRoot(EnvironmentService.getValue().stripe.pk),
    [...]
  ],
})

Does anyone knows a way to achieve this?

2

There are 2 answers

0
Buczkowski On

I do not have experience with ngx-stripe but according to docs that should work:

export const STRIPE_INSTANCE_TOKEN = new InjectionToken<StripeInstance>('STRIPE_INSTANCE_TOKEN');

@NgModule({
  imports: [
    CommonModule,
    NgxStripeModule.forRoot(),
  ],
  providers: [
    {
      provide: STRIPE_INSTANCE_TOKEN,
      useFactory: (factoryService: StripeFactoryService) => () => factoryService.create(EnvironmentService.getValue().stripe.pk),
      deps: [StripeFactoryService],
      multi: true
    },
    // Then access instance via injection token
    
    // OR
    {
      provide: StripeService,
      useFactory: (factoryService: StripeFactoryService) => () => factoryService.create(EnvironmentService.getValue().stripe.pk),
      deps: [StripeFactoryService],
      multi: true
    }
    // Then access via StripeService
  ]
})

Usually you would put your service on deps but since it looks like static one you don't have to.

0
M G On

If you read through ngx-stripe.module code https://github.com/richnologies/ngx-stripe/blob/main/projects/ngx-stripe/src/lib/ngx-stripe.module.ts, then you can notice that ngx stripe uses publishableKey parameter, to provide is as value for STRIPE_PUBLISHABLE_KEY injection token.

What you can do, you can override their provider, by putting yours, something like this:

@NgModule({
  imports: [
    CommonModule,
    ReactiveFormsModule,
    RouterModule.forChild(userRouting),
    [...]
    NgxStripeModule.forRoot(), // you can leave it empty, since you'll override key below
    [...]
  ],
  providers: [
    {
      provide: STRIPE_PUBLISHABLE_KEY,
      useFactory: (environmentService: EnvironmentService) => environmentService.getValue().stripe.pk,
      deps: [EnvironmentService]
    },
  ]
})

of course you need to add import of STRIPE_PUBLISHABLE_KEY from ngx-stripe