1

I'm trying to submit my form using formspree in a static site I'm building with React. I've gotten close, but now completely lost.

I'm trying to use ES6 Promise function but don't know how to complete it.

Here is my current code:

import React from 'react';
import { Link } from 'react-router';


import { prefixLink } from 'gatsby-helpers';
import { config } from 'config';

import Headroom from 'react-headroom';

import Nav from './nav.js';

import '../css/main.scss';

import Modal from 'boron/DropModal';

import {Input, Label,Textarea, Button} from 're-bulma';

const modalStyle = {
  minHeight: '500px',
  backgroundColor: '#303841'
};

const backdropStyle = {
  backgroundColor: '#F6C90E'
};

const contentStyle = {
  backgroundColor: '#303841',
  padding: '3rem'
};

const gotcha = {
  display: 'none'
};

const email = 'https://formspree.io/[email protected]';




export default class RootTemplate extends React.Component {
  static propTypes = {
    location: React.PropTypes.object.isRequired,
    children: React.PropTypes.object.isRequired,
  }

  static contextTypes = {
    router: React.PropTypes.object.isRequired,
  }

  constructor() {
    super();
    this.showModal = this.showModal.bind(this);
  }

  showModal () {
    this.refs.modal.show();
  }

  formSubmit(e) {
    e.preventDefault();
    let data = {
      name: this.refs.name.value,
      email: this.refs.email.value,
      message: this.refs.message.value
    }
    return new Promise((resolve, reject) => {
      const req = new XMLHttpRequest();
      req.open('POST', email);
    });
    console.log(data);
  }

  render() {
    return (
      <div>
        <Headroom>
          <Nav showModal={this.showModal}/>
        </Headroom>
        <Modal ref="modal" modalStyle={modalStyle} contentStyle={contentStyle} backdropStyle={backdropStyle}>
          <form ref='contact_form' onSubmit={::this.formSubmit}>
            <Label>Name:</Label>
            <Input ref="name" />
            <Label>Email:</Label>
            <Input ref="email" type="email"/>
            <Label>Message:</Label>
            <Textarea ref="message" />
            <Input type="text" name="_gotcha" style={gotcha}/>
            <Button buttonStyle="isOutlined" color="isWarning">Submit</Button>
          </form>
        </Modal>
        {this.props.children}
      </div>
    );
  }
}

I also currently get this error:

Object {name: undefined, email: undefined, message: undefined}

Any help would be greatly appreciated. Really trying to learn.

4
  • I recommend to read the MDN documentation about Promise and have a look at How do I return the response from an asynchronous call? Commented Oct 23, 2016 at 19:14
  • @FelixKling I'm just having a hard time wrapping my head around it. The reason for this project is to use real world examples. Also, not sure why I'm getting undefined from the ref. Commented Oct 23, 2016 at 19:26
  • @Dileet Your error, is from the API? Is the post executed? Thanks. Commented Oct 23, 2016 at 22:19
  • @chemitaxis I followed harabara's answer below and get a POST 400 error now Commented Oct 23, 2016 at 22:34

3 Answers 3

2

I might be wrong but from what I see you barely need to use Promise here. Try this instead

formSubmit = (e) => {
    e.preventDefault();
    const {name, email, message} = this.refs
    const formData = new FormData();
    formData.append("name", name.value);
    formData.append("email", email.value);
    formData.append("message", message.value);
    const req = new XMLHttpRequest();
    req.open('POST', url);
    req.send(formData);
  }

And I renamed previosley defined cosnt email to url

Sign up to request clarification or add additional context in comments.

1 Comment

Ok, I will check.
1

you could try fetch.

Example promise code:

var form = document.querySelector('form')


function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response
  } else {
    var error = new Error(response.statusText)
    error.response = response
    throw error
  }
}

function parseJSON(response) {
  return response.json()
}

    fetch('/users',{
       method: 'POST',
       body: new FormData(form)
       })
      .then(checkStatus)
      .then(parseJSON)
      .then(function(data) {
        console.log('request succeeded with JSON response', data)
      }).catch(function(error) {
        console.log('request failed', error)
      })

4 Comments

Do I add the fetch inside a function so I can call it on the onSubmit?
should I place the fetch code inside the formSubmit function I have in my code?
Yes. Check too in the brower (Chrome) the values of the params that you are sending in the body of the post ;)
This is my code formSubmit = (e) => { e.preventDefault(); let form = document.querySelector('form') fetch(url,{ method: 'POST', body: new FormData(form) }) .then(checkStatus) .then(parseJSON) .then(function(data) { console.log('request succeeded with JSON response', data) }).catch(function(error) { console.log('request failed', error) }) }
0

I finally figured it out. Thanks for all the help to everyone. The main issue was that the re-bulma npm library didn't allow "ref" for their <Input /> component. So I opted to the regular html input. I'm also using the Axios library to handle the request. This my updated code below, hope this helps someone.

formSubmit (e){
    e.preventDefault();

    let form = document.querySelector('form') 

    let name = this.nameRef.value
    let email = this.emailRef.value
    let message = this.messageRef.value


    axios.post(url, {
      data: {
        name: name,
        email: email,
        message: message
      }
    })
    .then(function (response) {
      console.log(response);
      form.reset()
    })
    .catch(function(error) {
      console.log(error);
      form.reset()
    });
  }

And the form markup:

 <form onSubmit={::this.formSubmit}>
     <div className="formInput">
        <input type="text" placeholder="Name" ref={(input) => this.nameRef = input} />
      </div>
      <div className="formInput">
        <input type="email" placeholder="Email" ref={(input)=> this.emailRef = input} />
      </div>
      <div className="formInput">
        <textarea placeholder="Message" ref={(input) => this.messageRef = input} />
      </div>
      <input type="text" name="_gotcha" style={gotcha}/>
      <div className="formInput">
        <Button buttonStyle="isOutlined" color="isWarning">Submit</Button>
      </div>
  </form>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.