richnologies / ngx-stripe

Angular 6+ wrapper for StripeJS
MIT License
219 stars 77 forks source link

production AOT app does not load Stripe scripts #25

Closed GeorgeKnap closed 4 years ago

GeorgeKnap commented 6 years ago

Hi When I build my app for development with ng build the package downloads the stripe scripts from script.src = 'https://js.stripe.com/v3/';

When I build the app with ng build --prod I'm getting following errors in runtime: error in Firefox: message: "this.stripe is undefined" error in Chrome: TypeError: Cannot read property 'elements' of undefined

The ngx-stripe package is not loading the stripe scripts, there is no record in Network list No other errors in console. It looks like the load() method does not work when built with AOT.

versions: @angular 5.2.9 ngx-stripe 0.7.1

richnologies commented 6 years ago

Hi, thanks for the report.

I use those versions and seems to, could you please tell the typescript and rxjs versions you're working with?

richnologies commented 6 years ago

Hi again, after a deeper look, I upgrade library started project and rebuild the lib, please try to upgrade to ngx-stripe@0.8.0 and please let me know if it works

Thanks

GeorgeKnap commented 6 years ago

@richnologies
I'm afraid upgrading had no effect. These are my dependencies

"dependencies": {
        "@angular/animations": "5.2.9",
        "@angular/common": "5.2.9",
        "@angular/compiler": "5.2.9",
        "@angular/core": "5.2.9",
        "@angular/forms": "5.2.9",
        "@angular/platform-browser": "5.2.9",
        "@angular/platform-browser-dynamic": "5.2.9",
        "@angular/router": "5.2.9",
        "@angular/service-worker": "5.2.9",
        "ngx-stripe": "0.8.0",
        "hammerjs": "2.0.8",
        "rxjs": "5.5.7",
        "jquery": "3.3.1",
        "zone.js": "0.8.20",
        "core-js": "2.5.3"
    },
    "devDependencies": 
        "@angular/cli": "1.7.3",
        "@angular/compiler-cli": "5.2.9",
        "@angular/language-service": "5.2.9",
        "@angularclass/hmr": "2.1.3",
        "codelyzer": "4.2.1",
        "node-sass": "4.7.2",
        "ts-node": "4.1.0",
        "tslint": "5.9.1",
        "typescript": "2.7.2",
        "webpack": "3.11.0"
    }
richnologies commented 6 years ago

Hi @GeorgeKnap, I am still unable to reproduce the error. I can build the test project with the --prod flag and still works.

I check the usual reasons for AOT to fail, and release another version, 0.8.1. If still fails, It will be very helpful for me if you can a minimum project that fails, to see if I can see where the problem is.

Otherwise I don't know what else to try

GeorgeKnap commented 6 years ago

Hi @richnologies in your test project, does it work in lazy loaded modules?

In the readme you are importing NgxStripeModule in app.module. In my case I'm injecting StripeService to a component in a lazy loaded feature module.

Importing NgxStripeModule in appmodule will throw error: Can't bind to 'options' since it isn't a known property of 'ngx-stripe-card'.

I can get over it by importing NgxStripeModule directly into lazy loaded feature module although I doubt it's correct to use .forRoot() methods in feature modules. Perhaps there should be .forChild() method in NgxStripeModule ?

richnologies commented 6 years ago

Hi @GeorgeKnap, now I understand.

I publish a new version, 0.8.2 to prevent any more confusion with a .forChild() method, so you can use it. As you say, by convention forChild is the right method.

However, the method returns the exact result.

So, the way I see it, you have two options:

1) If you need the StripeService across more than one LazyModule, you can call the forRoot method on the main module and the import just the NgxStripeModule without any method, not forRoot nor forChild, in every LazyModule you need the StripeService to be available.

2) If you need the StripeService in only one module, you can call the forChild method directly on the LazyModule.

You could also use the second option and call forChild in any LazyModule you use, but then you will be creating an instance of the StripeService in every module.

In this case, that won't be a problem.

Thanks again for the report, I will be adding information to readme for this case.

Kind regards

GeorgeKnap commented 6 years ago

Right. My current state is: NgxStripeModule module imported in app.module.ts

@NgModule({
    imports: [
        BrowserAnimationsModule,
        CommonModule,
        HttpClientModule,
        AppRoutingModule,
        NgxStripeModule.forRoot(environment.stripeKey),
        CoreModule,
        LayoutModule
    ],
    declarations: [
        AppComponent
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

to make things simple I injected the StripeService into layout.component which is part of LayoutModule like this:


@Component({
  selector: 'winnr-layout',
  templateUrl: './layout.component.html',
  styleUrls: ['./layout.component.scss']
})
export class LayoutComponent implements OnInit, OnDestroy {

  constructor(
    private readonly stripeService: StripeService
  ) {  }

ngOnInit(){
    let foo = this.stripeService.getInstance(); //expecting to get Stripe instance reference
    console.log(foo);
}

}

And the result: dev build (no aot, no minification) ngx-stripe package loads v3/ stripe scrips, injects the service and the foo variable is the expected object.

prod build (AOT & minification) no stripe scripts loaded and error ERROR TypeError: Cannot read property 'getInstance' of undefined This means even the service injection does not work.

Can you perhaps share your test project where production build works?

edgargonzalez525 commented 6 years ago

I'm having the same issue when loading the stripe service from a lazy loaded module, even including the <script src="https://js.stripe.com/v3/"></script> file directly on the index.html, is not working and it's the same error as @GeorgeKnap

ERROR TypeError: Cannot read property 'getInstance' of undefined

the error is located here https://github.com/richnologies/ngx-stripe/blob/master/src/services/stripe.service.ts#L75

ghost commented 5 years ago

Same here.

TypeError: Cannot read property 'elements' of undefined StripeService.ac_main../node_modules/ngx-stripe/modules/ngx-stripe.es5.js.StripeService.elements (ngx-stripe.es5.js:396)

So on this code

StripeService.prototype.elements = function (options) { => return this.stripe.elements(options); };

nyxz commented 5 years ago

I stumped up on the same issue and I got:

TypeError: Cannot read property 'elements' of undefined

Weirdly enough, after some hours of testing it turned out the issue appears when I import the module like

NgxStripeModule.forRoot(config.stripeApiKey)

but it works when I give it the key directly:

NgxStripeModule.forRoot('pk_test_e1T*********************xf1')

I'll do some more investigation but this is one workaround for now.

nyxz commented 5 years ago

Further investigation showed that AOT build works fine if I use the environment.stripeApiKey and not config.stripeApiKey where they are:

// src/environments/environment.prod.ts
export const environment = {
  production: true,
  stripeApiKey: 'pk_test_e1T*********************xf1',
};

and

// src/app/app.config.ts
import { environment } from '@env/environment';
export const config = Object.freeze(environment);
Sampath-Lokuge commented 5 years ago

@richnologies Thanks 1st option works for me on the Ionic 4/ Angular 8 app. But I used this fork: https://github.com/nomadreservations/ngx-stripe

llibdude commented 5 years ago

I also used the nomadreservations fork, but I hope this helps the people using this library as well. I believe this is the optimal solution to the problem.

imports: [
   ...
   NgxStripeModule.forRoot()
],
providers: [
    {
      provide: STRIPE_PUBLISHABLE_KEY,
      useValue: someKeyVariable
    }
  ]

Using the injection token to pass in the token if it's something other than a static string.

It might be nice to add this to the README as well.

richnologies commented 4 years ago

I will close this now due to inactivity. Sorry for this library to be abandon for such a long time. A new version of the library has been published that should address this issue. Please give it a try. If the problem persists, please fell free to open it again. The new commitment of the team is to answer in less than a week.