richnologies / ngx-stripe

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

ngx-stripe-card is not a known element #163

Closed knowledgeplaces closed 2 years ago

knowledgeplaces commented 2 years ago

Same problem has already been reported on https://github.com/richnologies/ngx-stripe/issues/115 but I have still the issue even adding the NgxStripeModule.forChild() in app.module.ts.

Here is the component template code except:

<div fxLayout="row" fxLayoutAlign="start">
<ngx-stripe-card [options]="cardOptions" [elementsOptions]="elementsOptions"></ngx-stripe-card>
<button i18n mat-raised-button color="primary" type="button"
    (click)="this.testStripeApi()">Test Stripe API</button>
</div>

Where I have the error: 'ngx-stripe-card' is not a known element:

Here is my component code:

// stripe imports
import {
    StripeCardComponent,
    StripeInstance,
    StripeFactoryService
} from 'ngx-stripe';
import {
    StripeCardElementOptions,
    StripeElementsOptions
} from '@stripe/stripe-js';

@Component({
    selector: 'app-eshop-settings-form',
    templateUrl: './eshop-settings-form.component.html',
    styleUrls: ['./eshop-settings-form.component.css']
})
export class EshopSettingsFormComponent implements OnInit, AfterViewInit {

    @ViewChild(StripeCardComponent) card: StripeCardComponent;
    cardOptions: StripeCardElementOptions = {
        style: {
            base: {
                iconColor: '#666EE8',
                color: '#31325F',
                fontWeight: '300',
                fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
                fontSize: '18px',
                '::placeholder': {
                    color: '#CFD7E0'
                }
            }
        }
    };
    elementsOptions: StripeElementsOptions = {
        locale: 'en'
    };

Code of my test button:

    testStripeApi(): void {
        const name = this.eShopSettingsFormGroup.get('stripeCardTest').value;
        this.stripe.createToken(this.card.element, { name }).subscribe((result) => {
            if (result.token) {
                // Use the token
                console.log(result.token.id);
            } else if (result.error) {
                // Error creating the token
                console.log(result.error.message);
            }
        });
    }

Any advice appreciated.

richnologies commented 2 years ago

Hi @knowledgeplaces, thanks for creating a separate issue, is easier for me to keep track this way.

forChild() is not necessary. I simple add it once because this kind of issues, but right now is not recommended (actually I will probably add the deprecated warning after this)

I prepare for you a Stackblitz example using some your snippets: https://stackblitz.com/edit/ngx-stripe-issue-163 I get rid of material and flexlayout libraries to keep as simple as possible, but if you think they're relevant please let me know

A few notes:

I would like to apologize for the confusion.

If this helps you please let me know so I can adapt the docs to help other. If not, you can create a free account in Stackblitz and make any changes you need to replicate the error, that would help me fix it quickly.

If you're not able to replicate or you have anymore questions, do not hesitate to ask, I'm here to help :)

Kind regards,

R

knowledgeplaces commented 2 years ago

Thanks for quick feedback, but I am not lucky yet. I have followed your sample code. In app.module.ts, I have no error with: import { NgxStripeModule } from 'ngx-stripe'; and NgxStripeModule.forRoot('pk_test_***my_key***') and RouterModule.forRoot([ { path: 'stripetest', loadChildren: () => import('./stripe-test-form/stripe-test-form.module').then((m) => m.StripeTestFormModule), }, In stripe-test-form.module.ts, I have no error with:

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { NgxStripeModule } from 'ngx-stripe';

import { StripeTestFormComponent } from './stripe-test-form.component';

@NgModule({
    declarations: [StripeTestFormComponent],
    imports: [
        CommonModule,
        RouterModule.forChild([
            {
                path: '',
                component: StripeTestFormComponent,
            },
        ]),
        ReactiveFormsModule,
        NgxStripeModule,
    ],
})
export class StripeTestFormModule { }

In stripe-test-form-component.ts, I have:

import { Component, ViewChild } from '@angular/core';
import {
    StripeCardElementOptions,
    StripeElementsOptions,
} from '@stripe/stripe-js';
import { StripeCardComponent, StripeService } from 'ngx-stripe';

@Component({
    selector: 'app-stripe-test-component',
    template: `
    <div>
      <ngx-stripe-card [options]="cardOptions" [elementsOptions]="elementsOptions"></ngx-stripe-card>
      <button i18n type="button"
        (click)="this.testStripeApi()">Test Stripe API</button>
    </div>
  `,
})
export class StripeTestFormComponent {
    @ViewChild(StripeCardComponent) card: StripeCardComponent;
    cardOptions: StripeCardElementOptions = {
        style: {
            base: {
                iconColor: '#666EE8',
                color: '#31325F',
                fontWeight: '300',
                fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
                fontSize: '18px',
                '::placeholder': {
                    color: '#CFD7E0',
                },
            },
        },
    };
    elementsOptions: StripeElementsOptions = {
        locale: 'en',
    };

    constructor(private stripe: StripeService) { }

    testStripeApi(): void {
        this.stripe
            .createToken(this.card.element, { name: 'knowledgeplaces' })
            .subscribe((result) => {
                if (result.token) {
                    // Use the token
                    console.log(result.token.id);
                } else if (result.error) {
                    // Error creating the token
                    console.log(result.error.message);
                }
            });
    }
}

And I still have an error on ngx-stripe-card type unknown.

When I compile, I get this:


./projects/metalms-admin/src/app/stripe-test-form/stripe-test-form.component.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/i
vy/index.js):
TypeError: Cannot read property 'replace' of undefined
    at escapeString (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:17327:18)
    at escapeNonAsciiString (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:17332:13)
    at Object.getLiteralText (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:14276:34)
    at getLiteralTextOfNode (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:107448:23)
    at emitLiteral (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:104922:24)
    at pipelineEmitWithHintWorker (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:104725:32)
    at pipelineEmitWithHint (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:104364:17)
    at pipelineEmitWithSourceMaps (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:108140:13)
    at pipelineEmitWithComments (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:107818:13)
    at pipelineEmit (C:\Users\ericm\Workspaces\MyEclipse\KPSAngular\node_modules\typescript\lib\typescript.js:104304:13)

Apologize in advance if I made mistakes in applying your code into mine. stripe error

richnologies commented 2 years ago

This is odd. What versions are you using of:

Also, it would be great if you can pass that error to Stackblitz because it must be a small detail we are not getting right

knowledgeplaces commented 2 years ago

Hi @richnologies , and thanks for follow up.

Good news and odd news this morning.

I shut down my PC yesterday evening, power it on this morning, launch Eclipse, just do a little refactoring of code by putting the html template in a seperate file of the component template like this: template file:

<div>
  <ngx-stripe-card [options]="cardOptions" [elementsOptions]="elementsOptions"></ngx-stripe-card>
  <button i18n type="button"
    (click)="this.testStripeApi()">Test Stripe API</button>
</div>

component file excerpt:

@Component({
    selector: 'app-stripe-test-component',
    templateUrl: './stripe-test-form.component.html'
})

With that, I still have 'ngx-stripe-card' is not a known element:' when I edit the component file, but now the app compiles fine with no errors at all, and moreover, the app runs file, I can now enter and validate credit cards!

Here are the versions you requested: @angular-devkit/architect 0.1202.7 @angular-devkit/core 12.2.7 @angular-devkit/schematics 12.2.7 @schematics/angular 12.2.7 typescript 4.3.5 ngx-stripe 13.0.0 node js 14.17.0

So, although the app compiles and runs fine, if I could get rid off this error, it would be much appreciated.

Also, the public key is hard coded in the app.module.ts file, but I need to load it dynamically, since this is an app which will be used by many customers, and of course each customer will have its dedicated Stripe keys. Please explain how to do this if you deprecate forChild()

richnologies commented 2 years ago

Hi @knowledgeplaces, glad to hear your are making progress.

It seems to be something is odd with webpack. Maybe I would suggest to use ngx-stripe version 12 to match the Angular one, but to be honest, I don't is going to have any impact, is "just in case". I will try it with your versions to see if I can replicate the error.

In the meantime, for the dynamic key, we have the idea of a factory service, check the docs here: https://docs.ngx-stripe.dev/core-concepts/service-factory

I've updated the stackblitz example to use the factory service: https://stackblitz.com/edit/ngx-stripe-issue-163

In summary:

knowledgeplaces commented 2 years ago

Hi @richnologies ,

With your updated Stackblitz, I have been able to add support for dynamic key and it works perfectly, thanks.

I have still the error 'ngx-stripe-card' is not a known element:' when I edit the component template file, but the app compiles with no errors and runs file, and when I close my Eclipse IDE and reopen it, the file is not marked in error, so I will keep everything as is.

Thanks for your quick and efficient support on this issue.

angiexroap commented 1 year ago

@richnologies ... hi sir, recently stripe js updated to 1.50 version, ngx stripe has problem with one of its classes, StripeElementsOptions, now this name is BasicStripeElementsOptions, all modules broke with that

"@angular/core": "^15.1.0", "@angular/cli": "~15.1.2", "@angular/compiler-cli": "^15.1.0", "ngx-stripe": "^15.5.1", "@stripe/stripe-js": "^1.50.0"

check it please sir, thanks

richnologies commented 1 year ago

Hey @angiexroap, can you please update @stripe/stripe-js to version 1.51.0 and let know if that works for you?

angiexroap commented 1 year ago

hi sir, ya, all its ok

El mié., 22 de marzo de 2023 7:00 p. m., Ricardo Sánchez < @.***> escribió:

Hey @angiexroap https://github.com/angiexroap, can you please update @stripe/stripe-js to version 1.51.0 and let know if that works for you?

— Reply to this email directly, view it on GitHub https://github.com/richnologies/ngx-stripe/issues/163#issuecomment-1480362379, or unsubscribe https://github.com/notifications/unsubscribe-auth/A5CBTWFA2EVNQFZGWBG237TW5OABLANCNFSM5PKVJBDQ . You are receiving this because you were mentioned.Message ID: @.***>