0
votes

I am using Flask to create a POST method to register a new user in my MySQL database. I tried created an Axios method to send the POST request from my React JS application. I was testing with Postman, and I am sending it using application/x-www-form-urlencoded. The registration works in Postman, but the data comes up as ImmutableMultiDict([]).

Flask code:

@app.route('/registerUser', methods=['POST'])
def registerUser():
    data = request.form
        if len(data) is 0:
            return 'Request was empty!'
        username = data['username']
        password = data['password']
        email = data['email']
        user = User(username=username, 
                    password=password, 
                    email=email)
        db.session.add(user)
        db.session.commit()
        return 'Registration success!'
    return 'Registration failed!'

React code:

class Signup extends Component {
    constructor(props){
        super(props);
        this.state = {
            username: '',
            password: '',
            email: ''
        }
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.clearInputs = this.clearInputs.bind(this);
    }

    handleChange(event){
        event.preventDefault();
        this.setState({[event.target.name]: event.target.value});
    }
    handleSubmit(event){
        event.preventDefault();
        const config = {
            headers: { 'content-type': 'application/x-www-form-urlencoded' }
        }
        axios.post(`http://localhost:5000/registerUser`, 
            this.state, config)
             .then(res => {
                alert(res.data);
             })
             .catch((err) => {
                alert(err);
             });
    }

    render(){
        return (
            <div className='signup'>
                <form onSubmit={this.handleSubmit}>
                    <label>
                        Username
                        <input type='text' name='username' 
                               value={this.state.username}
                               onChange={this.handleChange}/><br/>
                    </label>
                    <label>
                        Password
                        <input type='password' name='password' 
                               value={this.state.password} 
                               onChange={this.handleChange}/><br/>
                    </label>
                    <label>
                        Email
                        <input type='text' name='email' 
                               value={this.state.email}
                               onChange={this.handleChange}/><br/>
                    </label>
                    <input type='submit' value='Submit' /><br/>
                </form>
            </div>
        );
    }
}

export default Signup;

Why is the data not properly sending from Axios? I am using CORS in flask, and both Postman and Axios should be sending the same form data.

EDIT: I changed the POST request to use request.form However, Postman works, but Axios still doesn't. From Postman:

ImmutableMultiDict([('username', 'person'), ('password', 'Password1'), ('email', '[email protected]')])

From Axios: ImmutableMultiDict([('{"username":"someone","password":"Password1","email":"[email protected]"}', '')])

Is Axios misconfigured?

2

2 Answers

2
votes

I figured out the problem. By default, Axios sends data by JSON format. In order to comply with urlencoded, you would need to build a new URLSearchParams object to send instead. See the documentation

This is the working React code:

handleSubmit(event){
    event.preventDefault();
    const config = {
        headers: { 'content-type': 'application/x-www-form-urlencoded' }
    }
    const getParams = (obj) => {
        const params = new URLSearchParams();
        const keys = Object.keys(obj);
        for(let k of keys){
            params.append(k, obj[k]);
        }
        return params;
    }
    axios.post(`http://localhost:5000/registerUser`, 
        getParams(this.state), config)
         .then(res => {
            alert(res.data);
            this.clearInputs();
         })
         .catch((err) => {
            alert(err);
         });
}

This works with my OP Flask code.

0
votes

I think you will have to coerce the request data into type JSON within your registerUser route since you're trying to access a JSON response but you sent the request over in application/x-www-form-urlencoded format. application/x-www-form-urlencoded is the default form content type specification created by the W3C and is usually used to send text/ASCII data. Maybe you could try the following and see if you get the expected JSON response:

app.route('/registerUser', methods=['POST'])
def registerUser():
    requestJson = request.get_json(force=True)

    # check that requestJson is correct if so
    # create and save your new user to your db

    return 'Registration failed!'

If your requestJson is as expected then you can just pull out the required fields and save your new user to your database. If not please print out the request you're receiving to see how it can be appropriately parsed.

Hopefully that helps!