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/dillonraphael@gmail.com';




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.

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
Dileet
  • 2,034
  • 3
  • 33
  • 53
  • I recommend to read the [MDN documentation about `Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) and have a look at [How do I return the response from an asynchronous call?](http://stackoverflow.com/q/14220321/218196) – Felix Kling Oct 23 '16 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. – Dileet Oct 23 '16 at 19:26
  • @Dileet Your error, is from the API? Is the post executed? Thanks. – chemitaxis Oct 23 '16 at 22:19
  • @chemitaxis I followed harabara's answer below and get a POST 400 error now – Dileet Oct 23 '16 at 22:34

3 Answers3

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

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)
      })
chemitaxis
  • 13,889
  • 17
  • 74
  • 125
  • Do I add the fetch inside a function so I can call it on the onSubmit? – Dileet Oct 23 '16 at 22:38
  • should I place the fetch code inside the formSubmit function I have in my code? – Dileet Oct 23 '16 at 22:41
  • Yes. Check too in the brower (Chrome) the values of the params that you are sending in the body of the post ;) – chemitaxis Oct 23 '16 at 22:43
  • 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) }) }` – Dileet Oct 23 '16 at 23:43
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>
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Dileet
  • 2,034
  • 3
  • 33
  • 53