Cannot retrieve Users data from database. Server doesnt respond - node.js

I am learning a MERN stack course on Udemy and currently I am trying to retrieve the user's data from the server but I can't. I am able to retrieve the post data but the connections times out for users data. Can you guys help me find out what went wrong? Thank you in advance!
userController snippet:
exports.allUsers = (req, res) => {
const users = User.find({})
.then((users) => {
console.log(users);
})
.catch(err => console.log(err));
};
User routes snippet
const express = require('express'),
router = express.Router(),
{userById, allUsers } = require('../controllers/userController');
router.get('/users', allUsers);
router.param('userID', userById)
module.exports = router;
app.js code snippet
const express = require('express'),
app = express(),
postRoutes = require('./routes/post'),
authRoutes = require('./routes/auth'),
morgan = require("morgan"),
mongoose = require("mongoose"),
bodyParser = require("body-parser"),
cookieParser = require('cookie-parser'),
userRoutes = require('./routes/user'),
expressValidator = require('express-validator');
require('dotenv').config();
mongoose.connect(process.env.MONGO_URI,
{ useUnifiedTopology: true, useNewUrlParser: true })
.then(() => console.log("DB connected"));
app.use(morgan("dev"));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(expressValidator());
app.use('/', postRoutes);
app.use('/', authRoutes);
app.use('/', userRoutes);
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
res.status(401).json({error: "Unauthorised"});
}
});
app.listen(process.env.PORT || 3000, () => {
console.log(`SERVER AT PORT: 3000`);
});
Postman gets stuck here:

You have to end the request / respond to the request . In your userController you are missing ending/responding the request. You are just logging the user result .
Try this :
exports.allUsers = (req, res) => {
const users = User.find({})
.then((users) => {
console.log(users);
res.status(200).json(users);
})
.catch((err) => {
console.log(err);
res.status(500).json(err.message);
});
}

Related

How do we pass parameters to a mounted route in nodeJS?

I'm taking a course on NodeJS, there were a few assignments related to routing, everything works fine except this part which seems a little odd: For some reason, I cannot read the parameter ID being passed to the mounted router.
dish.js
const express = require('express');
const bodyParser = require('body-parser');
const dishRouter = express.Router();
dishRouter.use(bodyParser.json());
dishRouter.route('/')
.all((req,res,next) => {
res.statusCode = 200;
res.setHeader('Content-Type','text/plain');
next();
})
.get((req,res) => {
console.info('Info: ',req);
res.end(`Sending details of the dish back to you: ${req.params.dishId}`);
})
.post((req,res) => {
res.statusCode = 403;
res.end(`Operation not supported: ${req.params.dishId}`);
})
.put((req,res) => {
res.write(`Updating the dish...: ${req.params.dishId} \n` );
res.end(`Will update this dish: ${req.body.name} with details: ${req.body.description}`);
})
.delete((req,res) => {
res.end(`Deleting this dish: ${req.params.dishId}`);
});
exports.dish = dishRouter;
dishes.js
const express = require('express');
const bodyParser = require('body-parser');
const dishesRouter = express.Router();
dishesRouter.use(bodyParser.json());
dishesRouter.route('/')
.all((req,res,next) => {
res.statusCode = 200;
res.setHeader('Content-Type','text/plain');
next();
})
.get((req,res) => {
res.end('Sending all dishes back to you');
})
.post((req,res) => {
res.end(`Will add the dish: ${req.body.name} with details: ${req.body.description}`);
})
.put((req,res) => {
res.statusCode = 403;
res.end(`Operation not supported.`);
})
.delete((req,res) => {
res.end(`Deleting all dishes.....`);
});
exports.dishes = dishesRouter;
index.js
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const http = require('http');
const dishRouter = require('./routes/dish');
const dishesRouter = require('./routes/dishes');
const hostname = 'localhost';
const port = 3000;
const app = express();
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use('/dishes',dishesRouter.dishes);
app.use('/dishes/:dishId',dishRouter.dish);
app.use(express.static(__dirname+'/public'));
app.use((req,res,next) => {
res.statusCode = 200;
res.setHeader('Content-Type','text/html');
res.end('<html><body><h1>This is an Express Server</h1></body></html>');
});
const server = http.createServer(app);
server.listen(port,hostname,(req,res) => {
console.info(`Server running on port: ${port}, at: ${hostname}`);
})
This GET localhost:3000/dishes/123 is calling the right route, but the parameter dishId comes back as "undefined". Again, just learning nodeJS, seems like my receiver/mounted route should receive those parameters just fine, the body can be read properly, but not the params. ... thanks.
Yeah the params don't flow between routers. You're on a new router, hence new route params object.
You can check out the code for this:
https://github.com/expressjs/express/blob/master/lib/router/index.js#L43
Check out line 43 and line 53 where route.params is set to an empty object.
Some examples:
index.js
app.use('/dishes/:dishId',(req, res) => {
console.log('now I get my dishId', req.params.dishId)
});
dish.js (version 1)
dishRouter.route('/')
.get((req, res) => {
console.log('now i get nothing', req.params)
})
dish.js (version 2)
dishRouter.route('/:anotherId')
.get((req, res) => {
console.log('now we get another parameter', req.params.anotherId)
})
// the path would be /dish/123/456
I'm not sure if there is a offical-expressjs-way to pass the params object between routers.
One solution would be to create a custom handler
index.js
app.use('/dishes/:dishId', handler)
handler.js
function handler (req, res, next) {
if (req.method === 'GET') {
console.log('now we get it', req.params)
}
}
module.exports = handler
Anoter way would be to add the dishId to the request object before calling the router:
index.js
app.use('/dishes/:dishId', (req, res, next) => {
req.dishId = req.params.dishId
router(req, res, next)
})
dish.js
const express = require('express')
const router = express.Router()
router.route('/')
.get((req, res) => {
console.log('nothing here', req.params)
console.log('dishId', req.dishId)
})
module.exports = router
Third way would be to send the params as options to a router function
index.js
app.use('/dishes/:dishId', (req, res, next) => {
router(req.params)(req, res, next)
})
dish.js
function createRouter (options) {
const router = express.Router()
router.route('/')
.get((req, res) => {
console.log('nothing here', req.params)
console.log('but alot here', options)
})
return router
}
module.exports = createRouter
If you want you could also just put the :dishId on the router as an optional parameter
index.js
app.use('/dishes', dishesRouter)
dishes.js
const express = require('express')
const router = express.Router()
router.route('/:dishId?')
.get((req, res) => {
if (req.params.dishId) {
res.end(`Sending details of the dish back to you: ${req.params.dishId}`)
} else {
res.end('Sending all dishes back to you');
}
})
module.exports = router

Using express session to share information across different routes

I am wondering if anyone could help me please.
I have a react app that contains dialogflow (google's chatbot platform). I would like to share information in a user route to a dialogflow fulfillmentRoute using express-session. Here is my main server.js file. In the server.js I have declared an express-session
server.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const path = require('path');
var cors = require('cors')
const users = require('./routes/api/users');
const db = require('./config/keys').mongoURI;
require('./models/Users');
const app = express();
const session = require('express-session')
// Body parser middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cors());
require('./routes/fulfillmentRoutes')(app);
app.use(session({secret: 'ssshhhhh'}));
// Connect to MongoDB
mongoose
.connect(db)
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
// Passport middleware
app.use(passport.initialize());
// Passport Config
require('./config/passport')(passport);
// Use Routes
app.use('/api/users', users);
// Server static assets if in production
if (process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));
In the user.js route file, I then have this to save an email into a session variable;
user.js
router.post(
'/',
passport.authenticate('jwt', { session: false }),
(req, res) => {
sess = req.session;
var emails = req.user.email;
sess.emails;
res.json({ msg: 'Users Works' })
res.json({
id: req.user.id,
firstname: req.user.firstname,
lastname: req.user.lastname,
email: req.user.email,
week: req.user.week,
age: req.user.age
});
}
);
In my dialogflow fullfillment route file, I have the following;
fulfillmentRoutes.js
const {WebhookClient, Payload, Card} = require('dialogflow-fulfillment');
const express = require('express');
const chatbot = require('../chatbot/chatbot');
const mongoose = require('mongoose');
const passport = require('passport');
const keys = require('../config/keys');
const sourceFile = require('./api/users.js');
const User = require('../models/User');
module.exports = app => {
var router = express.Router();
app.post('/api/df_text_query', async (req, res) => {
let responses = await chatbot.textQuery(req.body.text, req.body.userID, req.body.parameters);
res.send(responses[0].queryResult);
});
app.post('/api/df_event_query', async (req, res) => {
let responses = await chatbot.eventQuery(req.body.event, req.body.userID, req.body.parameters);
res.send(responses[0].queryResult);
});
app.post('/', async (req, res) => {
const agent = new WebhookClient({ request: req, response: res });
async function welcome(agent) {
let user = await User.findOne({'email': sess.emails});
if (user !== null ) {
responseText = `${sess.emails}`;
}
agent.add(responseText);
}
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
agent.handleRequest(intentMap);
});
return router;
}
In the welcome async function in fulfillment.js route, I use sess.emails that was declared in the user.js routes file. However the variable comes back undefined. Any guidance or help will be appreciated please.
Thanks
In your user.js, sess.emails; is not being assigned any variable.
Can you try replacing it sess.emails = emails; and check if the emails field is undefined?

API Route for retrieving a MongoDB collection

I'm trying to retrieve data from my mongo database. The problem occurs when I try to do the get route in my API. The error I get is: SchemeName.collection is not a function.
Here is my API in routes/api/tejidos
const express = require("express");
const router = express.Router();
const Equipo = require("../../../models/Equipo");
router.post("/crear", (req, res) => {
// Form validation
const newEquipo = new Equipo({
nombre: req.body.nombre,
marca: req.body.marca,
modelo: req.body.modelo,
serial: req.body.serial,
proveedor: req.body.proveedor,
estado: req.body.estado,
zona: req.body.zona,
fechaCompra: req.body.fechaCompra,
tiempoGarantia: req.body.tiempoGarantia,
guiaUsoRapido:req.body.guiaUsoRapido
});
//if (err) throw err
newEquipo
.save()
.then(equipo=>res.json(equipo))
.catch(err => console.log(err));
});
router.get('/leer', function(req, res) {
const equipos = Equipo.collection("equipos")
res.json({
equipos: equipos
});
});
module.exports = router;
And this is my server.js
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const users = require("./routes/api/users");
const equipos = require("./routes/api/tejidos/equipos");
const app = express();
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }
)
.then(() => console.log("MongoDB successfully connected"))
.catch(err => console.log(err));
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes
app.use("/api/users", users);
app.use("/api/tejidos/equipos", equipos);
const port = process.env.PORT || 5000; // process.env.port is Heroku's port if you choose to deploy the app there
app.listen(port, () => console.log(`Server up and running... ${port} !`));
I need to retrieve data in my collection (the ones I created with the post method) from the database when I use the GET method in Postman at http://localhost:5000/api/tejidos/equipos/leer
Also, I will appreciate any documentation that you recommend.
Simply use find method:
router.get('/leer', async (req, res) => {
const equipos = await Equipo.find();
res.json({ equipos });
});
And here is the helpful documentation for making queries with mongoose

Can't use axios to get/post data from/to localhost server in android 7.0 device - React Native app

I use Axios in my react native app. I use Mobiistar Zumbo J2 with Expo to test but I get err: Network Error. I also set CORS for my node server but it still doesn't work. I test with Postman it work normally. Here is my code:
server.js
const express = require("express");
const path = require("path");
const bodyParser = require("body-parser");
const index = require("./routes/index");
const bookings = require("./routes/bookings");
const cors = require('cors'); // Yep, you need to install this
const app = express();
const port = process.env.PORT || 3000;
app.use(cors());
app.listen(port, () => {
console.log('Server is running on port', port);
});
app.set("views", path.join(__dirname, "views"));
app.set("view engine", 'ejs');
app.engine("html", require("ejs").renderFile);
//Body parser MW
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
//Routes
app.use("/", index);
app.use("/api", bookings);
bookings.js
const express = require("express");
const router = express.Router();
const mongojs = require("mongojs");
const db = mongojs("mongodb://<username>:<password>#ds139614.mlab.com:39614/booking-car-app", ["bookings"]);
router.get("/bookings", (req, res, next) => {
db.bookings.find((err, data) => {
if (err) {
res.send(err);
}
res.json(data);
});
});
router.post("/bookings", (req, res, next) => {
const booking = req.body;
if (!booking.userName) {
res.status(400);
res.json({err: "Bad data"});
} else {
db.bookings.save(booking, (err, savedBooking) => {
if (err) {
res.send(err);
}
res.json(savedBooking);
})
}
})
module.exports = router;
using Axios to get data from server
axios.get("http://127.0.0.1:3000/api/bookings/")
.then(res => {
console.log("Get booking info: ", res);
alert(res);
})
.catch(err => console.log(err))
Error:
Network Error
Stack trace:
node_modules\axios\lib\core\createError.js:16:24 in createError
node_modules\axios\lib\adapters\xhr.js:87:25 in handleError
node_modules\event-target-shim\lib\event-target.js:172:43 in dispatchEvent
node_modules\react-native\Libraries\Network\XMLHttpRequest.js:578:29 in setReadyState
node_modules\react-native\Libraries\Network\XMLHttpRequest.js:392:25 in __didCompleteResponse
node_modules\react-native\Libraries\vendor\emitter\EventEmitter.js:191:12 in emit
node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:349:47 in __callFunction
node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:106:26 in <unknown>
node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:297:10 in __guard
node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:105:17 in callFunctionReturnFlushedQueue
...
Please help me.
Thank you very much
Android uses a special type of IP address 10.0.2.2
axios.get("http://10.0.2.2:3000//api/bookings/")
.then(res => {
console.log("Get booking info: ", res);
alert(res);
})
.catch(err => console.log(err))

Cant set headers after they are sent

I am using express backend with a react frontend everything is working fine but occasionally i get error
Cant set header after they are sent
and server gets down.i searched few ways this error might happen but in my code i could not find such cases.i tried to be simple as possible in the code.can anyone please point me what might be the issue?
Server.js file
// call the packages we need
const addItem = require('./controllers/addItem');
const addCategory = require('./controllers/addCategory');
const addSubCategory = require('./controllers/addSubCategory');
const getSubCategory = require('./controllers/getSubCategoryByCategory');
const getCategory = require('./controllers/getAllCategory');
const getAllItems = require('./controllers/getAllItems');
const cors = require('cors');
const express = require('express');
// call express
const app = express(); // define our app using express
const bodyParser = require('body-parser');
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
const port = process.env.PORT || 8080; // set our port
// ROUTES FOR OUR API
// =============================================================================
const addItemRoute = express.Router(); // get an instance of the express Router
const getCategoryRoute = express.Router();
const addCategoryRoute = express.Router();
const addSubCategoryRoute = express.Router();
const getSubCategoryRoute = express.Router();
const getAllItemsRoute = express.Router();
getCategoryRoute.get('/get_category', (req, res) => {
getCategory(res);
});
addCategoryRoute.post('/add_category', (req, res) => {
addCategory(req.body.name, res);
});
getSubCategoryRoute.get('/get_subcategory/:catId', (req, res) => {
getSubCategory(req.params.catId, res);
});
addSubCategoryRoute.post('/add_subcategory', (req, res) => {
addSubCategory(req.body.name, req.body.cat_id, res);
});
// code, name, quantity, length, description and subcategory id should be passed as parameters
addItemRoute.post('/add_item', (req, res) => {
addItem(req.body.item, res);
});
getAllItemsRoute.get('/get_items', (req, res) => {
getAllItems(res);
});
// more routes for our API will happen here
// REGISTER OUR ROUTES -------------------------------
// all of our routes will be prefixed with /api
app.use('/api', addItemRoute);
app.use('/api', getCategoryRoute);
app.use('/api', addCategoryRoute);
app.use('/api', addSubCategoryRoute);
app.use('/api', getSubCategoryRoute);
app.use('/api', getAllItemsRoute);
// START THE SERVER
// =============================================================================
app.listen(port);
console.log(`Server started on port ${port}`);
getAllCategories() function
Object.defineProperty(exports, '__esModule', {
value: true,
});
const pool = require('./connection');
module.exports = function (res) {
pool.getConnection((err, connection) => {
if (err) {
connection.release();
return res.json({ code: 100, status: 'Error in connection database' });
}
console.log(`connected as id ${connection.threadId}`);
connection.query('select * from category;', (err, rows) => {
connection.release();
if (!err) {
return res.json(rows);
}
});
connection.on('error', err => res.json({ code: 100, status: 'Error in connection database' }));
});
};
If you get an error in connection.query() you send a response with res.json(). This error is caught in connection.on('error') where you send another response. You can't send two responses to the same request. It seems that in this case, you don't really need connection.on() at all or if you have it to catch other errors, don't send a response on connection.query()'s error.

Resources