How does the const a = express() works exactly? - javascript

I recently started learning Node/express. One doubt is bugging me for a couple of weeks now. I know what this does, and I've been able to get past it. But I cannot wrap my head around the logic used in the line const a = express().
express = require('express');
const a = express()
I don't think I have seen this before in javascript. In this case, express is an object or function (functions are also object in JavaScript) right? And this line is what gives the variable a access to lots of important methods like listen() and get(). But doesn't the syntax here is wrong? To use the express() function, we need to write like
const express = require('express');
const a = express.express()
or we need to use object destructuring to write like
const {express} = require('express');
const a = express()

Perhaps the confusion is in assuming that the default export of the express module is something other than a function, but as others have pointed out, the default export of express is a function. Once imported, the returned value of that function is an instance of Express which is where you then have access to all those methods you mentioned.
Imagine that the definition of function express and the object it returns looks something like
class Express {
// Implementation of Express server
}
// You're importing this and calling the function, receiving a new instance of this class. In reality this could be a class or object for all I know.
export default function express() {
return new Express()
}

Related

Best Practice for Route Architecture

I'm trying to set up routes for my backend. I have two ways that I've tried setting these routes up, and I'm wondering which way fits best practices (or neither?). The differences are minimal, but I'd love to know if there is an objective "best" here.
Here are my attempts:
const express = require("express");
const router = express.Router();
const flashcardController = require('../controllers/flashcardController');
router.get('/', flashcardController.readFlashcard);
router.post('/', flashcardController.createFlashcard);
router.patch('/', flashcardController.updateFlashcard);
router.delete('/', flashcardController.deleteFlashcard);
module.exports = router
VS
const express = require("express");
const router = express.Router();
const flashcardController = require('../controllers/flashcardController');
module.exports = (app) => {
router.get('/api/flashcard', flashcardController.readFlashcard);
router.post('/api/flashcard', flashcardController.createFlashcard);
router.patch('/api/flashcard', flashcardController.updateFlashcard);
router.delete('/api/flashcard', flashcardController.deleteFlashcard);
app.use('/', router);
};
Of course, my app.js (entry-point for my backend) file will need to be coded slightly differently for each of these options.
If you believe that the job of a router is to just handle some requests that it receives and it is the job of the calling code to place the router at whatever path the calling code wants it to operate on, then only your first option will do that. This would allow a caller to use these routes in whatever path it wants.
If you want the module that implements the routes to be entirely self-sufficient and install the routes on the path it wants them to be on, then only the second option does that.
I would say that the "usual" and more "flexible" scheme is the first one where the caller places the routes on the path where it wants them. But, you are free to choose whichever style you want.
The second option is not implemented particularly efficiently so it could be improved. No router is needed at all as the routes can be just installed directly on the app object directly. And, repeating /api/flashcard multiple times can be avoided.
For example, the second option could be this:
const controller = require('../controllers/flashcardController');
const routePath = '/api/flashcard';
module.exports = (app) => {
app.get(routePath, controller.readFlashcard);
app.post(routePath, controller.createFlashcard);
app.patch(routePath, controller.updateFlashcard);
app.delete(routePath, controller.deleteFlashcard);
};
Or, even just this:
const controller = require('../controllers/flashcardController');
module.exports = (app) => {
app.route('/api/flashcard')
.get(controller.readFlashcard)
.post(controller.createFlashcard)
.patch(controller.updateFlashcard)
.delete(controller.deleteFlashcard);
};
And, the first one could be simplified to this:
const router = require("express").Router();
const controller = require('../controllers/flashcardController');
router.route('/')
.get(controller.readFlashcard)
.post(controller.createFlashcard)
.patch(controller.updateFlashcard)
.delete(controller.deleteFlashcard);
module.exports = router

Use a class method in router.get

I'm really new to node.js
and I'm having trouble when I'm using a class method in router.get callback
It gives me this error:
Can you guys help me out ?
Route.get() requires a callback function but got a [object object]
Here is my code
router.js :
const express = require('express');
const router = express.Router();
const test = require('../controller/controller');
router.get('/', test.testing());
module.exports = router;
controller.js :
class oop
{
testing(req,res)
{
console.log('okay');
}
}
exports.testing =new oop();
app.js :
const express = require('express');
const app = express();
app.listen(80);
const wiki = require('./routes/router');
app.use('/', wiki);
A callback function will be called in some arbitrary amount of time, therefore you need to provide a reference to the function... so when the time comes, Javascript can execute that function. In your case, you are not passing the function, but running it! test.testing(). What you are actually passing to the 'callback' parameter is the result of test.testing() which, in this case, is undefined

Facebook Messenger Bot: Understanding Syntax

I am trying to learn how to create a facebook Bot.
I found this amazing article on Medium which illustrates how we can create a messenger bot
In this article, The author tells us to create a verification.js. file inside controllers/verification.js. and paste the following code in it.
module.exports = (req, res) => {
const hubChallenge = req.query[‘hub.challenge’];
const hubMode = req.query[‘hub.mode’];
const verifyTokenMatches = (req.query[‘hub.verify_token’] === ‘crowdbotics’);
if (hubMode && verifyTokenMatches) {
res.status(200).send(hubChallenge);
} else {
res.status(403).end();
}
};
Now, before trying to figure out what this code does (which she have explained), I am unable to understand why haven't she included any dependencies (precisely express) in this Node.Js file?
[Update] Can someone also please explain me in length what does the above code do?
Since this code looks like NodeJS code, Shouldn't she add something like
var express = require("express");
var app = express();
and do module.exports after?
To summarise the comments under the question:
You must import modules only if you need it. That chunk of code simply exports a function that can be used in any other module by importing it.
The author's just exporting an anonymous es6 arrow function, which is totally legit. It can be imported as
import * as whateverYouNameIt from 'controllers/verification';
or
let func = require('controllers/verification');
Have a look at arrow functions and node.js module exports

Express - Accessing top-level express function through dot-notation

In a simple javascript file, we can use express by adding these two lines of code at the beginning (after installing it through npm):
var foo = require('express');
var app = foo();
Now, according to the express API guide:
The app object conventionally denotes the Express application. Create it by calling the top-level express() function exported by the Express module
Since the app object is calling the top-level express() function, how come am I not able to just simply use:
var app = foo.express();
The first line assigns whatever the module 'express' exports to a variable named express. Different modules will export different things (objects, functions). Express exports a function.
The line:
var app = express()
executes the function. This function generates the express application object. This object has all the methods that you use to handle requests in your standard express apps.
The require function that was passed 'express' returns module.exports, which holds the top level function express(), something similar to:
module.exports = express(){...}
That is why we still need to call it either through:
var foo = require('express');
var app = foo();
or
var app = require('express')();
You cannot use:
var foo = require('express');
var app = foo.express();
because it was not set up that way, you could use it if the express module looked something like this:
module.exports.express = express(){...}
I don't know the reason as to why you would choose one over the other, I only know that the second technique simply exposes your function directly.

node.js variable scope with routes separation

my routes are defined in an external folder
./routes
here's the way i define the routes in my server.js file
app.get('/', routes.index);
app.post('/validation', register.valid);
the register.valid module, which is originally written in
./routes/validation.js
is responsible for creating a new user account and register it into a database (MongoDB).
How can i access an object from server.js in validation.js ? First, i thought declaring the object before defining my routes would resolve the case, but actually it doesn't seem to be the solution.
I'm assuming your current code already does work (that is, you receive the posted data), but you need access to another object from validation.js.
If your code works, then you probably have this line in server.js:
var register = require('./routes/validation');
And you need acess to the variable obj in the validation module. You could have a function inside the validation module:
var foo;
exports.configure = function(obj) {
foo = obj;
}
The exports mean the variable configure will be accessible to modules which "require" the validation module. This way you can do, inside the server.js module:
register.configure(obj);
app.post('/validation', register.valid);
The exact configuration of this will depend on what you are actually trying to accomplish. Sometimes, for example, it's good to have a database object stored in a global variable.
Generally in this kind of structure server.js will create the app object and then pass that to individual routes modules via a function. I do it by having each router module export a single function like this:
//routes/validation.js
function setup(app) {
app.get(....blah
app.post(....blah
}
module.exports = setup;
Then I tie that together in server.js like this:
//server.js
var express = require('express');
var app = express();
require('./routes/validation')(app);
See also my express_code_structure sample project for other code organization tips.

Categories