0

I'm trying to send data to my Flask API to get data into my database, but I keep getting the following error: OPTIONS /createUser HTTP/1.1" 400

Reg.js

import React, { Component } from 'react';  

class Reg extends Component {  

  constructor() {  
    super();  

    this.state = {  
      FirstName: '',  
      LastName: '',  
      Email: '',  
      Password: '' 
    }  

    this.Email = this.Email.bind(this);  
    this.Password = this.Password.bind(this);  
    this.FirstName = this.FirstName.bind(this);  
    this.LastName = this.LastName.bind(this);   
    this.register = this.register.bind(this);  
  }  

  Email(event) {  
    this.setState({ Email: event.target.value })  
  }   

  Password(event) {  
    this.setState({ Password: event.target.value })  
  }  
  FirstName(event) {  
    this.setState({ FirstName: event.target.value })  
  }  
  LastName(event) {  
    this.setState({ LastName: event.target.value })  
  }  

  register(event) {  

    fetch('http://localhost:5000/createUser', {  
      method: 'post',  
      headers: {  
        'Accept': 'application/json',  
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin':'*' 
      },  
      body: JSON.stringify({  
        "FirstName": this.state.FirstName,  
        "Password": this.state.Password,  
        "Email": this.state.Email,  
        "LastName": this.state.LastName 
      })  
    }).then(function(res){
      return res.json();
    }).then(function(data){
      console.log(data);
    }).catch((error) => {
      console.log(error);
    });
  }  

  render() {  

    return (  
      <div>  
        <form className="form" id="addItemForm">
            <input type="text"  onChange={this.FirstName} placeholder="Enter First Name"/>
            <input type="text"  onChange={this.LastName} placeholder="Enter Last Name"/>
            <input type="text"  onChange={this.Email} placeholder="Enter Email"/>
            <input type="password"  onChange={this.Password} placeholder="Enter Password"/>
            <button  onClick={this.register}  color="success" block>Create Account</button>
        </form>
      </div>  
    );  
  }  
}  

export default Reg; 

This is what my Flask API has

@main.route('/createUser', methods=['POST', 'OPTIONS'])
def createUser():
    conn = connection()
    cur = conn.cursor()

    req = request.get_json()
    first = req.get('FirstName')
    last = req.get('LastName')
    email = req.get('Email')
    pw = req.get('Password')

    sql = "INSERT INTO User (first, last, emailAddress, password) VALUES (?, ?, ?, ?)"
    data = (first, last, email, pw)
    cur.execute(sql, data)

    conn.commit()
    cur.close()

    return 'Done', 201

I've tried changing my JSON in case it was malformed, but it didn't change anything. I also tried posting from postman and it works fine from there so I'm thinking its the javascript.

6
  • try to use Axios for Http request in react js. you can refer to this doc Commented Feb 11, 2020 at 5:31
  • Your states' value should not be changing on event? Can you console.log them and post a snippet in here? Commented Feb 11, 2020 at 5:36
  • @Jawadulhassan where do I go about logging them? Commented Feb 11, 2020 at 5:41
  • Log them under render() and above return. Commented Feb 11, 2020 at 5:52
  • I'm wondering what the return type from the flask route is - you return simply "Done", 201 - that means most likely plain text, with 201 created. In your javascript, you try to parse JSON but you are not returning json. Has your user been created? Commented Feb 11, 2020 at 6:34

4 Answers 4

1

Try to add CORS extension if you are using Chrome and you should enable CORS in backend like springboot @CrossOrigin(origins="http://localhost:3000")

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

1 Comment

I have CORS imported for flask and added CORS extension and it didn't change anything.
0

Try to use this in the block when you retrieve data from the request. 400 error is usually a sign of that server can't get values from your POST request body.

req = request.json
first = req['FirstName']
last = req['LastName']

1 Comment

I got the following error: TypeError: 'NoneType' object is not subscriptable
0

You can also trastically shorten your Code Part By using Name fields in your input Form Tags like name=Email and designing an universal change handler like so:

onChange(event) {  
    this.setState({ event.target.name: event.target.value })  
  }   

Comments

0

From your error message error: OPTIONS /createUser HTTP/1.1" 400, the OPTIONS request is not handled correctly. I guess, Postman is not doing a OPTIONS request by default, so that case works for you. In addition, the route is not returning any json, so return res.json(); //error here fails if it's plain text.

I have modified your example with plain Flask methods. Note: I have also removed the 'Access-Control-Allow-Origin':'*' request header from the Javascript.

@main.route('/createUser', methods=['POST', 'OPTIONS'])
def createUser():
    # handle option request
    if request.method == "OPTIONS":
        response = make_response()
        response.headers["Access-Control-Allow-Origin"] = "*"
        response.headers[
            "Access-Control-Allow-Headers"
        ] = "Origin, Accept, Content-Type"
        response.headers["Access-Control-Allow-Methods"] = "POST,OPTIONS"
        response.headers["Access-Control-Allow-Credentials"] = "true"
        return response

    if request.method == "POST":
        # do your SQL stuff
        conn = connection()
        cur = conn.cursor()

        req = request.get_json()
        first = req.get("FirstName")
        last = req.get("LastName")
        email = req.get("Email")
        pw = req.get("Password")

        sql = (
            "INSERT INTO User (first, last, emailAddress, password) VALUES (?, ?, ?, ?)"
        )
        data = (first, last, email, pw)
        cur.execute(sql, data)

        conn.commit()
        cur.close()

        # make response
        response = make_response("{}")  # return empty JSON response
        response.headers["Access-Control-Allow-Origin"] = "*"
        response.headers[
            "Content-Type"
        ] = "application/json"  # set response type to JSON
        return response

    return "", 405  # method not allowed

And please don't save passwords in plaintext in your database :-)

6 Comments

I changed it and nothing happens. Is it because my code for react is sending an OPTIONS request even though I specified it to be a POST (although I'm reading that it is because of CORS pre-flight request, which I don't entirely understand)?
The browser always sends an OPTION request before the "regular" (GET, POST, PUT..) request to check if the resource is allowed. What is the error message in the browser?
flask outputs "[13/Feb/2020 23:39:46] "OPTIONS /createUser HTTP/1.1" 200 ", but I log the states and they come out empty and nothing gets inserted into the database
The option request looks good to me - what happens inside the post method? Any logs from the browser?
The post request does not hit the server? You just see the options request? What does your Postman request say?
|

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.