What does ".Strategy" do in Node or Passport? - node.js

What does ".Strategy" do here? Is it Node? Is it Passport?
var LocalStrategy = require('passport-local').Strategy;
Everything up to '.Strategy' part I understand. I just want to know what '.Strategy' does. I have checked the documentation on passport-local module on npm. I have also checked Passport's documentation, and it is just used in code snippets. No explanation is provided.
I am working with the MEAN stack and we are using Passport to authenticate users.

If you look at the sources of passport-local index.js you'll see it exports the same thing directly and in exports.Strategy.
When you do require('passport-local).Strategy you import the export defined in exports.Strategy, but it's really the same to do just require('passport-local') in this case because the same constructor is exported directly from the module.
If you define a module like this:
var Thing = { foo: () => 'bar' };
exports = module.exports = Thing;
exports.Thing = Thing;
you can use it in many ways:
const Thing = require('./module');
console.log(Thing.foo());
works, as does
const Thing = require('./module').Thing;
console.log(Thing.foo());
and with both imports you can actually call also
console.log(Thing.Thing.foo());
If you remove the exports.Thing = Thing; part of the module, then
const Thing = require('./module').Thing;
does not work anymore.
The exports cause confusion often. You could take a look of Node docs or eg. this answer.

Related

confused about node-localstorage

so I'm making a site with node js, and I need to use localstorage, so I'm using the node-localstorage library. So basically, in one file I add data to it, and in another file I want to retrieve it. I'm not 100% sure about how to retrieve it. I know I need to use localStorage.getItem to retrieve it, but do I need to include localStorage = new LocalStorage('./scratch');? So I was wondering what the localStorage = new LocalStorage('./scratch'); did. So here is my code for adding data:
const ls = require('node-localstorage');
const express = require("express");
const router = express.Router();
router.route("/").post((req, res, next) => {
var localStorage = new ls.LocalStorage('./scratch');
if(req.body.name != undefined){
localStorage.setItem("user", req.body.name);
res.redirect('/')
}
else{
console.log("undefind")
}
});
module.exports = router;
If my question is confusing, I just want to know what var localStorage = new ls.LocalStorage('./scratch'); does.
A drop-in substitute for the browser native localStorage API that runs on node.js.
It creates an instance of the "localStorage" class, which this library provides. The constructor expects the location of the file, the scripts stores the key, value elements in.
Opinion: This looks pointless to me - I guess it fits your use case.

Destructuring the t method out of i18next breaks it

I want to translate my node.js application using i18next.
In the documentation and examples the translations are made like this (supposing i18next is already initialized properly) :
const i18next = require("i18next")
console.log(i18next.t("key"))
I have a big quantity of text to translate at various places, so I would like to be able to save time by destructuring the t method like this :
const { t } = require("i18next")
console.log(t("key"))
But I get the following error : TypeError: Cannot read property 'translator' of undefined. It looks like the method is using the other properties of the i18next object, causing its destructuring to break it.
Is there any workaround?
I haven't verified this, but you should be able to do something like this
const i18next = require("i18next")
const t = i18next.t.bind(i18next);
console.log(t("key"))
I would suggest some better naming than t though...

Instantiate node module differently per (web) user

I was wondering what the best practice is for the following scenario:
I am planning to use an npm module for a web servie, where the user enters a access and secret key. Then a module is used which is instantiated like this:
var module = require('module')('ACCESS_KEY','SECRET_KEY');
Each user of course has a different access and secret key. The module exposes several functions which I want to use with the user's access and secret key on his behalf.
Now my question is, how I can 'require' that module with the keys from the database for each user, not just for the whole application with a single static pair. I am on node 8 and using ES6.
The crucial detail here is that this:
var module = require('module')('ACCESS_KEY','SECRET_KEY');
...is equivalent to this:
var moduleFunc = require('module');
var module = moduleFunc('ACCESS_KEY', 'SECRET_KEY');
In other words, 'module' exports a function, and you're calling that function with two arguments ('ACCESS_KEY', 'SECRET_KEY') and assigning the result to module.
That means you can instead require('module') at the top of your file and then use the function it gives you as many times as you want later on, with different arguments.
For example:
const someApi = require('some-api');
// ...later...
app.get('/', (req, res) => {
const { ACCESS_KEY, SECRET_KEY } = getUserKeys(req);
const apiClient = someApi(ACCESS_KEY, SECRET_KEY);
// ...
});

Having control flow issue with mongoose model's find

I'm completely new to node and it's frameworks Koa and express. I've a mongoose model called Drawing and a router module for that.
Problem is with express routers I was able the get the data from database using Drawing.find method but with Koa, control is not even going into Drawing.find. And I'm not able to get the data at all. Please find the following related code and help me understand the things better.
This is my router module
import * as Router from "koa-router";
import Drawing from "../../models/drawing";
function getRoutesForDrawing(): Router {
console.log("Inside getRoutes for drawing");
let route = new Router();
route.get("/drawing", function(context,next) {
console.log("Inside /drawing");
Drawing.find(function(err,drawings) {
console.log("Not gettig executed");
context.body = "Welcome";
});
//context.body = "Welcome";
});
}
export default getRoutesForDrawing();
And the model is
import mongoose = require("mongoose");
export interface IDrawing extends mongoose.Document {
drawingId:Number,
drawingName:String,
updatedOn:Date,
updatedBy:Number
};
export const DrawingSchema = new mongoose.Schema({
drawingId:Number,
drawingName:String,
updatedOn:Date,
updatedBy:Number
});
const Drawing = mongoose.model<IDrawing>('Drawing', DrawingSchema);
export default Drawing;
As you can see in my router module, the control is actually coming for /drawing and it's printing in console "Inside /drawing" but then control isn't coming to Drawing.find. I'm getting difficulty in understanding this.
It's a little bit hard to figure out what's going on because it looks like you have problems all over the place. Let me point out the things that stand out:
getRoutesForDrawing is declared to return a router and doesn't return anything
Koa routes are not like express. In particular they are not callback based. They take either generator functions (Koa 1.x) or async functions (Koa 2.x). You seem to expect that it's wanting a callback function which won't work. Assuming koa 2.x, its router.get('/drawing', async(context) => {...});
Assuming koa 2.x, you need to await the result of the mongoose methods, e.g. context.body = await Drawing.find({})

Using Express.js 3 with database modules, where to init database client?

Knowing that Express.js pretty much leaves it to developer on deciding app structure, and after reading quite a few suggestions on SO (see link1 and link2 for example) as well as checking the example in official repo, I am still not sure if what I am doing is the best way forward.
Say I am using Redis extensively in my app, and that I have multiple "models" that require redis client to run query, would it be better to init redis client in the main app.js, like this:
var db = redis.createClient();
var models = require('./models')(db);
var routes = require('./controllers')(models);
or would it be better to just init redis in each model, then let each controller require models of interests?
The latter approach is what I am using, which looks less DRY. But is passing models instance around the best way? Note that I am loading multiple models/controllers here - I am not sure how to modify my setup to pass the redis client correctly to each models.
//currently in models/index.js
exports.home = require('./home.js');
exports.users = require('./user.js');
TL;DR, my questions are:
where best to init redis client in a MVC pattern app?
how to pass this redis client instance to multiple models with require('./models')(db)
Update:
I tried a different approach for index.js, use module.exports to return an object of models/controllers instead:
module.exports = function(models){
var routes = {};
routes.online = require('./home.js')(models);
routes.users = require('./user.js')(models);
return routes;
};
Seems like a better idea now?
Perhaps it's useful if I share how I recently implemented a project using Patio, a SQL ORM. A bit more background: the MVC-framework I was using was Locomotive, but that's absolutely not a requirement (Locomotive doesn't have an ORM and it leaves implementing how you handle models and databases to the developer, similar to Express).
Locomotive has a construct called 'initializers', which are just JS files which are loaded during app startup; what they do is up to the developer. In my project, one initializer configured the database.
The initializer established the actual database connection, also took care of loading all JS files in the model directory. In pseudocode:
registry = require('model_registry'); // see below
db = createDatabaseConnection();
files = fs.readDirSync(MODEL_DIRECTORY);
for each file in files:
if filename doesn't end with '.js':
continue
mod = require(path.join(MODEL_DIRECTORY, filename));
var model = mod(db);
registry.registerModel(model);
Models look like this:
// models/mymodel.js
module.exports = function(db ) {
var model = function(...) { /* model class */ };
model.modelName = 'MyModel'; // used by registry, see below
return model;
};
The model registry is a very simple module to hold all models:
module.exports = {
registerModel : function(model) {
if (! model.hasOwnProperty('modelName'))
throw Error('[model registry] models require a modelName property');
this[model.modelName] = model;
}
};
Because the model registry stores the model classes in this (which is module.exports), they can then be imported from other files where you need to access the model:
// mycontroller.js
var MyModel = require('model_registry').MyModel;
var instance = new MyModel(...);
Disclaimer: this worked for me, YMMV. Also, the code samples above don't take into account any asynchronous requirements or error handling, so the actual implementation in my case was a bit more elaborate.

Resources