1

I am building a personal website with Gridsome. I am trying to set up a newsletter signup form via Netlify Forms. I don't want the user to be redirected after clicking 'Submit'. To prevent that I use @submit.prevent like so:

<form name= "add-subscriber" id="myForm" method="post" @submit.prevent="handleFormSubmit" 
data-netlify="true" data-netlify-honeypot="bot-field">
  <input type="hidden" name="form-name" value="add-subscriber" />
  <input type="email" v-model="formData.userEmail" name="user_email" required="" id="id_user_email">
  <button type="submit" name="button">Subscribe</button>
</form>

Then using a mix of the following guides (gridsome guide, CSS-Tricks guide) I do the following in my script section:

<script>
import axios from "axios";

export default {
    data() {
        return {
            formData: {},
            }
        },

    methods: {
        encode(data) {
            return Object.keys(data)
            .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
            .join('&')
        },

        handleFormSubmit(e) {
            axios('/', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: this.encode({
                    'form-name': e.target.getAttribute('name'),
                    ...this.formData,
                }),
            })
            .then(() => this.innerHTML = `<div class="form--success">Almost there! Check your inbox for a confirmation e-mail.</div>`)
            .catch(error => alert(error))
        }
    }
}
</script>

Error

Whatever I try I can't figure out how to configure the desired behavior. I keep getting the following errors - > Error: Request failed with status code 404 & Cannot POST /

Note

The reason I want to do it this way is that after the user submits the form a Netlify Function will be called to send the email_adress to EmailOctopus via their API.

This is how the function looks like:

submissions-created.js

import axios from "axios";

exports.handler = async function(event) {
    console.log(event.body)
    const email = JSON.parse(event.body).payload.userEmail
    console.log(`Recieved a submission: ${email}`)

    axios({
        method: 'POST',
        url: `https://emailoctopus.com/api/1.5/lists/contacts`,
        data: {
            "api_key": apikey,
            "email_address":  email,
        },
    })
    .then(response => response.json())
    .then(data => {
        console.log(`Submitted to EmailOctopus:\n ${data}`)
    })
    .catch(function (error) {
        error => ({ statusCode: 422, body: String(error) })
    });
}

Sorry for the long question. I really apreciate your time and your help. If you need any further details please let me know.

Rasul Kireev
  • 369
  • 1
  • 2
  • 16
  • 404 indicates that the URL is returning page not found. Are you sure the URL '/' exists and is accepting POST requests? – user120242 Apr 13 '20 at 18:18
  • Also I do not see where you have declared `listID` that you are using for your post request in `submissions-created.js` – user120242 Apr 13 '20 at 18:20
  • listID is an ENV variable. I put it there so it doesn't distract from the main issue. That was silly of me. Fixed it. As for the '/' url. That is supposed to be the home page, don't "go" to another page. – Rasul Kireev Apr 13 '20 at 18:25
  • Facing same problem... Is there any solution? – Atiar Rahman Aug 05 '20 at 16:59
  • I need to write up the solution, just don't remember the exact way I solved this. Meanwhile you can see my code here -> https://github.com/rasulkireev/gridsome-personal-webite. It is fully functional. – Rasul Kireev Aug 06 '20 at 20:35

1 Answers1

1

You can see the functional implementation in my repo (https://github.com/rasulkireev/gridsome-personal-webite). These are the changes I made.

submission-created.js

var axios = require("axios")

exports.handler = async function(event, context) {

    const email = JSON.parse(event.body).payload.email
    console.log(`Recieved a submission: ${email}`)

    return await axios({
        method: 'POST',
        url: 'https://api.buttondown.email/v1/subscribers',
        headers: {
            Authorization: `Token ${process.env.BUTTONDOWN_API}`
        },
        data: {
            'email': email,
        },
    })
    .then(response => console.log(response))
    .catch(error => console.log(error))
}

newsletter form in my components

 <div>
          <form
          name="add-subscriber"
          id="myForm"
          method="post"
          data-netlify="true"
          data-netlify-honeypot="bot-field"
          enctype="application/x-www-form-urlencoded"
          @submit.prevent="handleFormSubmit">
            <input type="hidden" name="form-name" value="add-subscriber" />
            <input type="email" name="userEmail" v-model="formData.userEmail">
            <button type="submit" name="button">Subscribe</button>
          </form>
        </div>

with the following script code in the same component

import axios from "axios";
export default {
    props: ['title', 'description'],
    
    data() {
        return {
            formData: {
                userEmail: null,
            },
        }
    },
    methods: {
        encode(data) {  
            const formData = new FormData();
            
            for (const key of Object.keys(data)) {
                formData.append(key, data[key]);
            }
            
            return formData;
        },
        handleFormSubmit(e) {
            const axiosConfig = {
                header: { "Content-Type": "application/x-www-form-urlencoded" }
            };
            axios.post(
                location.href, 
                this.encode({
                    'form-name': e.target.getAttribute("name"),
                    ...this.formData,
                }),
                axiosConfig
            )
            .then(data => console.log(data))
            .catch(error => console.log(error))
            .then(document.getElementById("myForm").innerHTML = `
            <div>Thank you! I received your submission.</div>
            `)
        }
    }
}
Rasul Kireev
  • 369
  • 1
  • 2
  • 16