AxleCat
AxleCat

Reputation: 57

How to post data from ReactJS to NodeJS Express API

I need to take the forma data submitted in ReactJS (JSX) and submit it to the app.post method in my Express API backend. I've looked for ages on how to do this, but I still have no idea.

My front-end form code:

import React, { Component } from 'react'
import '../public/styles/App.css'
import Header from "./header.js"

export default class Login extends Component {

    render() {
        return(   
            <div style={{border:"none"}}>
                <div style={{background:"white"}}>
                    <br></br>
                    <center><Header /></center>
                    <br></br>
                </div>
                <br></br>
                <br></br>
                <div style={{background:"white"}}>
                    <center><form>
                        <br></br>
                        Username: <br></br>
                        <input type = "text" name= "username"></input>
                        <br></br>
                        <br></br>
                        Password: <br></br>
                        <input type = "text" name = "password"></input>
                        <br></br>
                        <br></br>
                        <input type = "submit" value = "Log-in"></input>
                        <br></br>
                    </form></center>
                    <br></br>
                </div>
            </div>
        )
    }
}

Express post method:

app.post("/api/login", async(req, res) => {
    const id = await users.login(req.body.user, req.body.pass)
    console.log(id)

Not sure what params the express post needs to take it, or how to send it via the component in ReactJS. Any rough idea on how to send form data from ReactJS to NodeJS Express api would be great!

Upvotes: 2

Views: 8260

Answers (3)

Rohit Kashyap
Rohit Kashyap

Reputation: 1592

I am sure that the above mentioned answers work, but here is a beginner friendly approach using axios and concurrently.

Do a npm install for axios and concurrently.

Here's what your login file can do:

import React from 'react';
import '../public/styles/App.css'
import Header from "./header.js"
import Axios from 'axios'

class Login extends React.Component {

    constructor(props) {

        super(props);

        this.state = {

            username: '',
            password: ''
        };
    }

    handleInputChange = (e) => {

        this.setState({

            [e.target.name]: e.target.value

        });
    }

    handleSubmit = (e) => {

        e.preventDefault();

        const url = 'YOUR BACKEND URL HERE';

        const user = {

            username: this.state.username, 
            password: this.state.password
        }

        Axios.post(url, user).then((res) => {

            //handle your login 

        }).catch((e) => {

            //handle your errors
        });

    }

    render() {

        return (

            <div style={{border:"none"}}>
                <div style={{background:"white"}}>
                    <br></br>
                    <center><Header /></center>
                    <br></br>
                </div>
                <br></br>
                <br></br>
                <div style={{background:"white"}}>
                    <center>
                    <form onSubmit={this.handleSubmit}>
                        <br></br>
                        Username: <br></br>
                        <input type = "text" onChange={this.handleInputChange} name= "username"></input>
                        <br></br>
                        <br></br>
                        Password: <br></br>
                        <input type = "password" name = "password" onChange={this.handleInputChange}></input>
                        <br></br>
                        <br></br>
                        <input type = "submit" value = "Log-in"></input>
                        <br></br>
                    </form>
                  </center>
                    <br></br>
                </div>
            </div>

        );
    } 
}

export default Login;

Concurrently allows you to run your node backend server and the react app at once. In your node project folder (backend) open package.json and configure it as follows:

This is just a rough example:

{
  "name": "dev-proj",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "client-install": "npm install --prefix client",
    "start": "node app.js",
    "server": "nodemon app.js",
    "client": "npm start --prefix client",
    "dev": "concurrently \"npm run server\" \"npm run client\""
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bcryptjs": "^2.4.3",
    "express": "^4.16.3",  
  }
}

Read the concurrently documentation for more extensive examples.

I am using Nodemon to run my server (app.js). Also, the react project in my case is inside the client folder hence the above configration.

In your react project folder, open package.json and add the following line:

"proxy": "http://localhost:5000"

Considering your backend server is running on port 5000.

Upvotes: 3

Atakan Atamert
Atakan Atamert

Reputation: 235

Your form is empty, it basically has no attributes to send it to a route. As a result, your frontend code does not connect with the back-end side.

Just add <form action="/api/login" method="POST"> it should work.

Upvotes: 0

Varghese Mathai
Varghese Mathai

Reputation: 411

To use fetch to POST the data (in JSON) :

fetch("<--url-->", {
    method: 'POST',
    body: JSON.stringify({"user": this.state.username,
                            "pass": this.state.password}),
    headers: {
        'Content-Type': 'applications/json'
    }
})
.then(res => res.json())
.then(
    (result) => {
        //callback for the response
    }
);

In react, you need to use states to store the values of those textboxes. The states are changed using event that is triggered when the textbox values are changed:

<form>
   <br></br>
   Username: <br></br>
   <input type = "text" name= "username" onChange={this.handleUserNameChange}></input>
   <br></br>
   <br></br>
   Password: <br></br>
   <input type = "text" name = "password" onChange={this.handlePasswordChange}></input>
   <br></br>
   <br></br>
   <input type = "submit" value = "Log-in"></input>
   <br></br>
</form>

The handlers can be defined as:

handleUserNameChange = event => {
    this.setState({username: event.target.value});
}

handlePasswordChange = event => {
    this.setState({username: event.target.value});
}

Also don't forget to define those states:

constructor(props) {
    super(props);
    this.state = {
        username: "",
        password: ""
    }
}

Upvotes: 2

Related Questions