How to GET data from mongoDB ATLAS and display in React App - node.js

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
}
})

Related

Redirects to wrong page when logging in

it redirects to an empty js file when logging in, not to the js file I wrote. Should I redirect in my database code?
////////////////
const client = require('../../db')
const express = require('express');
const app = express();
const cors = require("cors");
app.use(cors());
app.use(express.json()); //req.body
app.listen(2136, ()=>{
console.log("Sever is now listening at port 5000");
})
client.connect();
app.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
const user = await client.query(
`SELECT * FROM users WHERE email=$1 AND password=$2`,
[email, password]
);
if (user.rows.length === 0) {
res.status(404).send("Kullanıcı adı veya şifre yanlış");
} else {
res.send("Kullanıcı adı veya şifre doğru");
}
}catch (err) {
response
.status(500)
.json({ message: "Error in invocation of API: /login" })
}
});
this is my database code.
///////////////////////
import {
BrowserRouter as Router,
Route
} from "react-router-dom";
import React, { useState } from 'react'
import Navbar from '../../common/Navbar/Navbar';
import AdminPage from './AdminPage';
const User = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [user, setUser] = useState([]);
const [error, setError] = useState('');
const onSubmitForm = async e => {
e.preventDefault();
try {
const response = await fetch(`http://localhost:2136/login`,{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
console.log(email,password)
console.log(response);
if ((response.status)===404) {
setError('Invalid email or password');
} else
{
window.location.replace(`/AdminPage`);
}
} catch (err) {
console.error(error);
setError('An error occurred. Please try again later.');
}
};
return (
<>
<Navbar/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"></link>
<div className="container text-center">
<h1 className="my-5">Search for the Dormitory You Want</h1>
<form className="d-flex" onSubmit={onSubmitForm}>
<input
type="text"
name="name"
placeholder="Enter email ..."
className="form-control"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<input
type="text"
name="name"
placeholder="Enter password ..."
className="form-control"
value={password}
onChange={e => setPassword(e.target.value)}
/>
<button className="btn btn-success">Submit
</button>
</form>
</div>
</>
)
}
export default User
this is my login page. the page it redirects to is a blank page. i don't understand why.
///////////////
import React, { useState } from 'react'
import AdminNavbar from '../../common/Navbar/AdminNavbar';
const AdminPage = () => {
return (
<>
<AdminNavbar/>
</>
);
}
export default AdminPage
and this the page I want to redirect AdminPage.So what can i do?
///////////////////
The difference between assign() and replace():
replace() removes the current URL from the document history.
With replace() it is not possible to use "back" to navigate back to the original document.
You can use assign method instead of location method

Failed to load resource: the server responded with a status of 405 AWS Amplify

I'm currently working on a full stack project and I'm stuck on the POST request to update my database. I'm using MERN and it's deployed using AWS Amplify. For some reason when I process the POST request using the local deployment everything works as expected, however when I attempt this using the AWS deployment I get the following error "Failed to load resource: the server responded with a status of 405 ()". Below is the code in question and anything that mught steer me in the right direction is greatly appreciated.
index.js(server)
const mongoose = require("mongoose");
const app = express();
const PortfolioModel = require("./models/Portfolio");
app.use(express.json());
mongoose.connect(
"mongodb+srv://EEngvall:*******#cluster0.frqsy.mongodb.net/Test?retryWrites=true&w=majority", {
useNewUrlParser: true,
});
app.post('/insert', async (req, res) =>{
const firstName = req.body.firstName
const lastName = req.body.lastName
const emailAddress = req.body.emailAddress
const portfolio = new PortfolioModel({firstName: firstName, lastName: lastName, emailAddress: emailAddress})
try {
await portfolio.save();
res.send("Data Inserted Successfully");
} catch (error) {
console.log(error)
}
})
app.listen(process.env.POST || 3000, () => {
console.log("Server is booming on port 3001")
});
contactMeInput.jsx(client)
import React, { Component, useState } from "react";
import "../styles/contactMeStyles.css";
import Axios from "axios";
function ContactMeInput() {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [emailAddress, setEmailAddress] = useState("");
const addToList = () => {
console.log(firstName + " " + lastName + emailAddress);
Axios.post("/insert", {
firstName: firstName,
lastName: lastName,
emailAddress: emailAddress,
});
};
return (
<div className="contact-me-main">
<h2>Send me a message!</h2>
<div className="input-container">
<label>First Name:</label>
<input
className="input-item"
type="text"
onChange={(event) => setFirstName(event.target.value)}
/>
<label>Last Name:</label>
<input
className="input-item"
type="text"
onChange={(event) => setLastName(event.target.value)}
/>
<label>Email Address:</label>
<input
className="input-item"
type="emial"
onChange={(event) => setEmailAddress(event.target.value)}
/>
<button onClick={addToList}>Submit</button>
</div>
</div>
);
}
export default ContactMeInput;

Page is rendering the users after second submit

currently learning React and want to POST-Data to my Database and after the Post the table with all users should update automatically.
Do you have any suggestion why it is not working?
I try to use the useEffect and add also the allData array, but it is then in an infinite loop.
So currently it is just loading the page if I again press the submit button.
import React from "react";
import { useState, useEffect } from "react";
import axios from "axios";
const Form = () => {
const [Username, setUsername] = useState("");
const [Password, setPassword] = useState("");
const [userList, setUserList] = useState([]);
const allData = () => {
axios.get("http://localhost:3001/api/alluser").then((response) => {
console.log(response.data);
setUserList(response.data);
});
};
useEffect(() => {
allData();
}, []);
const postdata = () => {
axios.post("http://localhost:3001/api", {
Username: Username,
Password: Password,
});
allData();
};
const deletedata = (e) => {
const users_id = e.target.id;
axios.post("http://localhost:3001/api", {
users_id: users_id,
});
};
const clickHandler = (e) => {
deletedata(e);
};
return (
<>
<label name="Username">
<input
onChange={(e) => setUsername(e.target.value)}
type="text"
name="Username"
placeholder="Username"
/>
</label>
<label name="password">
<input
onChange={(e) => setPassword(e.target.value)}
type="text"
name="Password"
placeholder="Password"
/>
</label>
<button onClick={postdata}>Submit</button>
{userList.map((val) => {
return (
<>
<li key={val.users_id}>
{val.users_id}
<button onClick={clickHandler}>
Löschen
</button>
</li>
</>
);
})}
</>
);
};
export default Form;
allData() should wait until axios.post returns the response. You could use callbacks or async/await to achieve it.
const postdata = async () => {
await axios.post("http://localhost:3001/api", {
Username: Username,
Password: Password,
});
allData();
};
or
const postdata = () => {
axios.post("http://localhost:3001/api", {
Username: Username,
Password: Password,
}).then(() => { allData(); });
};

React Hooks: How to make a POST request to server

I am a beginner.I am trying to implement a POST request from React.js in a simple form, but I cannot figure out how to send POST request to database. I guess I need <form action="URL"> as well.
Any help will be appreciated.
Below is the code from React.js(frontend)
import GameTestResult from './GameTestResult';
export default function App() {
const[data, setData] = useState([]);
const [formData, setFormData] = useState("");
useEffect (() => {
fetch('http://localhost:3000/game')
.then(res => res.json())
.then(result => setData(result.rows))
.catch(err => console.log("error"))
},[]);
const handleChange = event => {
setFormData(event.target.value)
}
const eventHandler = event => {
event.preventDefault();
setFormData("");
}
return (
<div className="App">
<form method="post" onSubmit = {eventHandler}>
<input value = {formData} onChange = {handleChange} />
<button type="submit">click</button>
</form>
{data && data.map((element, index)=>(
<GameTestResult
name = {element.name}
key={element.index}
/>
))}
</div>
);
}
here is the code from express.js(backend)
var router = express.Router();
const pool = require("../config.js");
var cors = require('cors');
router.get("/game", cors(), (req, res) => {
pool
.query("SELECT * FROM game")
.then((data) => res.json(data))
.catch((e) => {
res.sendStatus(404), console.log(e);
});
});
router.post("/game", (req, res) => {
const { name } = req.body;
pool
.query('INSERT INTO game(name) values($1);', [name])
.then(data => res.status(201).json(data))
.catch(e => res.sendStatus(404));
});
module.exports = router;
Here is what you can do:
Fetch games when component is mounted. And Submit new game when form is submitted.
export default function App() {
const [data, setData] = useState([])
const [formData, setFormData] = useState('')
useEffect(() => {
fetchGames() // Fetch games when component is mounted
}, [])
const fetchGames = () => {
fetch('http://localhost:3000/game', {
method: 'GET',
})
.then((res) => res.json())
.then((result) => setData(result.rows))
.catch((err) => console.log('error'))
}
const saveGames = () => {
fetch('http://localhost:3000/game', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: formData, // Use your own property name / key
}),
})
.then((res) => res.json())
.then((result) => setData(result.rows))
.catch((err) => console.log('error'))
}
const handleSubmit = (event) => {
event.preventDefault()
saveGames() // Save games when form is submitted
}
const handleChange = (event) => {
setFormData(event.target.value)
}
return (
<div className="App">
{/* method="post" not needed here because `fetch` is doing the POST not the `form` */}
{/* Also, note I changed the function name, handleSubmit */}
<form onSubmit={handleSubmit}>
<input type="text" name="name" value={formData} onChange={handleChange} />
<button type="submit">click</button>
</form>
{data &&
data.map((element, index) => (
<GameTestResult name={element.name} key={element.index} />
))}
</div>
)
}
You can read this about how to use fetch and this about how forms work in RecatJS.
Add name as "name" to input
Listen onChange and set data setFormData({[event.target.key]: event.target.value}) the data will be for example {name: "Tony"}
Call POST request on onClick action of button like code below
JSON.stringify(data) is important to convert js object to JSON when sending it to server
import GameTestResult from './GameTestResult'
export default function App() {
const [data, setData] = useState([])
const [formData, setFormData] = useState({})
useEffect(() => {
fetch('http://localhost:3000/game')
.then((res) => res.json())
.then((result) => setData(result.rows))
.catch((err) => console.log('error'))
}, [])
const handleChange = (event) => {
setFormData({ [event.target.name]: event.target.value })
}
const eventHandler = (event) => {
fetch('http://localhost:3000/game', {
method: 'POST',
body: JSON.stringify(formData),
})
.then((res) => res.json())
.then((result) => {
console.log(result)
setFormData('')
})
.catch((err) => console.log('error'))
}
return (
<div className="App">
<form>
<input name="name" value={formData.name || ''} onChange={handleChange} />
<button onClick={eventHandler}>click</button>
</form>
{data &&
data.map((element, index) => (
<GameTestResult name={element.name} key={element.index} />
))}
</div>
)
}

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