Change state and update it in the database - node.js

I'm working on a web app to track fruits vendor stock using React.js, MongoDB, Node.js, and Express. I called my database endpoints to render the data in the table. Now I try to increment and decrement the stock amount using a button, but when I try to set the new state, it doesn't work. I try to change the state by clicking, then update the new state in the database. Any advice?
FruitTable component:
import Reac, { Component } from 'react';
import * as ReactBootstrap from 'react-bootstrap';
import axios from 'axios';
import Button from 'react-bootstrap/Button';
class FruitTable extends Component {
constructor(props) {
super(props)
this.state = {
fruits: []
}
this.handleClick = this.handleClick.bind(this)
}
componentDidMount() {
axios.get('http://localhost:5000/fruits/')
.then(res => {
this.setState({
fruits: res.data
});
})
.catch((error) => {
console.log(error)
})
}
handleClick = () => {
const fruits = [...this.state.fruits]
this.setState({fruits: this.state.fruits[1] +1})
}
render() {
return(
<div>
<h1>Fruit Vendor Stock</h1>
<ReactBootstrap.Table striped bordered hover size="sm">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Stock</th>
<th>Price</th>
<th>Add/Reomve</th>
</tr>
</thead>
<tbody>
{
this.state.fruits.map((fruit, index) => (
<tr>
<th scope="row">{index + 1}</th>
<td>{fruit.name}</td>
<td>{fruit.stock}</td>
<td>{fruit.price}</td>
<td>
<div className="mb2">
<Button className="btn btn-primary btn-sm"
onClick={this.handleClick}
>Add</Button>{' '}
<Button className="btn btn-danger btn-sm"
>Remove</Button>
</div>
</td>
</tr>
))
}
</tbody>
</ReactBootstrap.Table>
</div>
)
};
}
export default FruitTable;
FruitsData.model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const fruits = new Schema({
name: { type: String, required: true },
stock: { type: Number, required: true },
price: { type: Number, required: true },
}, {
});
const Fruits = mongoose.model('Fruits', fruits);
module.exports = Fruits;
-Routes:
const router = require('express').Router();
let Fruit = require('../models/fruit_data');
router.route('/').get((req, res) => {
Fruit.find()
.then(fruits => res.json(fruits))
.catch(err => res.status(400).json('Error: ' + err));
});
router.route('/add').post((req, res) => {
const name = req.body.name;
const stock = Number(req.body.stock);
const price = Number(req.body.price);
const newFruit = new Fruit({
name,
stock,
price,
});
newFruit.save()
.then(() => res.json('Fruit has been added!'))
.catch(err => res.status(400).json('Error: ' + err));
});
router.route('/:id').get((req, res) => {
Fruit.findById(req.params.id)
.then(Fruit => res.json(Fruit))
.catch(err => res.status(400).json('Error: ' + err));
});
router.route('/:id').delete((req, res) => {
Fruit.findByIdAndDelete(req.params.id)
.then(() => res.json('Fruit has deleted.'))
.catch(err => res.status(400).json("Error: " + err));
});
router.route('/update/:id').put((req, res, next) => {
Fruit.findByIdAndUpdate(req.params.id, {
$set: req.body
}, (error, data) => {
if(error) {
return next(error);
console.log(error)
} else {
res.json(data)
console.log('Stock has been updated')
}
})
})
module.exports = router;
-Server.js:
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
const port = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, { useNewUrlParser: true });
const connection = mongoose.connection;
connection.once('open', () => {
console.log("MongoDb database connection established successfully!!")
})
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const fruitsRouter = require('./routes/fruit');
app.use('/fruits', fruitsRouter);
app.listen(port, () => {
console.log(`Server is running on port: ${port}`);
})
-App.js:
import "./App.css";
import React, { Component, useState, useEffect } from "react";
import FruitTable from "./Components/fruitTable";
import "bootstrap/dist/css/bootstrap.min.css";
import { sendEmail } from "./service/emailService";
import axios from 'axios';
function App() {
return (
<div className="App">
<FruitTable />
</div>
);
}
export default App;

The state update in handleClick isn't correct, it is taking the 1th element value, adding 1 to it, and setting this as the this.state.fruits state value. This breaks the state invariant of fruits being an array. This is likely the "crash" you are seeing as a non-array value is attempted to be mapped.
handleClick = () => {
const fruits = [...this.state.fruits]
this.setState({
fruits: this.state.fruits[1] +1 // <-- mutates state invariant!!
})
}
The code also isn't passing a reference to which index or fruit it is trying to update.
According to your schema the fruit items have 3 properties, name, stock, and price. For this solution I'll assume that name is sufficiently unique for identification purposes and that you are incrementing/decrementing the stock quantity.
handleClick = (name, addQuantity = 1) => () => {
this.setState(prevState => ({
fruits: prevState.fruits.map(fruit =>
fruit.name === name
? { ...fruit, stock: fruit.stock + addQuantity}
: fruit
)
}));
}
Now you need to pass the currently mapped fruit item's name property to the handler when mapping.
{this.state.fruits.map((fruit, index) => (
<tr key={fruit.name}>
<th scope="row">{index + 1}</th>
<td>{fruit.name}</td>
<td>{fruit.stock}</td>
<td>{fruit.price}</td>
<td>
<div className="mb2">
<Button
className="btn btn-primary btn-sm"
onClick={this.handleClick(item.name, 1)} // <-- add one
>
Add
</Button>{' '}
<Button
className="btn btn-danger btn-sm"
onClick={this.handleClick(item.name, -1)} // remove one
>
Remove
</Button>
</div>
</td>
</tr>
))}

Related

React+Node webpage - Update endpoint throws 404 error

I have setup a webpage to search a number via user input and if it's available in the SQL Server database, 2 text boxes would show up with the data using AXIOS GET endpoint. Then I'm trying to get those ID's of the data rows and if the user needs to UPDATE it, then UPDATE it via AXIOS PUT endpoint. The issue is once user clicks the UPDATE button it throws an error PUT http://localhost:5000/api/customerOrder/[object%20Object],[object%20Object] 404 (Not Found)
Here's what I've tried
Server endpoints :
dboperations.js
var config = require('./dbconfig');
const sql = require('mssql');
async function getallcustomerOrders(){
try{
let pool = await sql.connect(config);
let orders = await pool.request()
.query("SELECT * FROM [100].[dbo].[OELINCMT_SQL] order by ID desc");
return orders.recordsets;
}
catch (error){
console.log(error);
}
}
async function getcustomerOrders(orderNumber){
try{
let pool = await sql.connect(config);
let orders = await pool.request()
.input('input_parameter', sql.NChar, orderNumber)
.query("SELECT ID,cmt FROM [100].[dbo].[OELINCMT_SQL] where LTRIM(ord_no) = LTRIM(#input_parameter)");
return orders.recordsets;
}
catch (error){
console.log(error);
}
}
async function updateComments(ID){
try {
let pool = await sql.connect(config);
let orders = await pool.request()
.input('ID', sql.NChar, ID)
.query(`SELECT ID,cmt FROM [100].[dbo].[OELINCMT_SQL] WHERE ID = #ID`);
let order = orders.recordset.length ? orders.recordset[0] : null;
if (order) {
await pool.request()
.input('cmt', req.body.cmt)
.query(`UPDATE [100].[dbo].[OELINCMT_SQL] SET cmt = #cmt WHERE ID = #ID;`);
order = { ...order, ...req.body };
res.json(order);
} else {
res.status(404).json({
message: 'Record not found'
});
}
} catch (error) {
res.status(500).json(error);
}
}
module.exports = {
getallcustomerOrders : getallcustomerOrders,
getcustomerOrders : getcustomerOrders,
updateComments : updateComments
}
api.js
var Db = require('./dboperations');
var dboperations = require('./dboperations');
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
const { request, response } = require('express');
var app = express();
var router = express.Router();
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
app.use(cors());
app.use('/api', router);
router.use((request,response,next)=> {
console.log('middleware');
next();
})
router.route('/customerOrder').get((request,response)=>{
dboperations.getallcustomerOrders().then(result => {
response.json(result[0]);
console.log(result[0]);
})
})
router.route('/customerOrder/:orderNumber').get((request,response)=>{
dboperations.getcustomerOrders(request.params.orderNumber).then(result => {
response.json(result[0]);
console.log(result[0]);
})
})
router.route('customerOrder/:ID').put((request,response)=>{
dboperations.updateComments(request.params.ID).then(result => {
response.json(result[0]);
console.log(result[0]);
})
})
var port = process.env.PORT || 5000;
app.listen(port);
console.log('Customer Order API is running at ' + port);
dboperations.getcustomerOrders().then(result => {
console.log(result);
})
dboperations.getallcustomerOrders().then(result => {
console.log(result);
})
dboperations.updateComments().then(result => {
console.log(result);
})
Client :
EmailFaxDetails.js : This is the page user enters the number
import React, { useState,useEffect } from 'react'
import FetchOrderDetails from './FetchOrderDetails';
import axios from 'axios'
import '../App.css';
const EmailFaxDetails = () => {
const [orderNumber, setOrderNumber] = useState('');
const [id, setId] = useState([]);
const [isShown, setIsShown] = useState(false);
const url = `http://localhost:5000/api/customerOrder/${orderNumber}`
useEffect(() => {
axios.get(url)
.then(response => {
console.log(response.data)
setId(response.data)
})
.catch((err) => console.log(err));
}, [url]);
const handleChange = event => {
setOrderNumber(event.target.value);
console.log(event.target.value);
};
const handleClick = event => {
event.preventDefault();
setIsShown(true);
console.log(orderNumber);
}
return(
<div>
<br></br>
<br></br>
Order Number: <input placeholder="Order Number" type="text" id="message" name="message" onChange={handleChange} value={orderNumber} autoComplete="off" />
{id.map((idnum) => (
<div key={idnum.ID}>
<br></br>
ID : {idnum.ID}
</div>
))}
<button onClick={handleClick}>Search</button>
{isShown && <FetchOrderDetails ord_no={orderNumber} ID={id}/>}
</div>
)
}
export default EmailFaxDetails;
FetchOrderDetails.js : In this page user get's the output if the number is available in SQL server and let then UPDATE accordingly.
import React, { useEffect, useState } from 'react'
import axios from 'axios'
import '../App.css';
const FetchOrderDetails = ({ord_no,ID}) => {
const [data, setData] = useState([]);
const url = `http://localhost:5000/api/customerOrder/${ord_no}`
useEffect(() => {
axios.get(url)
.then(response => {
console.log(response.data)
setData(response.data)
})
.catch((err) => console.log(err));
}, [url]);
const url2 = `http://localhost:5000/api/customerOrder/${ID}`
const onSubmit = () => {
axios.put(url2)
.then((response) => {
if (response.status === 200) {
alert("Comment successfully updated");
ID.history.push(`/customerOrder/${ord_no}`);
} else Promise.reject();
})
.catch((err) => alert("Something went wrong"));
}
if(data) {
return(
<div>
{data.map((order) => (
<div key={order.ID}>
<br></br>
ID : {order.ID}
<br></br>
Email/Fax: <input defaultValue={order.cmt} placeholder="Sales Ack Email" id="salesAck" style={{width: "370px"}} />
</div>
))}
<div>
<br></br>
<br></br>
<button onClick={onSubmit}>Update</button>
</div>
</div>
)
}
return (
<h1>Something went wrong, please contact IT!</h1>
)
}
export default FetchOrderDetails;
What I suspect is the issue might be coming from the EmailFaxDetails.js page while trying to pass the ID since there are 2 ID's per number the user search. I might be wrong, if anyone could find the error and help making it correct I would really appreciate it.
I think problem here
setId(response.data)
You need retrieve only id and same for for orderid

How to GET data from mongoDB ATLAS and display in React App

I am new to MERN stack and been working on a project that uses different driver information entered from the user and display that information back to the user in a table. I have successfully connected to MongoDB Atlas and also can enter data using my front end but I can't seem to figure out how to retrieve the data back to the front end. Can y'all help me fetch the data back and how I can present it in a tabular format.
Thanks in advance.
//driver model
onst mongoose = require('mongoose');
const DriverSchema = new mongoose.Schema({
name:{type: String, required:true},
email:{type: String, required:true},
phone:{type: Number, required:true},
address:{type:String, required:true},
country:{type: String, required:true}
});
const DriverModel = mongoose.model("drivers", DriverSchema)
module.exports = DriverModel;
//routes
const router= require('express').Router();
let Driver = require('../models/driver');
router.route('/getDrivers').get((req, res) =>{
Driver.find()
.then(drivers => res.json(drivers))
.catch(err => res.status(400).json('Error: '+ err));
}
)
router.route('/createDrivers').post((req, res) => {
const name = req.body.name;
const email = req.body.email;
const phone = req.body.phone;
const address = req.body.address;
const country =req.body.country;
const newDriver = new Driver({name, email, phone, address, country});
newDriver.save()
.then(() => res.json('Driver added!'))
.catch(err => res.status(400).json('Error: ' + err));
});
router.route('/:id').get((req,res)=> {
Driver.findById(req.params.id)
.then(drivers => res.json(drivers))
.catch(err => res.status(400).json('Error: ' + err));
})
router.route('/:id').delete((req, res) => {
Driver.findByIdAndDelete(req.params.id)
.then(() => res.json('Driver deleted.'))
.catch(err => res.status(400).json('Error: ' + err));
});
router.route('/update/:id').post((req, res) => {
Driver.findById(req.params.id)
.then(driver => {
driver.name = req.body.name;
driver.email = req.body.email;
driver.phone = req.body.phone;
driver.address = req.body.address;
driver.country =req.body.country;
driver.save()
.then(() => res.json('Driver updated!'))
.catch(err => res.status(400).json('Error: ' + err));
})
.catch(err => res.status(400).json('Error: ' + err));
});
module.exports = router;
//frontend
import React from 'react';
import Sidebar from '../../components/sidebar/Sidebar';
import Navbar from '../../components/navbar/Navbar';
import { useEffect, useState } from 'react';
import "./dbtrial.scss" ;
import Axios from "axios";
function Dbtrial() {
const [listOfDrivers, setListOfDrivers]= useState([]);
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [phone, setPhone] = useState(0);
const [address, setAddress] = useState("");
const [country, setCountry] = useState("");
useEffect(() => {
const fetchDrivers= async () =>{
try{
const response = await fetch("http://localhost:3001/driver/getDrivers")
if(!response.ok) throw Error('Did not recieve expected data');
const listDrivers = await response.json();
console.log(listDrivers);
setListOfDrivers(listDrivers);
setFetchError(null);
} catch(err){
setFetchError(err.message)
}
}
setTimeout(() => {
(async () => await fetchDrivers())();
}, 2000)
//(async () => await fetchDrivers())();
}, [])
const createDrivers = () =>{
Axios.post("http://localhost:3001/createDrivers", {
name,
email,
phone,
address,
country,
}).then((response) =>{
setListOfDrivers([...listOfDrivers,
{
name, email, phone, address,
country,
},
]);
//alert("Driver added!");
});
}
return (
<div className="db">
<Sidebar />
<div className="dbq">
<Navbar />
<div className="formInput">
<label>Name</label>
<input type="text" placeholder="name" onChange={(event) => {
setName(event.target.value);
}} />
</div>
<div className="formInput">
<label>Email</label>
<input type="email" placeholder="email" onChange={(event)=> {setEmail(event.target.value);}}/>
</div>
<div className="formInput">
<label>Phonenumber</label>
<input type="text" placeholder="0923668881 " onChange={(event) => {setPhone(event.target.value);}}/>
</div>
<div className="formInput">
<label>Address</label>
<input type="text" placeholder="Addis Ababa" onChange={(event)=> {setAddress(event.target.value);}}/>
</div>
<div className="formInput">
<label>Country</label>
<input type="text" placeholder="country" onChange={(event) => {setCountry(event.target.value);}}/>
<button type="submit" onClick={createDrivers}>Send</button>
</div>
</div>
</div>
)
}
export default Dbtrial
On your backend, your router functions don't seem to use
res.send
Where you are doing res.json, you can do something like
res.status(200).send(responseData)
So in router.routes.findById' then callback, instead of:
.then(drivers =>
res.json(drivers))
You can have
.then(drivers =>
res.status(200).send(JSON.stringify(drivers)) //maybe you don't need to use JSON.stringify here
In your frontend, I'm not sure what response.data will be defined after your api call. To be sure what properties the response has, you can console.dir(response.data), console.dir(response.json()) and check the result in the browser console. (Not too familiar with axios) If the result is your driver array, you can do like are already doing with setDriverList to set the state, but probably with the result of, or a part of the result of response.data or response.data.devices or something like that.
So I would do something like
//...api call
.then((response) => {
if(response.status === 200){
setDriverList(response.data.drivers) //or response.data or whatever
}
})

How do I properly update my Postgres Database in Node.js?

The Problem: syntax error at or near "$"
The Context: My App does two CRUD operations - Update & Read Data from a Postgres database. It successfully reads data from the database and displays on the frontend. However, it fails to update the database when I query it to do so. It throws an error that 'syntax error at or near "$"'.
So far, I have failed to debug the error successfully.
The Stacks: Postgres, Node.js, React
The Query (BackEnd):
//burrow a book
app.post("/books/:id", async (req, res) => {
try {
const { id } = req.params;
const copies = await pool.query('SELECT copies FROM books WHERE book_id = $id', [id]);
const stock = copies - 1;
const updateBook = await pool.query("UPDATE books SET copies = $1 WHERE book_id = $2", [stock, id]);
const allBooks = await pool.query("SELECT * FROM books");
res.json(allBooks.rows);
} catch (err) {
console.error(err.message);
}
});
The Function(FrontEnd):
async function burrowbook(id) {
try {
const res = await fetch(`http://localhost:5000/books/${id}` , {method: "POST"});
console.log(res);
// setbooks(jsonData);
// console.log(jsonData);
} catch (err) {
console.error(err.message);
}
}
The Full React Component(FrontEnd):
import React, { Fragment, useEffect, useState } from 'react';
const ListBooks = () => {
const [books, setbooks] = useState([]);
async function burrowbook(id) {
try {
const res = await fetch(`http://localhost:5000/books/${id}` , {method: "POST"});
console.log(res);
// setbooks(jsonData);
// console.log(jsonData);
} catch (err) {
console.error(err.message);
}
}
const getBooks = async () => {
try {
const response = await fetch("http://localhost:5000/books");
const jsonData = await response.json();
setbooks(jsonData);
// console.log(jsonData);
} catch (err) {
console.error(err.message);
}
}
useEffect(() => {
getBooks();
}, []);
return (<Fragment>
<div class="container ">
<h1 class="text-center mt-5">Wakanda Library</h1>
</div>
<table class="table table-hover table-dark text-center mt-5">
<thead>
<tr>
<th scope="col">Book ID</th>
<th scope="col">Title</th>
<th scope="col">Author</th>
<th scope="col">Year</th>
<th scope="col">Stock</th>
<th scope="col">Burrow</th>
<th scope="col">Return</th>
</tr>
</thead>
<tbody>
{books.map(book => (
<tr key={book.book_id}>
<td>{book.book_id} </td>
<td>{book.title} </td>
<td>{book.author} </td>
<td>{book.publish_year} </td>
<td>{book.copies} </td>
<td><button
className="btn btn-success btn-circle btn-md"
onClick={() => burrowbook(book.book_id)}
>
Burrow
</button></td>
<td><button
className="btn btn-primary btn-circle btn-md"
// onClick={() => returnBook(book.book_id)}
>
Return
</button></td>
</tr>
))}
</tbody>
</table>
</Fragment>);
};
export default ListBooks;
The Full index.js script(BackEnd):
const express = require("express");
const app = express();
const cors = require('cors');
const pool = require('./db');
//middleware
app.use(cors());
app.use(express.json()); //req.body
//ROUTES//
//login user
//register user
//list of books in library
app.get("/books", async (req, res) => {
try {
const allBooks = await pool.query("SELECT * FROM books");
res.json(allBooks.rows);
} catch (err) {
console.error(err.message);
}
});
//burrow a book
app.post("/books/:id", async (req, res) => {
try {
const { id } = req.params;
console.log(id);
const copies = await pool.query('SELECT copies FROM books WHERE book_id = $id', [id]);
console.log("b");
const stock = copies - 1;
console.log("c")
const updateBook = await pool.query("UPDATE books SET copies = $1 WHERE book_id = $2", [stock, id]);
console.log("d")
const allBooks = await pool.query("SELECT * FROM books");
console.log("heee")
res.json(allBooks.rows);
} catch (err) {
console.error(err.message);
}
});
//return a book
app.put("/booksreturn/:id", async (req, res) => {
try {
const { id } = req.params;
const { copies } = req.body;
const returnBook = await pool.query(
"UPDATE books SET copies = $copies WHERE book_id = $id",
[copies = parseFloat(copies) + 1, id]
);
res.json("Book was returned!");
} catch (err) {
console.error(err.message);
}
});
//list of books in users possession
app.listen(5000, () => {
console.log("Baba... server don start on top port 5000.")
});

Keeping an open connection in Node.js app

I want to create a module, which keeps an open connection to Flickr API and keeps on receiving new recent photos.
I've tried the 'agentkeepalive' node module, but cloudfront seems to block the requests. This is what my current module code looks like, obviously, the fetch now only runs once:
Server side
require('dotenv').config()
var Flickr = require('flickr-sdk')
var flickr = new Flickr(process.env.FLICKR_API_KEY)
var express = require('express')
var app = express()
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept',
)
next()
})
app.get('/fetch', function(req, res) {
(() =>
flickr.photos
.getRecent()
.then(result => {
return res.send(result.body.photos.photo)
})
.catch(err => {
console.error('Error: ', err)
}))()
})
const PORT = process.env.PORT || 5000
app.listen(PORT, () => console.log(`Server started on port ${PORT}`))
Client side
import './App.css'
import 'bootstrap/dist/css/bootstrap.css'
import React, { Component } from 'react'
import axios from 'axios'
export class App extends Component {
constructor(props) {
super(props)
this.state = {
fetchClicked: false,
photos: [],
}
}
onFetchClick = () => {
this.state.fetchClicked
? this.setState({ fetchClicked: false })
: this.setState({ fetchClicked: true }, () => {
axios.get('http://localhost:5000/fetch').then(response => {
this.setState({
photos: response.data,
})
})
})
}
render() {
const { fetchClicked } = this.state
return (
<div className="App p-5 bg-secondary">
<h1>Flickr Streamer </h1>
{fetchClicked ? (
<button className="btn btn-info" disabled>
Streaming...
</button>
) : (
<button className="btn btn-info " onClick={() => this.onFetchClick()}>
Start the stream!
</button>
)}
<div>{this.state.dataReceived}</div>
<table className="table table-dark mt-5">
<thead>
<tr>
<th scope="col">Photo</th>
<th scope="col">Title</th>
</tr>
</thead>
<tbody>
{this.state.photos.map(item => {
return (
<tr key={item.id}>
<td>
<img
src={`https://farm${item.farm}.staticflickr.com/${item.server}/${item.id}_${item.secret}.jpg`}
/>
</td>
<td scope="row" className="w-50">
{item.title || 'No name'}
</td>
</tr>
)
})}
</tbody>
</table>
</div>
)
}
}
export default App
Polling is usually the way to do this kind of thing. This is how I would do it:
fetch = () => axios.get('http://localhost:5000/fetch')
.then(({data}) => this.setState({ photos:data })
onFetchClick = () =>
this.setState({ fetchClicked: !this.state.fetchClicked }),
() => this.fetch()
.then(() => setInterval(() => this.fetch(), 15 * 1000))
This doesn't deal with the user clicking the button more than once, but if that callback only executes if the state changed, or you disable the button when it is clicked, that would be handled for you by that. Otherwise, you'd have to handle it.

Unable to show response message from node server

I am creating MERN stack app and trying to save data in database.After data added successfully in database I am sending success message from node server and I want to show this message on front-end side but it is showing nothing though I am sending message from server.
Below is my code:
React code form.js
import React,{Component} from 'react';
import Axios from 'axios';
import swal from 'sweetalert';
class Form extends Component{
constructor(props){
super(props)
this.state = {
title:'',
detail:''
}
}
onTitleChange = (e) => {
this.setState({
title:e.target.value
});
}
onDetailChange = (e) => {
this.setState({
detail:e.target.value
});
}
handleSubmit = (e) => {
e.preventDefault();
Axios.post('http://localhost:5000/save',{
title:this.state.title,
detail:this.state.detail
}).then((msg) =>{
swal(msg);
}).catch((err) => {
console.log("React Error:",err);
});
}
render(){
return(
<div className="container">
<h2 id="formTitle">Add blog</h2>
<form>
<div>
<input type="text" className="validate" name="title" value={this.state.title} placeholder="Title" onChange={this.onTitleChange} required/>
</div>
<div>
<textarea type="text" value={this.state.detail} className="validate materialize-textarea" name="detail" placeholder="Detail" onChange={this.onDetailChange} required></textarea>
</div>
SUBMIT
</form>
</div>
)
}
};
export default Form;
saveData.js
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const blogs = require('../models/blogPost');
const mongoose = require('mongoose');
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({extended: true}));
const dburl = 'mongodb+srv://exp#cluster1-5ws.mongodb.net/expdb?retryWrites=true'
router.post('/save',(req,res) => {
const data = {
title: req.body.title,
detail: req.body.detail
}
const newBlog = new blogs(data);
mongoose.connect(dburl, {useNewUrlParser: true,useUnifiedTopology:true}).then((resp) =>{
newBlog.save().then(() => {
res.json({msg:"Data inserted"});
}).catch((err) => {
console.log("Insertion error", err);
});
}).catch((err) => {
console.log("database error: ",err);
});
});
module.exports = router;
mongoose database schema blogPost.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const BlogPostSchema = new Schema({
title:String,
detail:String,
date:{
type:String,
dafault:Date.now()
}
});
const BlogPost = mongoose.model('BlogPost',BlogPostSchema);
module.exports = BlogPost;
Someone please let me know what I m doing wrong any help would be appreciated.
Thanks
In Axios then block Simply add res.data to get response from server.
Axios.post('http://localhost:5000/save',{
title:this.state.title,
detail:this.state.detail
}).then((res) =>{
swal(res.data);
}).catch((err) => {
console.log("React Error:",err);
});
THANKS

Resources