React : POST and GET not found - javascript

I'm following this tutorial which I adapt to React Router v4.
I have these files :
auth.js
const express = require('express');
const validator = require('validator');
const router = new express.Router();
function validateLoginForm(payload) {
const errors = {};
let isFormValid = true;
let message = '';
if (!payload || typeof payload.email !== 'string' || payload.email.trim().length === 0) {
isFormValid = false;
errors.email = 'Please provide your email address.';
}
if (!payload || typeof payload.password !== 'string' || payload.password.trim().length === 0) {
isFormValid = false;
errors.password = 'Please provide your password.';
}
if (!isFormValid) {
message = 'Check the form for errors.';
}
return {
success: isFormValid,
message,
errors
};
}
router.post('/login', (req, res) => {
console.log("lol");
const validationResult = validateLoginForm(req.body);
if (!validationResult.success) {
return res.status(400).json({
success: false,
message: validationResult.message,
errors: validationResult.errors
});
}
return res.status(200).end();
});
router.get('/login', (req, res) => {
console.log(req.url);
});
router.get('/', (req, res) => {
console.log(req.url);
console.log("lmao")
});
module.exports = router;
index.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const router = new express.Router();
// tell the app to look for static files in these directories
app.use(express.static('./server/static/'));
app.use(express.static('./client/dist/'));
app.use(bodyParser.urlencoded({extended:false}));
const authRoutes = require('./server/routes/auth');
app.use('/login', authRoutes);
// start the server
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000 or http://127.0.0.1:3000');
});
Base.jsx
import React from 'react';
import PropTypes from 'prop-types';
import { Link, NavLink } from 'react-router-dom';
const Base = ({ child }) => (
<div>
<div className="top-bar">
<div className="top-bar-left">
<NavLink to="/">React App</NavLink>
</div>
<div className="top-bar-right">
<Link to="/login">Log in</Link>
</div>
</div>
{child.render()}
</div>
);
Base.propTypes = {
child: PropTypes.object.isRequired
};
export default Base;
and app.jsx
import React from 'react';
import ReactDom from 'react-dom';
import injectTapEventPlugin from 'react-tap-event-plugin';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import {BrowserRouter, Switch, Route} from 'react-router-dom';
import Base from './components/Base.jsx';
import HomePage from './components/HomePage.jsx';
import LoginPag from './components/LoginPag.jsx';
// for MaterialUI to work properly
injectTapEventPlugin();
const TestLogin = (props) => {
return (<Base child={LoginPag}/>)
};
const TestBase = (props) => {
return(<Base child={HomePage}/>)
};
ReactDom.render((<BrowserRouter><MuiThemeProvider muiTheme={getMuiTheme()}>
<div>
<Switch>
<Route exact path="/" component={TestBase}/>
</Switch>
<Route exact path="/login" component={TestLogin}/>
</div>
</MuiThemeProvider>
</BrowserRouter>), document.getElementById('react-app'));
As you can see, I did a little "workaround" to have everything rendered nicely and it works. But it only works for Client-side routing.
I can't reload pages via f5 or refresh button, nor can I send form and get it through router.post(). It automatically results in a 404 not found.
I printed req.url in router.get('*') to see where the thing goes down and it appears that everywhere I go, the server still receives the address /. I believe the matter is with the <Link to> tag..
How can I fix this and get the server "follow" the client side routing ?
I'm using latest versions of Express, React, and React-Router. Thanks in advance
EDIT : Edited to take into account the remarks made by VivekN

Change your index.js file to the below one:-
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const router = new express.Router();
// tell the app to look for static files in these directories
app.use(express.static('./server/static/'));
app.use(express.static('./client/dist/'));
app.use(bodyParser.urlencoded({extended:false}));
const authRoutes = require('./server/routes/auth');
app.use('/', authRoutes);
// start the server
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000 or http://127.0.0.1:3000');
});
The problem with your code is that you had written when a request comes to your server which has /login in its path, then that should go inside auth.js file and inside that you should check for router.post('/') method.
Either this or you change the index.js file to be
app.use('/', authRoutes);

Related

Keep getting error with simple ReactJS FORM posting to Express JS server

I am new to ReactJS and trying to find a way to connect my React front end to my Express js backend. To do this, I am just setting up a simple form that sends a POST request after I press a register button in a form.
The problem is I keep getting these error messages in the console.
These are the errors
POST http://localhost:3000/api/users 404 (Not Found)
Error: Request failed with status code 404
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.onloadend (xhr.js:66)
This is the react code
import Proj from './Proj'
import React, {Fragment, useState} from 'react'
import axios from 'axios';
export const Homepage = () => {
const [formData, setFormData] = useState({
name:'',
});
const { name } = formData;
const onChange = e =>
setFormData({...formData, [e.target.name]:e.target.value})
const onSubmit = async e => {
console.log('submitted')
e.preventDefault();
const newUser = {
name,
}
try {
const config = {
headers:{
'Content-Type':'application/json'
} }
const body = JSON.stringify(newUser)
const res = await axios.post('/api/users',body, config)
console.log(res)
} catch (err) {
console.error(err)
}
}
return (
<div className="Landing">
<Proj/>
<section>
<form onSubmit = {e=>onSubmit(e)}>
<input
type="text"
placeholder="Name"
name="name"
value = {name}
onChange = {e =>onChange(e)}
required />
<input type="submit" className="btn btn-primary" value="Register" />
<h1>Contact</h1>
</form>
</section>
</div>
)
}
export default Homepage
This App.js
import { Navbar } from './components/Navbar';
import Homepage from './components/Homepage';
import Projects from './components/Projects';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import './App.css';
function App() {
return (
<Router>
<div className="App">
<Navbar/>
</div>
<Route exact path="/" component={Homepage} />
<Switch>
<Route exact path="/Projects" component={Projects} />
</Switch>
</Router>
);
}
export default App;
This is my server side JS
const express = require ('express')
const path = require('path');
const app = express()
app.use(express.urlencoded({extended: false}));
app.use('/', require('./routes/api/users'))
// Serve static assets in production
if (process.env.NODE_ENV === 'production'){
app.use(express.static('client/build'))
app.get('*', (req,res)=>{
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'))
})
}
const PORT = 5000
app.listen(process.env.PORT || 5000)
and this is users.js in the api folder in routes
const express = require('express')
const router = express.Router();
router.post('/', async (req,res)=>
{
console.log('its working, and here is the data', req.body)
})
module.exports = router;
client side package.json
"proxy":"http://localhost:5000",
I would really appreciate it if someone can tell me what I am doing wrong or if there is a better way to do things.Thanks.
Instead of
app.use('/', require('./routes/api/users'))
type in
app.use('/api/users', require('./routes/api/users'))
You are posting currently to a route that does not exist.

axios GET request not working in MERN application [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
So, I am attempting a simple, single-page application on the MERN stack that takes notes - a note title and a note content and displays them on the same root route; the data is supposed to also be saved on the backend for later retrieval. At this time, there is no authentication. My backend seems to be working perfectly, but when I connect the front end React application to the backend MongoDB database, my GET request (using axios instance) fails.
My backend renders on localhost:5000, no problem.
But on localhost:3000, I'm seeing this error in App.jsx:
Error: Request failed with status code 404
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:62)
Here's what I have going on:
BACKEND
// server.js
import express from 'express';
import cors from 'cors';
import notes from './api/notes.route.js';
const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/api/v1/notes', notes);
app.use('*', (req, res) => res.status(404).json({ error: 'not found' }));
export default app;
// notes.route.js
import express from 'express';
import NotesController from './notes.controller.js';
const router = express.Router();
router
.route('/')
.get(NotesController.apiGetNotes)
.post(NotesController.apiPostNote)
.put(NotesController.apiUpdateNote)
.delete(NotesController.apiDeleteNote);
export default router;
// notes.controller.js
import NotesDAO from '../dao/notesDAO.js';
class NotesController {
static apiGetNotes = async (req, res, next) => {
const notesPerPage = req.query.notesPerPage
? parseInt(req.query.notesPerPage)
: 20;
const page = req.query.page ? parseInt(req.query.page) : 0;
const { notesList, totalNumNotes } = await NotesDAO.getNotes({
page,
notesPerPage
});
let response = {
notesList,
page,
notesPerPage,
totalNumNotes
};
res.json(response);
};
export default NotesController;
// notesDAO.js
import mongodb from 'mongodb';
const ObjectID = mongodb.ObjectId;
let notes;
class NotesDAO {
// call this on db connection:
static injectDB = async conn => {
if (notes) return;
try {
notes = await conn.db(process.env.NOTESDB_NS).collection('notes');
} catch (e) {
console.error(`unable to establish collection handle in notesDAO: ${e}`);
}
};
static getNotes = async ({ page = 0, notesPerPage = 20 } = {}) => {
let query;
let cursor;
try {
cursor = await notes.find(query);
} catch (e) {
console.error(`unable to issue find command, ${e}`);
return { notesList: [], totalNumNotes: 0 };
}
const displayCursor = cursor.limit(notesPerPage).skip(notesPerPage * page);
try {
const notesList = await displayCursor.toArray();
const totalNumNotes = await notes.countDocuments(query);
return { notesList, totalNumNotes };
} catch (e) {
console.error(
`unable to convert cursor to array or problem counting documents, ${e}`
);
return { notesList: [], totalNumNotes: 0 };
}
};
}
export default NotesDAO;
FRONTEND
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route } from 'react-router-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Route path="/" component={App} />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
// App.jsx
import { useState, useEffect } from 'react';
import NoteDataService from './services/note.js';
import Header from './Header';
import Footer from './Footer';
import CreateArea from './CreateArea';
import Notes from './Notes';
const App = () => {
const [notes, setNotes] = useState([]);
useEffect(() => {
retrieveNotes();
}, []);
const retrieveNotes = async () => {
await NoteDataService.getAll()
.then(response => {
console.log(response.data);
setNotes(response.data.notes);
})
.catch(e => console.log(e));
};
return (
<>
<Header />
<CreateArea clicked={addNote} />
<Notes notes={notes} clicked={deleteNote} />
<Footer />
</>
);
};
export default App;
// http-common.js
import axios from 'axios';
export default axios.create({
baseURL: 'http://localhost:5000/api/vi/notes',
headers: {
'Content-type': 'application/json'
}
});
// note.js
import http from '../http-common.js';
class NoteDataService {
getAll() {
return http.get('/');
}
}
export default new NoteDataService();
You have a typo. The backend route is /api/v1/notes, but the frontend is sending requests to /api/vi/notes

Cannot import a function in another file (node.js)

I have an issue that I can't resolve. I'm working with node.js and I simply want to use an export router function in another file .
Here is the code from the import file:
import express from "express";
import * as zoneInstance from "../../controllers/objectInstance/zoneInstance.js";
import { mobilityRouter } from "../../controllers/routerFunction/routerLogic.js";
const router = express.Router();
/* Router for mobility render
// const mobilityRouter = (zone, instance) => {
// return (
// router.get("/mobility/" + zone, instance)
// );
// } */
mobilityRouter(zoneInstance.shoulder.zone, zoneInstance.shoulder.mobilityRender());
Here is the code from the export file:
import express from "express";
const router = express.Router();
// Router for mobility render
export const mobilityRouter = (zone, instance) => {
return (
router.get("/mobility/" + zone, instance)
);
}
// Router for reinforcement render
export const reinforcementRouter = (zone, instance) => {
return (
router.get("/reinforcement/" + zone, instance)
);
}
// Router for proprioception
export const proprioceptionRouter = (zone, instance) => {
return (
router.get("/proprioception/" + zone, instance)
);
}
In the index.js
// Routes for
import mobilityRouter from "./routes/mobility/mobilityAPI.js";
const app = express();
//for mobility URL
app.use("/", mobilityRouter);
When I copy past the 'mobilityRouter' function and use it in the import file it works perfectly, but once I put it in another file and exports it I have a "cannot GET/" in my browser. Thank you for your help.
You have different instances of router in both files. Either pass router as a parameter to the function in the other file or export & import in your routerLogic.js.

How do I get my express server to GET a request from my React client app?

I'm working on my first express backend React frontend app. Currently working on the user register/login/logout section.
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const keys = require('./config/keys')
const passport = require('passport');
const session = require('express-session');
const LocalStrategy = require('passport-local');
// const passportLocalMongoose = require('passport-local-mongoose');
const User = require('./models/User');
const app = express();
// Use BodyParser
app.use(bodyParser.urlencoded({ extended: true }));
// Passport
app.use(passport.initialize());
app.use(passport.session());
app.use(session({
secret: 'Rusty is the best',
saveUninitialized: false,
resave: false
}));
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
// Connect to the Database
const db = keys.mongoURI
mongoose
.connect(db, { useNewUrlParser: true })
.then(() => console.log(`MongoDB connected...`))
.catch(err => console.log(err));
// Routes
const items = require('./routes/api/items')
app.use('/api/items', items);
// Auth Routes
app.post('/register', function(req, res) {
User.register(new User({ username: req.body.username }), req.body.password, function(err, user) {
if (err) {
console.log(err);
return res.render('/register');
}
passport.authenticate('local')(req, res, function() {
res.redirect('/secret');
})
})
});
app.post('/login', passport.authenticate('local', {
successRedirect: '/secret',
failureRedirect: '/login'
}), function(req, res) {
});
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
})
// Port and Listen
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on ${port}...`));
The post routes at the end of my express server.js file work fine, but I have problems when I get to app.get('/logout').
My server is running on 5000 and client is on 3000.
I have "proxy": "http://localhost:5000" inside my client project.json.
localhost:3000/logout returns a blank page while localhost:5000/logout returns the res.send message "You have hit the logout page".
Anyone know how I can fix this?
edit: Here is my react router to show how the client routes
import React, { Component } from 'react';
import { Route, BrowserRouter } from 'react-router-dom';
import Input from './components/Input';
import SignUp from './components/SignUp';
import Form from './components/Form';
import LogIn from './components/LogIn';
import SignUp2 from './components/SignUp2';
import Profile from './components/Profile';
import Home from './components/Home';
import LogOut from './components/LogOut';
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Route exact path='/' component={ Home } />
<Route path='/register' component={ SignUp2 } />
<Route path='/changeThisBackToRegister' component={ SignUp } />
<Route path='/form' component={ Form } />
<Route path='/login' component= { LogIn } />
<Route path='/profile' component = { Profile } />
<Route path='/secret' component = { Input } />
<Route path='/logout' component = { LogOut } />
</div>
</BrowserRouter>
);
}
}
export default App;
Change your /logout api response to send json response.
app.get('/logout', function(req, res) {
req.logout();
res.json({success: true});
})
In your Logout component, make /logout call when the component mounts.
import React, { Component } from 'react';
export default class Logout extends Component {
constructor(props) {
super(props);
this.state = {
logoutSuccess: false
};
}
componentDidMount() {
fetch('/logout')
.then((response) => response.json())
.then(() => {
this.setState({logoutSuccess: true});
});
}
render() {
const { logoutSuccess } = this.state;
return (
<div>
{ logoutSuccess && (<div>Logout Success</div>)}
</div>
);
}
}

React-routes express-server

I'm learning to work with the rect, when I try to follow the link, I get such errors:
My client.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import App from '../components/first_page/App';
import {Router, Route } from 'react-router';
import { browserHistory } from 'react-router';
class Main extends Component {
render(){
return (
<Router>
<Route history = {browserHistory}>
<Route path="/f" component={App}/>
</Route>
</Router>
);
}
}
render (<Main />, window.document.getElementById('app'))
App.js
import React, { Component } from 'react';
import Bootstrap from 'bootstrap/dist/css/bootstrap.css';
import { Button } from 'react-bootstrap';
class App extends Component{
render(){
return (
<div>
<Button>Start!</Button>
<Button>Login!</Button>
</div>
);
}
}
export default App
Server
var express = require('express');
var path = require('path');
var config = require('../webpack.config.js');
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var app = express()
var compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {noInfo: true, publicPath: config.output.publicPath}));
app.use(webpackHotMiddleware(compiler));
app.use(express.static(path.resolve(__dirname, './dist')));
app.use('/', function (req, res) {
res.sendFile(path.resolve('client/index.html'));
});
var port = process.env.PORT || 4000;
app.listen(port, function(error) {
if (error) throw error;
console.log("Express server listening on port", port);
});
I tried to pass different tutorials, but always these mistakes are obtained, I will be happy with any help, thanks

Categories