module.exports = app More than One Require - node.js

I'm creating a lambda function on AWS and I'm looking to require more than one file for "app". Apologies, I'm not great with Node yet.
In a routes.js file I have the following...
module.exports = app => {
require("./event.routes.js")(app);
require("./eventtemplate.routes.js")(app);
};
Normally there is only 1 require() between the {}. But I require both files as I've separated out the code into two different files for clarity. When I comment out the second require all is good and the runtime can find the functions in event.routes.js. But with the second require in there. It does not. Do I need to somehow name them? They do have similarly named functions. But they are contained within their "Event" and "EventTemplate" object in those different files.
Here's the event.routes.js file...
module.exports = app => {
const controller = require("../controllers/event.controller.js");
// Create a new event
app.post("/event", controller.create);
};
My eventtemplate.routes.js has similarly named functions. So I'm guessing this is the issue. My attempt to make things cleaner has broken things. Wondering if there is a better way to separate out things?
** UPDATE **
As requested, here is eventTemplate.routes.js...
module.exports = app => {
const controller = require("../controllers/eventtemplate.controller.js");
// Create a new EventTemplate
app.post("/event/template", controller.create);
);

I solved the issue. It was just that I had a misnamed function in my controller file that was being referenced from my route file. I had truncated the source listing for brevity but I would've had to post the controller code as well to see the error.
However thanks for the comments. It did steer me in the right direction to know that what I was doing was fine and correct and was just a typo. Thank you!

Related

Expressjs higher order router vs appending to request

Let's say I want to pass to an ExpressJS route callback an object.
I know I can append to app:
// router.js
const getFoo = (req, res) => res.json(req.app.foo);
// index.js
const app = express();
app.foo = {};
app.get('/foo', getFoo);
or I can use a higher order function:
// router.js
const getFoo = foo => (req, res) => res.json(foo);
// index.js
const app = express();
const foo = {};
app.get('/foo', getFoo(foo));
Both are easy to write, extend and test.
But, I don't know the implications of the solutions and whether one is better.
Is there anyone knowing real differences between the two approaches?
I think the second solution is more correct, here's why.
imagine you get used to the first solution and one day you need to send something called post or get or anything with the name of app property and you forget that there is already a property named like that, so you override original property without even realizing and when you call app.post() program will crash.
Believe me, you don't want hours of research wasted on something like that and realizing that you simply overrode original method
Also, in my opinion, it's always a bad idea mutating original object which wasn't generated by you
As #vahe-yavrumian mentioned it is not a good idea to mutate the state of the object created by a third party library.
between you can also use app.get() and app.set() methods to pass any data to the other routers in the queue (seems those methods are there just for this purpose.)
more information at https://expressjs.com/en/api.html.
The second solution easily allows you to pass different value for foo on different routes, if you ever found a need to do that.
The first solution essentially puts the value on the app singleton, which has all the implications of using singletons. (And as mentioned by #Anees, for express specifically the app settings with get and set are the proper place to store this, not a custom property)

NodeJS, express - routing

I´ve setup a little NodeJS API with 'expressjs'. In my code I have some similar code blocks looking like this:
app.get('/api/my/path', (req, res) => {
doSomethingUseful();
});
All thoses requests do something different, so the function being called is always different too.
I´m asking myself if this is good practice for writing code in NodeJS or not.
If there is a better / cleaner way of writing all those paths I would appreciate if you could tell me how or at least giving me a place to look for it.
EDIT 1: To be clear: I ask if it´s a good idea to write a lot of 'app.get(...)' into one source code file or if there is a better way?
Yes there is a better way than writing all routes in one file. For example, let us say you have routes for users and questions.
For users, you want get/set/put/delete for profile, and similarly for questions.So you create the following folder structure: /api/users and /api/questions
In /api/users,
const express=require('express')
const router=express.Router()
//this handles route: /users
router.get('/',(req,res)=>{})
//this handles route: /users/profile
router.get('/profile',(req,res){})
//this is to retrieve profile of specific user by user id :/users/profile/:userID
router.get('/profile/:userId',(req,res))
router.post('/profile',(req,res))
.
.
Then, in your index.js or entry point of your project,
const users=require('./api/users')
const questions=require('./api/questions')
app=require('express')
app.use('/users',users)
app.use('/questions',questions)
So in effect, you say for any /users route, refer to the users.js file, for any /questions routes, refer questions.js file and so on
Use a simple module, don't be invoking routes until you form a heap.
Try Route Magic
You want to do just 2 lines of code and have the module read your directory and file structure to handle all the app.use routing invocations, like this:
const magic = require('express-routemagic')
magic.use(app, __dirname, '[your route directory]')
For those you want to handle manually, just don't use pass the directory to Magic.

What is the best way to separate your code in a Node.js application?

I'm working on a MEAN (Mongo Express.js Angular Node.js) CRUD application. I have it working but everything is in one .js file. The single source code file is quite large. I want to refactor the code so CRUD functionality is in different source code files. Reading through other posts, I've got a working model but am not sure it is the right way in Node using Mongo to get it done.
Here's the code so far:
<pre>
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var path = require('path');
var db;
var connect = 'mongodb://<<mddbconnect string>>;
const MongoClient = require('mongodb').MongoClient;
var ObjectID = require("mongodb").ObjectID;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(__dirname + '/'));
// viewed at http://localhost:<<port referecnes in app.listen>>
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/index.html'));
});
MongoClient.connect(connect, (err, database) => {
if (err) return console.log(err)
db = database
app.listen(3000, () => {
console.log('listening on 3000' + Date() );
// Here's the require for the search function in another source code file.
var searchroute = require('./serverSearch')(app, db);
})
})
//Handlers
The rest of the CRUD application functions with app.post, app.get. These are other functions I want to move into different source code files, like serverSearch.js.
</pre>
The code I separated right now is the search functionality which is inside of the MongoClient.connection function. This function has to successfully execute to make sure the variable 'db' is valid before passing both variables 'app' and 'db' to the the search function built out in the source code file serverSearch.js.
I could now build out my other CRUD functions in separate files in put them in the same area as 'var searchroute = require('./serverSearch)(app,db);
Is this the best way to separate code in a MEAN application where the main app and db vars need to be instantiated then passed to functions in other source code files?
What you are basically describing is modular coding heading towards "services" perhaps even micro-services. There are a few factors to keep in mind for your system. (I have no doubt that there are many other approaches to this btw). Basically in most NodeJS systems I have worked on (not all) I try to apply the following architecture in development and then bring over as much as possible I to production.
Create a directory under the main one. I usually use some type of name that points to the term functions. In this directory I maintain function and /or class files divided into categories. Function wrappers for DB would be held in DB functions. This file would only contain functions for the DB. Security functions in another file. Helper functions in another. Time manipulation in another. I am sure you get the idea. These are all wrapped in module exports
Now in any file in my project where say I would need DB and helpers I will start it by:
let nhelpers = require("helpfuncs");
let ndb = require("dbfuncs");
Obviously names are different.
And btw I divide all the NPM packages in the same way under an environment directory.
Maintaining that kind of structure allows you to maintain sane order over the code, logical chaining in any decent IDE, and having relevant methods show up in your IDE without having to remember every function name and all the methods within.
It also allows you to write an orderly system of micro-services making sure each part dies exactly what you want and allows for sane debugging.
It took me awhile to settle on this method and refine it.
It paid off for me. Hope this helps.
Edit to clarify for the OP:
When it comes to the process.env variables I became a great fan of dotenv https://www.npmjs.com/package/dotenv
This little package has saved me an incredible amount of headaches. Of course you will have to decide if you include it in production or not. I have seen arguments for both, but i think in a well set up AWS, Google, Azure environment (or in Docker of course) I am of the opinion it can safely be used.
A couple of caveats.
Do not leave your dotenv file in the root. Move it somewhere else in your directory structure. It is simple and I actually put it in the same directory as all my environment files and helper files.
Remember it is simply a text file. So an IDE will not pick up your specific env variables in chaining. (Unless someone knows of a trick which I would love to hear about)
If you put env variables like access info to your DB system or other sensitive stuff, HASH THEM FIRST, put the hash in your env and have a function in your code which specifically just does the hash to the string. Do not under any conditions leave sensitive information in your environment file without hashing it first.
The final Gatcha. These are not PHP magic globals which cannot be overwritten. If you lose track and overwrite one of those process.env variables in your code it will take the new value until you restart your node app and it reads from the dotenv file again. (But then again that is the rule with all environment variables not only user defined ones)
Any typos above excuse me. Done from my cell in the train.

Where should I put custom errors in sails.js?

I was wondering what's the best practice and if I should create:
a directory in which declare statically all the errors my application uses, like api/errors/custom1Error
declare them directly inside the files
or put the files directly inside the dir that needs that error, like api/controller/error/formInvalidError
other options!?
A neat way of going about this would be to simply add the errors as custom responses under api/responses. This way even the invocation becomes pretty neat. Although the doc says you should add them directly in the responses directory, I'm sure there must be a way to nest them under, say, responses/errors. I'll try that out and post an update in a bit.
Alright, off a quick search, I couldn't find any way to nest the responses, but you can use a small workaround that's not quite as neat:
Create the responses/errors directory with all the custom error response handlers. Create a custom response and name it something like custom.js. Then specify the response name while calling res.custom().
I'm adding a short snippet just for illustration:
api/responses/custom.js:
var customErrors = {
customError1: require('./errors/customError1'),
customError2: require('./errors/customError2')
};
module.exports = function custom (errorName, data) {
var req = this.req;
var res = this.res;
if (customErrors[errorName]) return customErrors[errorName](req, res, data);
else return res.negotiate();
}
From the controller:
res.custom('authError', data);
If you don't need logical processing for different errors, you can do away with the whole errors/ directory and directly invoke the respective views from custom.js:
module.exports = function custom (viewName, data) {
var req = this.req;
var res = this.res;
return res.view('errors/' + viewName, data);//assuming you have error views in views/errors
}
(You should first check if the view exists. Find out how on the linked page.)
Although I'm using something like this for certain purposes (dividing routes and so on), there definitely should be a way to include response handlers defined in different directories. (Perhaps by reconfiguring some grunt task?) I'll try to find that out and update if I find any success.
Good luck!
Update
Okay, so I found that the responses hook adds all files to res without checking if they are directories. So adding a directory under responses results in a TypeError from lodash. I may be reading this wrong but I guess it's reasonable to conclude that currently it's not possible to add a directory there, so I guess you'll have to stick to one of the above solutions.

What is the purpose of the `(app)` in `require(controller)(app)`?

I'm new to node, blah blah
I'm looking through some code I found, and encountered the lines
var app = express();
var glob = require('glob');
var controllers = glob.sync(config.root + '/app/controllers/*.js');
controllers.forEach(function (controller) {
require(controller)(app);
});
I understand that this goes and gets all the filenames of every file in /app/controllers/ that ends with .js, and sticks them in an array, then iterates over each one and calls a require on it. Makes sense, and looks like a nice way of not requiring each one individually. My question is what's that last (app) for? I tried looking at node documentation, but there is no require()() function. editing out the (app) leaves the code working fine with no errors, but doesn't load the controllers. If I had to take a guess, is it 'multiplying' the app by the found controller? Why would app.require(controller) not be a suitable option?
Thanks in advance
require is a part of node and is how modules are loaded. When you edit out the (app), it is probably still loading the controllers but because you haven't passed the app object over to each controller, they fail silently or return a controller object that doesn't work.
So something in the controller (probably a route being created or other similar stuff) needs to know about the app object and it has to be passed into the controller because app isn't in the global scope. You may want to review the node docs for module and globals as those will probably clear up WAY more than just this one question.
In my estimation we will have:
/* some-controller-file.js */
module.exports = function (app) {
/* do things with `app` */
}
So this allows you to use the created app inside of the controllers probably so you can attach routes.

Resources