0

I'm currently trying to implement a way for customers to pay online through my company's website, but I'm having troubles being able to call other methods that are outside the callback object. Here is a snippet of the code that I'm trying to execute and having issues with:

OpenLightBox(txn_type, invoices, amount, customer){

        $.get('/token_req', 
            {
                amount: amount, 
                invoice: `#9999999`, 
                type: txn_type == "cc" ? "ccsale" : "ecspurchase",
                email: customer.Email,

            }, (response) => {
        
            let token = response;

            let paymentFields = {
                ssl_txn_auth_token: token
            }

            let callback = {
                onError: (error) => {
                    console.error(error);   // api/payment_error
                },
                onDeclined: (response) => {
                    console.error(response.ssl_result_message); // api/payment_decline
                },
                onApproval: (response) => {
                    this.PayInvoices(response, invoices); // error this.PayInvoices is not defined
                }
            };
            
            PayWithConverge.open(paymentFields, callback);

            
        })
    }

    PayInvoices(response, invoices){
        console.log({invoices});
        console.log({response});
    }

    FormatDate2(dateIn){
       let [month,day,year] = dateIn.split('/');
       return `${year}-${month}-${day}`;
    }

PayWithConverge is a method that comes from an asynchronous script inside my index.html file.

The issue occurs when I have a successful transaction and when I try to call my PayInvoices method. I tried using .bind(this); on just about everything that I could think of but still run into the same issue.

I want to know if it's possible to call methods that are outside this callback object, and if so, how could I do that given the code I have here? Thanks!

EDIT

The OpenLightBox method is being called like this within my code:

<div className="ad-size-container fade-in">
                    <div className="page-header">
                        <h1>Pay Invoice</h1>
                    </div>
                    <Invoice invoices={this.state.Invoices} customer={this.state.Customer} getToken={this.OpenLightBox}></Invoice>
                </div>

Michael
  • 1,454
  • 3
  • 19
  • 45

1 Answers1

-2

It is because this refers to the Object inside get function.

Move it outside, above $.get

OpenLightBox(txn_type, invoices, amount, customer){

        let callback = {
            onError: (error) => {
                console.error(error); 
            },
            onDeclined: (response) => {
                console.error(response.ssl_result_message); 
            },
            onApproval: (response) => {
                this.PayInvoices(response, invoices); 
            }
        };
// .... rest of your code

Because arrow functions have lexical this binding. You can also keep it where it is but use regular functions, i.e:

    let callback = {
        onApproval: function(response) {
            this.PayInvoices(response, invoices); 
        }
        // ... rest of code
    };
Mr Shumar
  • 251
  • 1
  • 4
  • I think using regular functions is the opposite of what is intended. The OP used arrow functions, with the intention that `this` should refer to their own `PayInvoices` method. The way you propose it, it is quite certain that `this` will not refer to their class anymore. Moreover, *"the Object inside get function"* is not clear... Certainly the callback passed to `$.get` is not defining another `this`, as this callback is an arrow function... – trincot Sep 25 '20 at 14:29
  • Okay, I see, second way would not work, but first one should work (moving it outside `$.get`? – Mr Shumar Sep 25 '20 at 14:34
  • 1
    If it does not work inside `$.get` callback, it will not work outside it either, since there the value of `this` is exactly the same. The key is what Bergi wrote in comments... – trincot Sep 25 '20 at 14:37