Error when trying to run JS from a Flow (on success of form) - "Uncaught (in promise) TypeError: Cannot read property ‘apply’ of undefined"

System: Mac
Project: NodeJS
db: MySql8

Following the stripe checkout tutorial (here), as we now have some one off products that need to be purchased and our billing portal doesn’t handle this.

I am able to successfully create the session etc. but on success when I try to run the JS snippet provided in the tutorial (with the values amended to suit my app) I get the following error:

Uncaught (in promise) TypeError: Cannot read property 'apply' of undefined
    at n.runJS (dmxAppConnect.js:7)
    at n._execStep (dmxAppConnect.js:7)
    at dmxAppConnect.js:7

I can confirm that the stripe script is in the header and the JS is in the body of the page.

Looking online at this issue, it appears it is indeed a bug that is experienced outside of Wappler.

1 Like

How does your flow step look like? If you try to call that function from the console in devtools does it then work?

When I try and run from console:

The flow etc. is exactly as per the tutorial I linked to, however here is a screenshot:

Now also doing the same for a simple redirect action that previously worked (sending me to Stripe hosted checkout).

Well seems the JavaScript function you are running has an error.

Also if you really want a good integrated asynchronous JavaScript function in a flow - it should return a JavaScript promise to let the flow knows when it is done.

Hey @George - I’ve copied word for word the js from the mentioned stripe tutorial that everyone is using successfully.

And the above (last error) - is a browser redirect not JS.

@George, @patrick - bumping this, naturally being able to actually setup to process payments is pretty critical. Please advise if/how I can debug this further for you.

Aimed to go live this week, but this and the other API issues/bugs are blocking this now.

Matt

Without more information it is difficult to tell what goes wrong. The first error runStripe is not defined seems that it can’t find the function. How was the function included on the page, is it global available (on the window object). Try to run it in the console to see if it works.

Second error seems to be again an undefined value in the goto action. What is the expression that you used, did you reference an object that was not defined.

Hi @patrick

FIRST ERROR

The JS Snippet (below) is included in the content page, keeping it within the ‘body’:

</div>
<script>
var stripe = Stripe('pk_test_MYKEY');
function runStripe() {
stripe.redirectToCheckout({
sessionId: dmx.parse('emailPack1form.data.stripe.data.id')
});
}
</script>
</main></div>
</div>
</div>
</main>

<script src="[bootstrap/4/js/popper.min.js](http://localhost:8100/bootstrap/4/js/popper.min.js)"></script>
<script src="[bootstrap/4/js/bootstrap.min.js](http://localhost:8100/bootstrap/4/js/bootstrap.min.js)"></script>
</body>

</html> 

This is what it looks like in Wappler code editor:

This is what it looks like when I view source in the fully rendered page:

And the <script src="https://js.stripe.com/v3/"></script> link is in the within the header on the layout page. Within the <header></header> tags.

As per the Stripe tutorial mentioned above, I have on form success a FLOW:

Wappler code editor view of the on-success form and FLOW:
Screen Shot 2020-10-20 at 4.40.07 pm

The Server Action executes perfectly, and what should then happen on success is the redirect action. However, this is what I get:

I’ve followed the tutorial word for word, everything works except running the JS to redirect with the session ID to Stripe. So any help here or how I can debug further would be appreciated.

I’m no JS dev - so I’m sorry but I don’t know how to run this in the console. However I have pasted the JS snippet (without the script) and tried to run it that way - and it returns ‘undefined’ in the console, too.

I’ve now also tried creating the sessionId and inputting that manually in the sessionId incase it was dmx.parse that was causing issues - no change, same error.

SECOND ERROR:
This is now fixed. Redirect element is working fine, I had switched SC’s and this was an incorrect endpoint for billing portal.

You could try moving the script block with the function to the head or to the end of the body. The problem is that it can’t find the function.

An other option you could try is to rewrite the function like:

var stripe = Stripe('...');
window.runStripe = function() {
  stripe.redirectToCheckout({
    sessionId: dmx.parse('...')
  });
}

@patrick

I don’t want to move the script block to the head, as that would mean it sits in the layout page - and then would load on a lot of pages it doesn’t need to.

So should we assume that this is simply a bug in a nodejs project? Surely the FLOW should be able to run this and other basic JS on the page without issue?

I’ve just tried your solution using window.runStripe - no luck.

Can we please have a fix ASAP for this - as I literally cannot transact with stripe without this…

@patrick - I’m getting another ‘undefined’ issue (I’ll report this as a separate bug here) when trying to use Google Autocomplete again (a new implementation - it’s working on older pages).

Page is rendered fine with dynamic picker.
I choose input and click ‘Make Google Places Autocomplete’
Then screen goes completely blank and I receive this error in Wappler UI:

All Google JS scripts are in the layout page header, and have/are working fine on other pages. It’s failing on a new implementation of Google Autocomplete.

Seemingly related as I’m getting another not defined error as per above.

Really need a fix for these items.

How did you create these pages, are they SPA pages and is are the scripts in the part that is dynamically loaded or did you use the new server-side templates? It looks like the script is somehow not being executed.

Server side template.

Layout page and a Content page
The Stripe JS ref link is in the header in the layout page, and the JS snippet (runstripe function) is in the body of the content page.

I think that I found the reason, I assume you also use the view component. The script is not being executed when it was loaded via ajax. You can test this by reloading the page, the script block is then generated server-side and it should run. There are multiple solution that I have to test to fix this (https://stackoverflow.com/questions/2592092/executing-script-elements-inserted-with-innerhtml).

Thanks @patrick - but when I try reloading the page to test if it does indeed work, I get the exact same error. I appreciate you looking into this - obviously pretty critical for me/any user that used Node and wants to use Stripe.

I still think it is better to have the script in the head, or load it using a js file. Since you have a SPA page it keeps the runStripe function also after navigating, when the function is created it will stay there until the whole page is reloaded. So even you loaded a new content page without the script block the runStripe will still be available, it is registered to the global page scope.

How would I load it via a js file? I’m trying to load the is via flow right now and it’s not working. I really don’t want the js snippet in the layout head - it’s only one page that it’s needed.

Whereas if it’s a js issue with run does this just mean I won’t be able to use flow for any JS functions?

I mean that you put the content of the script block into a js file and load it using <script src="runstripe.js"></script>.

I really need this working but I’m not following how to do what you suggest. Can we expect a fix this update or is this the only solution?

If so can you provide a little more guidance to do what you are suggesting please?