I'm doing to some refactoring in my application and I don't understand why this case is failing.
index.js
const express = require('express');
const router = express.Router();
const models = require('../models');
const listRoute = require('./list');
router.use('/list', listRoute);
list.js
const express = require('express');
const router = express.Router();
const models = require('../models');
const sendListDataToView = (req, res, view) => {
// get data from backend and pass to template
}
router.route('/list/show/:id')
.get((req, res) => {
sendListDataToView(req, res, 'view-list')
})
router.route('/list/expand-records-forms/:id')
.get((req, res) => {
sendListDataToView(req, res, 'edit-list-records')
})
module.exports = router;
Trying to navigate to /list/show/3 throws a 404 error. However, if I move the definitions of these routes and sendListDataToView to index.js, the page loads fine. Is this because of the multiple router.routes?
I'm just going to wipe my original answer.
You need to create the app.
const express = require('express');
const app = express();
const models = require('../models');
const listRoute = require('./list');
app.use('/list', listRoute); // Using express now.
app.listen(8080); // starts server
Related
I am new to Node.js and trying to make an API which would add a user into MongoDB database, my problem is I am Unable to access any properties of res & req in my controller. I tried searching for answer on SO but it seems the problem lies how you export the routes but the more I see the answers the more I get confused.
Here is part of my Server.js file,
const express = require("express");
const { readdirSync } = require("fs");
const dotenv = require("dotenv");
const app = express();
const mongoose = require("mongoose");
app.use(cors(options));
app.use(express.json());
This is how I am registering Routes,
readdirSync("./routes").map((r) => app.use("/", require("./routes/" + r))); //here route folder is being registered as a controller
Now in my Routes/User.js
const express = require("express");
const { register } = require("../controllers/user");
const router = express.Router();
router.get("/register", register);
module.exports = router;
In Controller/User.js
exports.register = async (req, res) => {
// here is the problem, when this controller is hit, i want to send response back
// like res.send("user added successfully") but I am unable to access req."send" or "body"
};
I have Tried using app.use(express.json()); answer on some forums but to no avail.
Here my server code
var express = require("express");
var isAuthen = require('./middleware/authorize')
var router = express.Router();
var app = express();
var order_process = require('./routes/order-process');
app.use('/order',isAuthen, order_process);
and here order_process code
var express = require('express');
var bodyParser = require('body-parser');
const bcrypt = require("bcrypt");
var router = express.Router();
var db = require('../models/database');
router.get('/', urlencodedParser, function (req, res) {
try {
console.log(req.params);
}catch(err){
console.log(err);
}
module.exports = router;
http://localhost:3000/order/2
as i know that url should return number 2 ??
i dont know why it cannot return ?
should return correct params from url
Here's an example of how to get the params from a route:
const express = require('express');
const router = express.Router();
const app = express();
app.use('/order', router);
router.get('/:page', (req, res) => {
res.send(`You are viewing page ${req.params.page}`);
});
const server = app.listen(8000);
Then go to http://localhost:8000/order/2 and you should see it say:
You are viewing page 2
Given a simple Express app
const express = require('express')
const app = express()
app.get('/users/:userId', (req, res) => {
console.log(req.orginalUrl) // /users/1
console.log(req.route.path) // /users/:userId
res.json({})
})
It gives me the right and complete route schema req.route.path.
But if we use a router to abstract the first part of the URI then it doesn't give the full route schema anymore.
const express = require('express')
const app = express()
const users = express.Router()
.get(':userId', (req, res) => {
console.log(req.orginalUrl) // /users/1
console.log(req.route.path) // /:userId
res.json({})
})
app.use('/users', users)
It there a way to get /users/:userId while using routers?
You just have to concatenate baseUrl and path like this :
let fullPath = req.baseUrl + req.route.path;
I'm new to express and node js, I recently learned how to write API for express but at the end, I get some sort of problem which not resolved by me after several tries. I could not get a response on localhost:8080/users
src/routes/users.js
const { Router } = require("express");
const router = Router();
const getUsers = (req, res) =>
res.send(Object.values(req.context.models.users));
const getUser = (req, res) =>
res.send(req.context.models.users[req.params.userId]);
router.get("/users/", getUsers);
router.get("/users/:userId", getUser);
module.exports = router;
src/routes/index.js
const user = require("./user");
const message = require("./message");
module.exports = {
user,
message
};
src/index.js
const express = require("express");
const app = express();
// Custom Modules
const routes = require("./routes");
const models = require("./models");
// Application-Level Middleware Starts
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use((req, res, next) => {
req.context = {
models,
me: models.users[1]
};
console.log(req.context.models.users);
next();
});
// Used Routes
app.use("/users", routes.user);
app.use("/messages", routes.message);
// App Listning to HTTPS Module
app.listen(process.env.PORT);
You need to fix your endpoints in users.js:
router.get("/", getUsers);
router.get("/:userId", getUser);
The reason is because of app.use("/users", routes.user); in your index.js, where the endpoint for users is set. If you leave /users/ in users.js it would be localhost:8080/users/users/. Same problem might be with /messages.
I am trying to most optimally structure the files of my Express app. And the Router module confuses me.
As far as I know, all queries should be in models folder.
This is my current desired setup (which does not work for my query.js and query2.js files, the error I get is that "App" is not defined).
When I put the query code (from query.js file) inside my App.js file directly, then it works however.
Also the setup I have works correctly for my Email routing.
How to fix?
Here my project structure:
project_structure
Here content of my files:
APP.JS
const express = require('express');
const request = require('request');
const requestPromise = require('request-promise');
const bluebird = require('bluebird');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
app.use(cors());
const router = require('./routes');
app.use(router);
function App(req, res) {
if (!req.url) {
req.url = '/';
req.path = '/';
}
return app(req, res);
}
module.exports.my_server = App;
INDEX.JS (in routes folder)
const express = require('express');
const router = express.Router();
const config = require('../config');
let email = require('../models/email');
const query = require("../models/query");
const query2 = require("../models/query2");
router.post('/api/subscribe', function (req, res) {
const data = {
subscribed: true,
address: req.body.email,
};
...
module.exports = router;
QUERY.JS (in models folder)
app.get('/query', function(req, res, next) {
request({
uri: 'https://queryapi.api/search?q=stuff&api-key=api_key',
qs: {
api_key: 'api_key',
}
}).pipe(res);
});
You don't have access to the variable app from your query.js.
You would want to export your methods from query.js instead so you can import them to your router like this:
EDIT: change http verb from .get to .post
replace:
app.get('/query', function(req, res, next) {
with
exports.post = function(req, res, next) {
and this is how you would assign the exported method query.post to route /api/subscribe/query
const query = require("./query");
router.post('/api/subscribe/query', query.post);
/* more end points below: */
// router.get(...
// router.put(...
// ...and so on
POST request on /api/subscribe/query
P.S: This works but things can quickly get ugly if you have more routes so it would be more maintainable if you restructure your source such that the main routes are expressed clearly in your app entry file; But that's another concern.
In index.js add this line.
router.use(query)