Reputation: 465
I am trying to create a book app i have react on the front and node js on the backend. When i tried to create in backend its say Cannot POST /create.What do i have to do ,the folder is divided into front end and backend. i am using axios.I am new to react js please help.How can i pass data from a form in react to express to save.
this is the react component create
import React, {Component} from 'react';
class Create extends Component{
render(){
return(
<div>
<br/>
<div class="container">
<form action="http://127.0.0.1:3000/create" method="post">
<div style={{width: '30%'}} class="form-group">
<input type="text" class="form-control" name="BookID" placeholder="Book ID"/>
</div>
<br/>
<div style={{width: '30%'}} class="form-group">
<input type="text" class="form-control" name="Title" placeholder="Book Title"/>
</div>
<br/>
<div style={{width: '30%'}} class="form-group">
<input type="text" class="form-control" name="Author" placeholder="Book Author"/>
</div>
<br/>
<div style={{width: '30%'}}>
<button class="btn btn-success" type="submit">Create</button>
</div>
</form>
</div>
</div>
)
}
}
export default Create;
this index.js in the backend
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var cors = require('cors');
app.set('view engine', 'ejs');
//use cors to allow cross origin resource sharing
app.use(cors({
origin: 'http://localhost:3000',
credentials: true
}));
var books = [{
"BookID": "1",
"Title": "Book 1",
"Author": "Author 1"
},
{
"BookID": "2",
"Title": "Book 2",
"Author": "Author 2"
},
{
"BookID": "3",
"Title": "Book 3",
"Author": "Author 3"
}
]
app.get('/home', function (req, res) {
console.log("Inside Home Login");
res.writeHead(200, {
'Content-Type': 'application/json'
});
console.log("Books : ", JSON.stringify(books));
res.end(JSON.stringify(books));
})
app.post('/create', function (req, res) {
var newBook = {
"BookID": req.body.BookID,
"Title": req.body.Title,
"Author": req.body.Author
}
books.push(newBook)
console.log(books);
})
//start your server on port 3001
app.listen(3001);
console.log("Server Listening on port 3001");
Upvotes: 8
Views: 50676
Reputation: 2185
There were a few errors. Here is some updated code and a description of what was going on:
React App.js:
import React, { Component } from 'react';
import axios from 'axios';
class Create extends Component {
constructor(props) {
super(props);
this.state = {
bookID: '',
bookTitle: '',
bookAuthor: '',
};
}
handleInputChange = e => {
this.setState({
[e.target.name]: e.target.value,
});
};
handleSubmit = e => {
e.preventDefault();
const { bookID, bookTitle, bookAuthor } = this.state;
const book = {
bookID,
bookTitle,
bookAuthor,
};
axios
.post('http://localhost:3001/create', book)
.then(() => console.log('Book Created'))
.catch(err => {
console.error(err);
});
};
render() {
return (
<div>
<br />
<div className="container">
<form onSubmit={this.handleSubmit}>
<div style={{ width: '30%' }} className="form-group">
<input
type="text"
className="form-control"
name="bookID"
placeholder="Book ID"
onChange={this.handleInputChange}
/>
</div>
<br />
<div style={{ width: '30%' }} className="form-group">
<input
type="text"
className="form-control"
name="bookTitle"
placeholder="Book Title"
onChange={this.handleInputChange}
/>
</div>
<br />
<div style={{ width: '30%' }} className="form-group">
<input
type="text"
className="form-control"
name="bookAuthor"
placeholder="Book Author"
onChange={this.handleInputChange}
/>
</div>
<br />
<div style={{ width: '30%' }}>
<button className="btn btn-success" type="submit">
Create
</button>
</div>
</form>
</div>
</div>
);
}
}
export default Create;
class
and not className
. class
is a reserved word in react.js and should not be used.axios
to make the CORS post call. I also created a function to handle the input changing on every key press with react.js.state
to your component. This is common when there are form inputs to store them in state
. I also changed the name of your variables to be title case which is the common way to write code variables.Node.js index.js:
const express = require('express');
const logger = require('morgan');
const cors = require('cors');
const app = express();
//use cors to allow cross origin resource sharing
app.use(
cors({
origin: 'http://localhost:3000',
credentials: true,
})
);
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
let books = [];
app.get('/home', function(req, res) {
console.log('Inside Home Login');
res.writeHead(200, {
'Content-Type': 'application/json',
});
console.log('Books : ', JSON.stringify(books));
res.end(JSON.stringify(books));
});
app.post('/create', function(req, res) {
const newBook = {
BookID: req.body.bookID,
Title: req.body.bookTitle,
Author: req.body.bookAuthor,
};
books.push(newBook);
console.log(books);
});
//start your server on port 3001
app.listen(3001, () => {
console.log('Server Listening on port 3001');
});
app.use(express.json());
and
app.use(express.urlencoded({ extended: false }));
which should
take care of most of the issues.req.body
variables to match those coming over from
React.morgen
which you see here app.use(logger('dev'));
this is helpful by showing all your requests and statuses for dev purposes. In this case, it was showing that you were getting a 500 (internal server error) because express couldn't read bookID
of undefined
(because the body wasn't being parsed).This should be working now, let me know if you have any problems.
Upvotes: 20
Reputation: 342
You should have some kind of response on your /create
endpoint
For example:
app.post('/create', function (req, res) {
var newBook = {
"BookID": req.body.BookID,
"Title": req.body.Title,
"Author": req.body.Author
}
books.push(newBook)
console.log(books);
res.status(201).json({"some":"response"})
})
Upvotes: 0
Reputation: 265
I don't use express some so the details may not apply.
In essence you will have to send a network request to your server. How you do this is up to you, The most common ways are with axios(a library) or with vanilla js with the fetch api.
I would just use the fetch api. it takes two parameters an url and the options. so it should be called like this fetch(url,options)
so in your case it would be fetch('localhost:3001/create, options)
What should be in the options. I just suggest you look at the fecth MDN docs here https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
but your case you will need to pass an object with the method property set to post and the new book you want to data property set to a JSON serialized object of the book you want to create.
for example
let book ={
BookId:1,
Title: "coolBook",
Author: "Me"
}
fetch("localhost:3001/create",
{
method: "post",
data: JSON.stringify(book)
}
When passing the books a string instead of an object you will likely have to take that string and parse it as an object on the server so that you express /create handler looks more like:
app.post('/create', function (req, res) {
var newBook = JSON.parse(req.body.data)
books.push(newBook)
console.log(books);
})
On the react side you need to create an event handler that calls the above fetch function. I recommend you watch a react/express tutorial though as I can;t really cover all the thing required here in a stack overflow question such as: using and validating forms in react, error handling, async/await and so on.
All the Best! hope that was slightly helpful
Upvotes: 0