2

I was checking out this answer.

It's basically a request to Mailchimp to send a confirmation email to the user when they submit their email.

The code works perfectly with jquery. But I don't like jquery. And it's kind of annoying to have to add it just for this tiny snippet, since I won't be using it in the rest of my project. I already tried "translating" this into vanilla javascript using fetch but it doesn't seem to work.

function register($form) {
    $.ajax({
        type: $form.attr('method'),
        url: $form.attr('action'),
        data: $form.serialize(),
        cache       : false,
        dataType    : 'json',
        contentType: "application/json; charset=utf-8",
        error       : function(err) { alert("Could not connect to the registration server. Please try again later."); },
        success     : function(data) {
            if (data.result != "success") {
                // Something went wrong, do something to notify the user. maybe alert(data.msg);
            } else {
                // It worked, carry on...
            }
        }
    });
}

EDIT Some suggested I should add the HTML form: I am doing all this because I want to send the user email to my MailChimp subscription list. But I want it to do it directly from my website without redirecting to the Mailchimp subscription page.

<form action="https://herokuapp.us5.list-manage.com/subscribe/post-json?u=070e69e5e3e6e664a8066e48f&amp;id=0bf75ac6c4&c=?" method="get" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate newsletter__form" target="_blank">

      <label for="mce-EMAIL">Ingresa tu correo electrónico:</label>
      <input type="email" placeholder="ejemplo@gmail.com" value="" name="EMAIL" class="required textfield email__textfield" id="mce-EMAIL">
      <input type="submit" value="suscribirme" name="subscribe" id="mc-embedded-subscribe" class="button raise">

      <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_070e69e5e3e6e664a8066e48f_0bf75ac6c4" tabindex="-1" value=""></div>
</form>

I also found out jquery ajax method get accepts the data argument but it takes what's inside of the data and adds it to the URL. So it's still a get request with no body. I am trying to find a way to do that but with fetch but somehow the jquery URL has things I don't know where they come from. I also tried doing this with POST method and fetch but apparently, the server doesn't allow that.

For what is worth this is how the URL generated by jquery request looks like:

 https://herokuapp.us5.list-manage.com/subscribe/post-json?u=070e69e5e3e6e664a8066e48f&id=0bf75ac6c4&c=jQuery35105022544193369527_1633147928440&EMAIL=email123456%40gmail.com&b_070e69e5e3e6e664a8066e48f_0bf75ac6c4=&_=1633147928441

And this is how I can trick my URL to look like with fetch. Here I get a CORS error

  https://herokuapp.us5.list-manage.com/subscribe/post-json?u=070e69e5e3e6e664a8066e48f&id=0bf75ac6c4&c=?&EMAIL=paula.uzcategui68%40gmail.com&b_070e69e5e3e6e664a8066e48f_0bf75ac6c4=

And this is what I'm doing with fetch

     function register(form) {
        data = new FormData(form);
        data = Object.fromEntries(data);
        data = Object.entries(data);
        let arroba = /@/gi;

        let action = form.getAttribute("action")+ "&"+ data[0][0] +"="+ data[0][1].replace(arroba, '%40') + "&" + data[1][0] + "=" + data[1][1]
       // console.log(action)
        fetch(action, {
            method: 'get',
            cache: 'no-cache',
            headers: {
                'content-type': 'application/json; charset=utf-8'
            },
        }) 
        .then(response => response.json())
        .catch(error => {
            alert("Could not connect to the registration server. Please try again later."+ error)
        });
    } 



pauzca
  • 164
  • 1
  • 12

1 Answers1

0

Try this, it is the exact solution for your question (I hope). If you still get stuck please comment down, I will explain.

async function register(form) {
    let data = new FormData(form);
    data = JSON.stringify(Object.fromEntries(data)); // convert formdata to json

    let response = await fetch(form.action, {
        method: form.method,
        body: data,
        cache: 'no-cache',
        headers: {
            'content-type': 'application/json; charset=utf-8'
        }
    })
    .then(response => response.json())
    .catch(error => {
        alert("Could not connect to the registration server. Please try again later.")
    });
}
Sparrow
  • 280
  • 1
  • 12