Ad

Integrating Stripe JS Into Laravel 6.0: [Vue Warn]: Error Compiling Template:

I have my Stripe.js integration in my checkout.blade.php file. It works but not without this error:

[Vue warn]: Error compiling template:

Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <script>, as they will not be parsed

I have made the error disappear but then the Stripe Element won't appear on the page. I also have other JS integrated in this file for my form validation that works fine and doesn't return an error.

Here is the Stripe code that returns an error:

<script>
        (function(){
        // Create a Stripe client.
        var stripe = Stripe('pk_test_9dn1vt3i0j0Q5GZdwAXn9iUs00iMziQDyD');

        // Create an instance of Elements.
        var elements = stripe.elements();

        // Custom styling can be passed to options when creating an Element.
        // (Note that this demo uses a wider set of styles than the guide below.)
        var style = {
        base: {
            color: '#32325d',
            fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
            fontSmoothing: 'antialiased',
            fontSize: '16px',
            '::placeholder': {
            color: '#aab7c4'
            }
        },
        invalid: {
            color: 'red',
            iconColor: 'red'
        }
        };

        // Create an instance of the card Element.
        var card = elements.create('card', { style: style, hidePostalCode: true });

        // Add an instance of the card Element into the `card-element` <div>.
        card.mount('#card-element');

        // Handle real-time validation errors from the card Element.
        card.addEventListener('change', function(event) {
        var displayError = document.getElementById('card-errors');
        if (event.error) {
            displayError.textContent = event.error.message;
        } else {
            displayError.textContent = '';
        }
        });

        // Handle form submission.
        var form = document.getElementById('payment-form');
        form.addEventListener('submit', function(event) {
        event.preventDefault();

        stripe.createToken(card).then(function(result) {
            if (result.error) {
            // Inform the user if there was an error.
            var errorElement = document.getElementById('card-errors');
            errorElement.textContent = result.error.message;
            } else {
            // Send the token to your server.
            stripeTokenHandler(result.token);
            }
        });
        });

        // Submit the form with the token ID.
        function stripeTokenHandler(token) {
        // Insert the token ID into the form so it gets submitted to the server
        var form = document.getElementById('payment-form');
        var hiddenInput = document.createElement('input');
        hiddenInput.setAttribute('type', 'hidden');
        hiddenInput.setAttribute('name', 'stripeToken');
        hiddenInput.setAttribute('value', token.id);
        form.appendChild(hiddenInput);

        // Submit the form
        form.submit();
        }
        })();
    </script>

Note that right now that the Stripe code is nested into my:

@section('content')

@endsection

which is extended by my parent template, '''app.blade.php'''.

If I paste it outside the parent template and wrap it with something like this:

@section('stripe')

@endsection

then no error returns but the element won't appear because my JS doesn't know where to mount my Stripe element. Of course, I had this in my parent template too: @yield('stripe')

How can I get my Stripe Element to appear without getting this templating error?

EDIT: I used the Laravel/ui scaffolding (Bootstrap version). Attached are the following:

app.js:

require('./bootstrap');

window.Vue = require('vue');

const app = new Vue({
    el: '#app',
});

ExampleComponent.vue:

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Example Component</div>

                    <div class="card-body">
                        I'm an example component.
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

Thanks

Ad

Answer

As you mention in your question, you're using the bootstrap scaffolding from laravel/ui. Depending on the commands you used to generate that scaffolding, it can install some VueJS-centric files or data into common files, which appears to have happened with you. While you yourself did nothing with VueJS, the scaffolding did it for you.

In your app.js file, if you remove or comment-out lines 3-7, and re-run laravel-mix:

require('./bootstrap');

// 3 window.Vue = require('vue');
// 4
// 5 const app = new Vue({
// 6    el: '#app',
// 7 });

You will solve your problem.

As shown on line 6, VueJS targets the app id'd element which is present in app.stub, which is a file that is normally put under resources/views/layouts/app.blade.php; this view is used as the base view to extend other views from. Given that the app id'd div encapsulates most of the page/body element, any content you put inside of it VueJS will interpret as part of it's base template. This is why your error warns not to "put script tags inside the template".

As said, the above changes to your app.js file will of course solve the problem, as it takes VueJS out of the equation. That said, however, if you don't plan on using VueJS at all, you could also remove it from your package.json file and run npm prune to remove unused packages(as in any package not specified in package.json and not required as a dependency of another package), to remove the library from your site entirely.

Ad
source: stackoverflow.com
Ad