I know similar questions have been answered multiple times over the years and I have scoured through just about all of them and can't seem to figure out what my issue is.
I am getting the Cannot GET / error with NodeJS when opening the localhost:5000 in browser. When inspecting I can see it says "Failed to load resource: the server responded with a status of 404 (Not Found)", which I think may be related to my controllers file.
Note: I am trying to code based off of this tutorial: https://www.youtube.com/watch?v=ngc9gnGgUdA
The "This works" message previously showed up for me and the array symbol still shows up. It is the JSX structure part where I first run into this issue (begins at 28:50). I feel I have done exactly as the tutorial explains, but perhaps I need a better person than me to look at it.
server/Index.js
import express from 'express';
// import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import cors from 'cors';
import postRoutes from './routes/posts.js';
const app = express();
app.use('/posts', postRoutes);
app.use(express.json({ limit: "30mb", extended: true }));
app.use(express.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
const CONNECTION_URL = 'mongodb+srv://*****:******#cluster0.kwo9h.mongodb.net/myFirstDatabase?retryWrites=true&w=majority'
const PORT = process.env.PORT || 5000;
mongoose.connect(CONNECTION_URL, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => app.listen(PORT, () => console.log(`Server running on port: ${PORT}`)))
.catch((error) => console.log(error.message));
mongoose.set('useFindAndModify', false);
controllers/posts
import PostMessage from '../models/postMessage.js';
// import router from '../routes/posts.js';
export const getPosts = async (req, res) => {
try {
const postMessages = await PostMessage.find();
// console.log(postMessages);
res.status(200).json(postMessages);
} catch (error) {
res.status(404).json({ message: error.message });
}
}
export const createPost = async (req, res) => {
const
post = req.body;
const newPost = new PostMessage(post);
try {
await newPost.save();
res.status(201).json(newPost);
} catch (error) {
res.status(409).json({ message: error.message });
}
}
routes/posts
import express from 'express';
import { getPosts, createPost } from '../controllers/posts.js'
const router = express.Router();
// localhost:5000/posts
router.get('/', getPosts);
router.post('/', createPost);
export default router;
Any help would definitely make my day. Thank you!
In the tutorial, there are actually 2 applications. The first one is the backend (NodeJS), which is running on port 5000. The second one is the frontend (React), which is running on port 3000.
At 30:50, you see that the mentor typing "npm run start" on the 2nd terminal to start the react application.
At 33:12, the URL is localhost:3000, which is pointing to React application. It isn't localhost:5000. You get the error 404 because in the NodeJS part, there is no GET "/" route. So you just need to use the correct URL.
You cannot directly use router.
declare the express app first and attach the router to it.
const app = express();
const router = express.Router();
router.get('/', getPosts);
router.post('/', createPost);
app.use('/', router)
export default router;
You have no route declared for http://localhost:5000 - your router is under /posts
So you need to visit http://localhost:5000/posts to see something.
If you want something to appear directly at http://localhost:5000 you can do something like
index.js
const app = express();
app.use('/', (req, res) => {
res.send('works')
})
app.use('/posts', postRoutes);
What do you want to see at http://localhost:5000?
If you want to display a index.html website you can put your index.html file in a a folder e.g. public and add
app.use(express.static('public'))
If you want your posts to appear at http://localhost:5000 then change your routing
index.js
const app = express();
app.use('/', postRoutes)
Related
I am still learning Node.js. I created a server using express documentation and it worked before.
But now for a project I have imported some npm packages. like dotenv, http-errors, ejs and others. I created (.env) file and there decleared PORT=5000, import it in my (main.js) file and called app.listen function. So that, it can show my ejs template in the browser but when i hit http://localhost:5000 it just keeps loading but nothing appears. it's not giving any errors in the terminal either, it just keeps loading unless i press ctrl+c in my terminal.
main.js
const express = require("express");
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const path = require("path");
const cookieParser = require("cookie-parser");
const { notFoundHandler, errorHandler } = require("./middlewares/common/errorHandler");
const app = express();
dotenv.config();
//database connection
mongoose.set("strictQuery", true);
mongoose.connect(process.env.MONGO_CONNECTION_STRING, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log("Database Conntcted!"))
.catch(err => console.log(err));
app.use(express.json);
app.use(express.urlencoded({ extended: true }));
app.set("view engine", "ejs");
app.set('views', 'views');
app.use(express.static(path.join(__dirname, "public")));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(notFoundHandler);
//common error handler
app.use(errorHandler);
app.listen(process.env.PORT, () => {
console.log(`app is listing at port ${process.env.PORT}`);
});
my errorhandler.js
const createError = require("http-errors");
function notFoundHandler(req, res, next) {
next(createError(404, "CONTENT WAS NOT FOUND!"));
}
function errorHandler(err, req, res, next) {
res.render("error", {
title: "Error Page",
});
}
module.exports = {
notFoundHandler: notFoundHandler,
errorHandler,
};
error.ejs
my ejs file route ("./views/error.ejs")
<title><%= title %></title>
<body>
Alart!
</body>
.env file
PORT=5000
problem fixed! The problem was in my main file. There was a parentheses() missing.
it would be app.use(express.json());
I am building a simple express application that stores the data from a particular server and sent it to frontend on request.
Here is my code.
index.js
import express from 'express';
import cors from 'cors';
import morgan from 'morgan';
import { routes } from '../routes';
export let cache = {};
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
app.use(cors());
app.use(express.json());
app.use(morgan('tiny'));
app.use('/', routes);
app.disable('x-powered-by');
app.listen(port, () => {
console.log(`Listening to port ${port}`);
... DOING SOMETHING ...
const result = someFunc();
cache = result;
});
router.js
... ... ...
routes.get(
'/cache',
catchAsync(async (req: Request, res: Response) => {
const query = req.query?.fields || '';
const fields = query ? String(query).split(',') : [];
res.status(200).json(fields.length ? pick(cache, fields) : cache);
}),
);
This works well on local, but when I deploy it to Vercel it always returns {}.
It seems that setting to cache is not working on Vercel.
How can I implement do this?
The recommended way of caching is by using a in-memory database like Redis. You can go through this to get started.
Okay so i just started building an api using Node. Normally, before i even start, i test it in the postman using dummy data to make sure all the routes are working fine but i never tested it on the browser until today. It brings out the dummy data all fine in the postman but when I put in the same route i used in the postman on the browser tab, it just brings out my custom error message "Route does not exist". Why is this happening?
This is my routes/auth.js
const express = require('express')
const router = express.Router()
const {upload} = require('../utils/multer')
const { register, login } = require('../controllers/auth')
router.post('/register', upload.single('picture'), register)
router.post('/login', login)
module.exports = router
This is my controllers/auth.js:
const register = async (req, res) => {
res.send('register')
}
const login = async (req, res) => {
res.send('login')
}
module.exports = {register, login}
This is my app.js:
require('dotenv').config()
require('express-async-errors');
const bodyParser = require('body-parser')
const cors = require('cors')
const multer = require('multer')
const helmet = require('helmet') //helps you secure your Express apps by setting various HTTP headers.
const morgan = require('morgan')
const path = require('path')
const express = require('express');
const app = express();
/* CONFIGURATIONS */
app.use(helmet());
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
app.use(morgan("common"));
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(express.urlencoded({ limit: "30mb", extended: true }));
app.use("/assets", express.static(path.join(__dirname, "public/assets")));
//routers
const authRouter = require('./routes/auth')
// error handlers
const notFoundMiddleware = require('./middleware/not-found');
const errorHandlerMiddleware = require('./middleware/error-handler');
//middleware
app.use(express.json());
app.use(cors());
//routes
app.use('/api/v1/auth', authRouter)
//errors
app.use(notFoundMiddleware);
app.use(errorHandlerMiddleware);
//database
const connectDB = require('./db/connect');
const port = process.env.PORT || 5000;
const start = async () => {
try {
await connectDB(process.env.MONGO_URI);
app.listen(port, () =>
console.log(`Server is listening on port ${port}...`)
);
} catch (error) {
console.log(error);
}
};
start();
Please note that i do not understand what most of these configurations do, not very well anyways. i have tried to remove them though but the problem was still there.
I am assuming you are trying to access /login or /register route from browser search bar something like this http://host:port/login. With this browser will send GET /login request but /login is a POST method route that is the reason you are getting Route not found
When you send request from your browser then by default it will send GET request and your app is not handling GET requests.
You are handling POST requests for /register and /login routes.
I have a heroku app and when I use local host urls to get and post data between my frontend (react) and backend (express & node.js) everything works fine. However when I deploy the app and change the urls to match my site I get an error in the network tab of the browser log. It says "An error occurred when trying to load the resource". In the console I also get: "Unhandled Promise Rejection: SyntaxError: The string did not match the expected pattern". This happens every time I use fetch with the url of the deployed site. If the project did work as I intended it should display 'Hello World' on the screen after the fetch request. Here is the code:
Client(react):
import React,{useState, useRef} from 'react';
import './App.css';
function App() {
const [test, setTest] = useState('none')
async function FetchTest(){
setTest('starting')
const Res = await fetch('/test')
const Data = await Res.json()
setTest(Data)
}
return (
<div>
<p>{test}</p>
<button onClick={FetchTest}> Test </button>
</div>
)
}
export default App;
Here is the server (express & node.js):
//importing dependancy's
const express = require('express')
const app = express()
const cors = require('cors')
const path = require('path')
const bodyParser = require("body-parser")
app.use(cors())
app.use(bodyParser.json())
app.use(express.urlencoded({extended: false}))
const port = process.env.PORT || 4000
//serves build file from react /build folder
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'))
})
}
//simple routes
app.get('/test', (req, res) => {
res.json('Hello World')
})
app.listen(port)
I am trying to create an api and send post request using the postman,
but for some reason I'm not getting the data which is sent through the
post man. Instead when I cancel the postman send request I get
response which is shown in the screenshot.
Postman Screenshot:
nodejs server response screenshot:
server.js
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
// importing custom created modules
const config = require('./config');
// Instantiating express
const app = express();
// Connecting to the mongodbLab
mongoose.connect(config.database, { useNewUrlParser: true }, (error) => {
if (error) {
console.log('Error :',error);
} else {
console.log('Connected to the database.');
}
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(morgan('dev'));
app.use(cors);
const userRoutes = require('./routes/account');
app.use('/api/accounts', userRoutes);
// Running the server at port 3000
app.listen(config.port, error => {
console.log('Server started with config file at Port: ' + config.port);
});
account.js
const router = require('express').Router();
const jwt = require('jsonwebtoken'); // Encrypts user data.
router.post('/signup', (req, res, next) => {
console.log(req.body);
});
module.exports = router;
I tried even changing from https://localhost:3000 to
http://localhost:3000 as suggested in this post Here
And even tried adding res.end() as suggested here and here.
But nothing is working, If I goto localhost:3000 the server just keeps loading infinitely. Please help!
Okay I got the solution, it was because of app.use(cors). I don't know why but when I commented out this line everything started to work perfectly.
But in the response although I get the json object. But there is an array of Object, which I didn't get.
Here's the response screenshot:
Edit:
I finally got it I didn't call the cors() method properly. It should have been app.use(cors()), but I called it as just app.use(cors) missing paranthesis().
Now Everything is working fine.