0

I am receiving this token back from stripe.com, this.token tok_1E38C6Hzz3t7gwGKyWMW0mLA, and console.log it before sending it to the back end. It is defined in the console.log code below:

 onSubmit() {
this.stripeService
  .createToken(this.card.getCard(), this.address)
  .subscribe(result => {
    if (result.token) {
      this.approveCreditCardResponse.token = result.token.id;
      console.log('this.address', this.address);
      console.log('this.token', this.approveCreditCardResponse.token);
    } else if (result.error) {
      // Error creating the token
      console.log(result.error.message);
    }
  });
    const data = {
      "amount" : this.approveCreditCardResponse.amount,
      "currency" : this.approveCreditCardResponse.currency,
      "description" : this.approveCreditCardResponse.description,
      "token" : this.approveCreditCardResponse.token,
      "name": this.address.name,
      "address_line1": this.address.address_line1,
      "address_line2": this.address.address_line2,
      "address_city": this.address.address_city,
      "address_state" : this.address.address_state,
      "address_zip": this.address.address_zip,
      "address_country": this.address.address_country
    }
    console.log('this.token', this.approveCreditCardResponse.token);
    this.creditCardService.postCcData(data);

}

I get this response in the google chrome console window:

this.token tok_1E38C6Hzz3t7gwGKyWMW0mLA

I send it to the aspnet core backend with this code:

public async Task<IActionResult> PostCreditCardData([FromBody] StripeDto stripeDto)
     {

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

all of the values are defined in stripeDto using a breakpoint except for token. token is defined as ""

This is the StripeDto.cs

    public class StripeDto
{
    public int id { get; set; }
    public string amount { get; set; }
    public string currency { get; set; }
    public string description { get; set; }
    public string token { get; set; }
    public string name { get; set; }
    public string address_city { get; set; }
    public string address_line1 { get; set; }
    public string address_line2 { get; set; }
    public string address_state { get; set; }
    public string address_zip { get; set; }
    public string address_country { get; set; }
}

What am I missing?

Lee9287
  • 367
  • 3
  • 6
  • 18
  • `this.stripeService .createToken(this.card.getCard(), this.address)` is an async function - you need to move the method that sends the token to the server to the callback of this method. – tymeJV Feb 12 '19 at 21:44
  • @tymeJV why is the token defined before I send it to the back end, and is not the same at the backend? – Lee9287 Feb 12 '19 at 21:46
  • 1
    The token is defined because you're checking it *inside the callback of your async function* - outside the callback - the token doesnt exist. Your call to the server is happening before your call to get the token finishes. It's a common mistake when first learning async calls. See this post for much more info: https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – tymeJV Feb 12 '19 at 21:47
  • Thanks @tymeJV I get it now. but this site where I got angular ngx stripe does not use async https://www.npmjs.com/package/ngx-stripe – Lee9287 Feb 12 '19 at 21:48
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – ConnorsFan Feb 12 '19 at 21:49
  • Your stripe call is an AJAX call @Lee9287 - that's async. Any network call from JavaScript is async - it's an **A**JAX request – tymeJV Feb 12 '19 at 21:50
  • You have two lines `console.log('this.token', this.approveCreditCardResponse.token);`. One is inside the callback, the other is outside. Can you give them a different prefix and check if they output the same value to the console? – ConnorsFan Feb 12 '19 at 21:51
  • @ConnorsFan how is this a duplicate questions when I have no idea the answer is I should make it async? That was the answer given to me. – Lee9287 Feb 12 '19 at 21:59
  • @ConnorsFan thanks for the console.log input. The first token is defined but the second is not. I am new at this. I will review the post tymeJV provided to me to know where to put the await. – Lee9287 Feb 12 '19 at 22:02
  • The answer, as given by @tymeJV, is to move the lines `const data = { ... };` and `this.creditCardService.postCcData(...);` inside the callback, just after `this.approveCreditCardResponse.token = result.token.id;` (or at the end of the callback if you want to post the data even when there is an error). – ConnorsFan Feb 12 '19 at 22:03

1 Answers1

1

You need to move your server call into the callback from your stripe call - so it looks like:

onSubmit() {
    this.stripeService
        .createToken(this.card.getCard(), this.address)
        .subscribe(result => {
            if (result.token) {
                this.approveCreditCardResponse.token = result.token.id;
            } else if (result.error) {
                // Error creating the token
                console.log(result.error.message);
            }

            const data = {
                "amount" : this.approveCreditCardResponse.amount,
                "currency" : this.approveCreditCardResponse.currency,
                "description" : this.approveCreditCardResponse.description,
                "token" : this.approveCreditCardResponse.token,
                "name": this.address.name,
                "address_line1": this.address.address_line1,
                "address_line2": this.address.address_line2,
                "address_city": this.address.address_city,
                "address_state" : this.address.address_state,
                "address_zip": this.address.address_zip,
                "address_country": this.address.address_country
              }
              this.creditCardService.postCcData(data);
        });
}

What is happening is, the code is hitting your stripe call:

this.stripeService
        .createToken(this.card.getCard(), this.address)
        .subscribe(result => {
             //some code here, this is the callback!
             //code here gets executed once the request to stripe is complete
         });

//CODE HERE GETS IMMEDIATELY EXECUTED - IT DOES NOT WAIT FOR THE PREVIOUS
//CALL TO COMPLETE - THINGS DEFINED IN THE CALLBACK ABOVE WILL NOT BE ACCESSIBLE HERE

And then immediately going to the code after the stripe call and outside the callback - it does not wait for the call to finish.

tymeJV
  • 103,943
  • 14
  • 161
  • 157