onMount reference to not yet defined script

Viewed 95

I want to add a Mailchimp form. I added the code provided by Mailchimp to my Svelte page:

<script>
    onMount(async() => {
        (function($) {
            window.fnames = new Array();
            window.ftypes = new Array();
            fnames[0]='EMAIL';
            ftypes[0]='email';
            fnames[1]='NAME';
            ftypes[1]='text';
            /*
             * Translated default messages for the $ validation plugin.
             * Locale: NL
             */
            $.extend($.validator.messages, {
                required: "Dit is een verplicht veld.",
                email: "Vul hier een geldig e-mailadres in.",
            });
        }(jQuery));
        var $mcj = jQuery.noConflict(true);
    });
</script>

<svelte:head>
    <script type='text/javascript' src='https://s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js'></script>
</svelte:head>

<div id="mc_embed_signup">
    <form action="https://openstate.us4.list-manage.com/subscribe/post?u=03355fd4f1a7935cae63b21aa&amp;id=a9619e4f3e" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
        <div id="mc_embed_signup_scroll">
            <h2>Subscribe</h2>
            <div class="indicates-required"><span class="asterisk">*</span> indicates required</div>
            <div class="mc-field-group">
                <label for="mce-EMAIL">Email Address  <span class="asterisk">*</span></label>
                <input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL">
            </div>
            <div id="mce-responses" class="clear">
                <div class="response" id="mce-error-response" style="display:none"></div>
                <div class="response" id="mce-success-response" style="display:none"></div>
            </div>    <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
            <div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_03355fd4f1a7935cae63b21aa_a9619e4f3e" tabindex="-1" value=""></div>
            <div class="clear"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"></div>
        </div>
    </form>
</div>

Most of the form works, but the translation of validation messages doesn't as it gives this error when I load the page:

Uncaught (in promise) ReferenceError: jQuery is not defined

This seems to be because mc-validate.js is loaded after the validator script already tried to call jQuery. How do I fix this?

1 Answers

You are right that onMount is called too soon, because at that point the script is not loaded yet. There's a DOM event onload which you can take advantage of, it's fired once the script is loaded:

<script>
    function init() {
        (function($) {
            window.fnames = new Array();
            window.ftypes = new Array();
            fnames[0]='EMAIL';
            ftypes[0]='email';
            fnames[1]='NAME';
            ftypes[1]='text';
            /*
             * Translated default messages for the $ validation plugin.
             * Locale: NL
             */
            $.extend($.validator.messages, {
                required: "Dit is een verplicht veld.",
                email: "Vul hier een geldig e-mailadres in.",
            });
        }(jQuery));
        var $mcj = jQuery.noConflict(true);
    }
</script>

<svelte:head>
    <script type='text/javascript' src='https://s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js' on:load={init}></script>
</svelte:head>

<!-- ... -->
Related