Issue

I am trying to integrate paypal with Angular. When I call an injected service inside a function of the promise returned I am unable to do it. I need help in achieving it.

Here are the steps I am trying to do.

  1. Click on the load PayPal button.
  2. Load the dynamically injected Braintree and PayPal sdk.
  3. Authorize into PayPal and get the nonce token.
  4. Pass the nonce token generated into the service which is injected into the component.

Code below

app.component.html

 <button (click)="initializePayPal()">load paypal</button> <div></div> 

app.component.ts

export class AppComponent { constructor(private backEndService: BackEndService) {} initializePayPal() { get("", () => { get( "", () => { console.log("loaded"); this.loadPayPalSDK(); } ); }); } private loadPayPalSDK(): void { braintree.client .create({ authorization: "sandbox_5rnr7xqg_kx8tzdyvfcrnxq5y" }) .then(clientInstance => { // Create a PayPal Checkout component. return braintree.paypalCheckout.create({ client: clientInstance }); }) .then(paypalCheckoutInstance => { return paypalCheckoutInstance.loadPayPalSDK({ vault: true }); }) .then(paypalCheckoutInstance => { return paypal .Buttons({ locale: "en_US", fundingSource: paypal.FUNDING.PAYPAL, style: { height: 40 }, createBillingAgreement() { return paypalCheckoutInstance.createPayment({ flow: "vault" }); }, onApprove(data, actions) { return paypalCheckoutInstance .tokenizePayment(data) .then(payload => { console.log(payload.nonce); this.backEndService.addToken(payload); }); }, onCancel(data) {}, onError(err) { // } }) .render("#pay-pal-btn"); }); } } 

Back End Service backend.service.ts

import { Injectable } from "@angular/core"; @Injectable({ providedIn: "root" }) export class BackEndService { addToken(token: string) { // here is am going to use the token generated and pass this value to backend service using http request. console.log("token" + token); } } 

Expected Resolution

I need to call the injected service upon the tokenizePayment method is called.

Thanks a lot in advance

StackBlitz URL

2

1 Answer

The problem you are having right now is related to the scope.

// you are losing the scope on calling paypal.Buttons // because this function has its own scope and it is not possible to // get the backend service which has another scope (this) return paypal.Buttons({ onApprove() { return paypalCheckoutInstance .tokenizePayment(data) .then(payload => { this.backendservice // <- this is undefined because of scope }); } }) 

However, I found two ways to handle this case.

  1. Use a static method.
 return paypal.Buttons({ onApprove() { return paypalCheckoutInstance .tokenizePayment(data) .then(payload => { BackEndService.sendToken(payload.nonce); }); } }) 

backend.service.ts

export class BackEndService { // our static method static sendToken(token: string) { console.log("[backend service] send token", token); } 
  1. Pass our scope indirectly using an object with our service reference.
 // create an object with my scope calling our service // we need to pass this object to our // method loadPayPalSDK config = { onApprove: (token: string) => { this.backEndService.addToken(token); } }; // I need my config here private loadPayPalSDK(config = this.config): void { // code omitted ... return paypal.Buttons({ onApprove() { return paypalCheckoutInstance .tokenizePayment(data) .then(payload => { config.onApprove(payload.nonce); }); } }) } 
4

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.