Why is my post route not running properly in Express app? - node.js

I am trying to add a route to '/signup' in my express application. But, every time I am sending a post request to the server it is resolving in "No response". Whereas the '/' route is working. Where have I gone wrong with the code?
index.js
import dotenv from "dotenv";
import cors from "cors";
import morgan from "morgan";
import dbConnect from "./config/dbConnect.js";
import { authRoute } from "./routes/auth.js";
dotenv.config();
const port = process.env.PORT;
const DATABASE_URI = process.env.DATABASE_URI;
const app = express();
dbConnect();
app.get("/", (req, res) => {
res.sendStatus(200);
});
app.use(express.json());
app.use(cors());
app.use(morgan("combined"));
app.use("/api/v1", authRoute);
app.listen(port, () => {
console.log(`Server running at ${port}...`);
});
auth.js
import { Router } from "express";
const router = Router();
router.post("signup", (req, res) => {
const password = req.body.password;
console.log(password);
});
export { router as authRoute };
dbConnect.js
import mongoose from "mongoose";
import dotenv from "dotenv";
dotenv.config();
const DATABASE_URI = process.env.DATABASE_URI;
const dbConnect = () => {
mongoose.set("strictQuery", false);
mongoose
.connect(DATABASE_URI)
.then(() => {
console.log("connected");
})
.catch((error) => {
console.error(error);
});
};
export default dbConnect;

router.post("signup", (req, res) => {
const password = req.body.password;
console.log(password);
});
The client doesn't get a response because you haven't written any code to send a response.
You completely ignore the object passed to res.
You don't call res.json or res.render or res.send or any of the other methods that would send a response.

Seems like the problem was with my VSCode extension RapidApi client, tried using insomnia and it worked out fine. Sorry for the trouble!

Related

How to set up custom koa.js server in next.js

I have set up custom koa.js server and every time I make a request to api for example
/api/login
It always ends up in being 404 not found.
I have tried looking for a solution but, could not really find it.
Below is my server.js file
import '#babel/polyfill';
import dotenv from 'dotenv';
import 'isomorphic-fetch';
import next from 'next';
import Koa from 'koa';
import Router from 'koa-router';
import UserRouter from './routes/user';
import cors from '#koa/cors';
dotenv.config();
const compression = require('compression');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = new Koa();
const router = new Router();
server.use(
cors({
origin: '*',
})
);
router.get('*', async (ctx) => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
});
server.use(UserRouter.routes()).use(UserRouter.allowedMethods());
server.use(router.allowedMethods());
server.use(router.routes());
server.listen(port, (err) => {
if (err) throw err;
console.log(`Server ready on ${port}`);
});
});

How to read all routes dynamically in node.js

I am trying to read all routes in my app.js file from './routes' folder,but
gettingerror:"TypeError: Cannot read property 'forEach' of undefined"
import express from "express";
import fs from "fs";
const app = express();
fs.readdir('./routes', (err, fs) => {
fs.forEach(file => {
app.use('/', require('./routes/' + file))
});
})
export default app
This worked for me:
sync
fs.readdirSync('/some/path/routes').forEach(function(file) {
app.use('/', require(`/some/path/routes/` + file));
});
async
fs.readdir('/some/path/routes', function(err, files){
files.forEach(function(file){
app.use('/', require(`/some/path/routes/` + file));
});
});
You can do using fs.readdirSync because the server is not yet started.
fs.readdir(`${__dirname}/routes`, (err, files) => {
if (err)
console.log(err);
else {
files.forEach(file => {
app.use('/', require(`${__dirname}/routes` + file));
})
}
})
You can use fspromise and import to handle using promise. 🚀🚀🚀
import { promises as fsPromises } from 'fs';
export const init = async () => {
const files = await fsPromises.readdir(`${__dirname}/routes`);
const router = Router();
const createRoute = async (file) => {
const route = await import(`./routes/${file}`);
router.use("/", route.default);
};
await Promise.all(files.map(createRoute));
return router;
}
// app.js
import {init} from "./routes";
const app = express();
(async() => {
await init();
// Start server
})();
I would suggest doing like below. You will have more control over routes. You can do customization on routes bases if needed.
ex. /v1 and /v2 etc..
// routes/index.js
import { Router } from "express";
import route1 from './route1';
import route2 from './route2';
const router = Router();
[route1, route2].forEach((route) => router.use("/", route));
export default router;
// app.js
import express from "express";
import routes from "./routes";
const app = express();
app.use("/", routes);
export default app;

Can't retrieve information from mongodb when deploying on heroku

The problem is as the title suggests. When I run my app locally, I'm able to retrieve information from MongoDB but on Heroku, undefined is returned. Should I connect to MongoDB in another way because if I hardcode some text everything works just fine. Here are my scripts:
function to get data
const MongoClient = require("mongodb").MongoClient;
const dbConnectionUrl = "mongodb+srv://xxxxxxx#cluster0.ro4dz.mongodb.net/data?retryWrites=true&w=majority";
const saySomething = (req, res, next) => {
// res.status(200).json({
// body: 'Hello from the server!'
// });
login()
.then(val=>res.send(val))
};
async function login(){
const client = new MongoClient(dbConnectionUrl)
try{
await client.connect();
const database = client.db("data");
const movies = database.collection("movies");
const query = { name: "toke" };
const movie = await movies.findOne(query);
return movie
}catch(err){
console.log(err)
}
}
module.exports.saySomething = saySomething;
router
const express = require('express');
const router = express.Router();
const controllers = require('./../controllers/controllers');
router.get('/say-something', controllers.saySomething);
module.exports = router;
server
// Import dependencies
const express = require('express');
const cors = require('cors');
const path = require('path');
// Create a new express application named 'app'
const app = express();
// Set our backend port to be either an environment variable or port 5000
const port = process.env.PORT || 5000;
// This application level middleware prints incoming requests to the servers console, useful to see incoming requests
app.use((req, res, next) => {
console.log(`Request_Endpoint: ${req.method} ${req.url}`);
next();
});
// Configure the CORs middleware
// Require Route
app.use(cors());
const api = require('./routes/routes');
// Configure app to use route
app.use('/api', api);
// This middleware informs the express application to serve our compiled React files
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'staging') {
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
});
};
// Catch any bad requests
app.get('*', (req, res) => {
res.status(200).json({
msg: 'Catch All'
});
});
// Configure our server to listen on the port defiend by our port variable
app.listen(port, () => console.log(`BACK_END_SERVICE_PORT: ${port}`));
front
import { useEffect, useState } from 'react';
import './App.css';
import axios from 'axios'
function App(){
useEffect(()=>{
get()
})
const[text, settext] = useState('')
async function get(){
let request = await axios.get('/api/say-something')
console.log(request.data.name)
settext(request.data.name)
}
return(
<div>{text}</div>
)
}
export default App;
I solved the issue! The first thing I did was that I added MongoDB connection URI as an environmental variable in my app via Heroku. Secondly, I added an option in MongoDB so that the cluster can be accessed from any computer. By default, the access is set to the local computer so I added another IP, namely 0.0.0.0/0 to my cluster, and now everything works just fine.

POST http://localhost:5000/login 500 (Internal Server Error)(This is a post request for a login page)

Getting a 500 error for login request: POST http://localhost:5000/login 500 (Internal Server Error). Writing a login page. Not sure where this error is coming from. This is my app.js, routes and form handle submit pages. Can post more code if needed. Using passport to authenticate but dont think the error is coming from there.
import express from 'express';
const router = express.Router();
router.post('/', (req, res, next) => {
passport.authenticate("local", (err, user, info) => {
if (err) throw err;
if (!user) res.send("No User Exists");
else {
req.logIn(user, (err) => {
if (err) throw err;
res.send("Successfully Authenticated");
console.log(req.user);
});
}
})(req, res, next);
});
export default router;
import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import cors from 'cors';
import dotenv from 'dotenv';
import postRoutes from './routes/posts.js'
import userRoutes from './routes/user.js'
import loginRoutes from './routes/login.js'
const app = express();
dotenv.config();
app.use(bodyParser.json({limit: "30mb", extended: true}));
app.use(bodyParser.urlencoded({limit: "30mb", extended: true}));
app.use(cors());
app.use('/posts', postRoutes);
app.use('/auth', userRoutes);
app.use('/login', loginRoutes);
const PORT = process.env.PORT || 5000;
mongoose.connect(process.env.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)
const handleSubmit = event => {
event.preventDefault();
const user = {
username: username,
password: password,
}
axios.post('http://localhost:5000/login', user )
.then(res=>{
console.log(res);
console.log(res.data);
})
}
You have forgotten to initialize Passport in your app.js.
I guess you are using "Passport" for your authentication/authorization goals.
Double-check this article if you want any help:
const res = await client.post("/sign-in", {email, password});
Try this code in handle-submit.

Getting "undefined" in node.js when i send data from angular form

Whenever I submit data from angular forms I'm receiving undefined in the backend (node.js) even I used body-parser to parse the incoming data.
server.js
const express= require("express");
const app=express();
const bodyParser = require("body-parser");
const api=require("./server/routes/api");
const cors=require('cors')
const port=4440;
app.use(cors())
app.use("/api",api)
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
app.get("/", (req,res)=>{
res.send("hello from server")
})
app.listen(port,()=>{
console.log("server listening on port"+" "+port)
})
Below is the api.js code
api.js
const express= require("express");
const router=express.Router();
const User=require("../models/user")
const mongoose= require('mongoose');
const db="mongodb+srv://srihari:dbuser#cluster0.yuykq.mongodb.net/users?retryWrites=true&w=majority"
mongoose.connect(db,{useNewUrlParser:true,useUnifiedTopology:true},(err)=>{
if(err){
console.error("Error" + err)
}else{
console.log("DB connected!")
}
}
)
router.get("/", (req,res)=>{
res.send("From API route")
})
router.post("/register",(res,req)=>{
let userData=req.body;
console.log(userData);
let user=new User(userData)
user.save((error,registeredUser) =>{
if(error){
console.log(error);
}else{
console.log(registeredUser)
}
})
})
module.exports=router;
angular form code
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class UserserviceService {
url="http://localhost:4440/api/register";
constructor(private http:HttpClient) { }
registrationdata(user:any){
console.log(user);
return this.http.post<any>(this.url,user);
}
// loginData(data:any){
// return this.http.post<any>(this.)
// }
}
above is the code which is in the front end whenever I'm submitting the form data it is logging in my console but in the backend, I'm getting req.body as "undefined".
First error I can see it's that your middleware that parse the JSON , is after the API , so it will never arrive there unless the POST was to the / route that it's the only one after it
also you dont need the bodyparser since express already can do that
change your code to something like this
const express= require("express");
const app=express();
const api=require("./server/routes/api");
const cors=require('cors')
const port=4440;
app.use(cors())
app.use(express.json()) // Express has already a method to parse json
app.use(express.urlencoded({ extended: false })) //Allso for the url encoded
app.use("/api",api) //<== Move this line AFTER calling body parsers
app.get("/", (req,res)=>{
res.send("hello from server")
})
app.listen(port,()=>{
console.log("server listening on port"+" "+port)
})
I already saw the problem, and it's a really simple one but hard to see because words are very similar.
You have a typo, this is very common so:
router.post("/register",(res,req)=>{
Should be:
router.post("/register",(req,res)=>{
Try that and it should work. Tell me if don't and i'll try to help.

Resources