Reputation: 1333
I have a project that was started as ES5.1, later I changed it to support ES6 so I was using async-await, let...
now I need to have module/object that is instance-like.
I found this post explaining the process, but...
when I do:
'use strict';
let _ = require('lodash');
var mappings;
function SafeRequestHandler(reqMappings) {
if (!(this instanceof SafeRequestHandler)) {
return new SafeRequestHandler((reqMappings));
}
mappings = reqMappings;
}
function safeHandleReq(req, res) {
try {
let pair = _.find(mappings, {'url': req.url});
return pair.handler(req, res);
} catch (err) {
console.log(err);
}
}
SafeRequestHandler.prototype.safe = safeHandleReq;
module.exports = SafeRequestHandler;
but now, each time I do:
var handler = require('../util/safeRequestHandler');
let handlerMappings = [
{
url: def.party_create,
handler: partyCreate
},
{
url: def.party_modify,
handler: partyModify
},
{
url: def.party_get,
handler: partyGet
}
];
var handle = new handler(handlerMappings).safe;
I get this.mappings
REPLACED in SafeRequestHandler
eg. it's NOT an instance.
so I tried ES6 approach defining the handler:
'use strict';
let _ = require('lodash');
class SafeRequestHandler {
constructor(reqMappings) {
this.mappings = reqMappings;
}
safeHandleReq(req, res) {
try {
let pair = _.find(this.mappings, {'url': req.url});
return pair.handler(req, res);
} catch (err) {
console.log(err);
}
}
}
and instantiate it like:
let handlerMappings = [
{
url: def.party_create,
handler: partyCreate
},
{
url: def.party_modify,
handler: partyModify
},
{
url: def.party_get,
handler: partyGet
}
];
let handle = new SafeRequestHandler(handlerMappings).safeHandleReq;
..but this way I can't even reach out mappings
in safeHandleReq(...)
. this
is undefined, mappings
is undefined
I think I just don't fully understand basic principles, so can you please correct&explain what is wrong with this two approaches?
Thanks!
Upvotes: 0
Views: 63
Reputation: 14189
You will lose the context if you store a method
of a specific class instance into a variable.
// handle doesn't have a pointer to its context (aka, this)
let handle = new SafeRequestHandler(handlerMappings).safeHandleReq;
// so handle() will output cannot read property mappings of undefined
Change it to:
const instance = new SafeRequestHandler(handlerMappings);
const handle = (...args) => instance.safeHandleReq(...args);
Further info here: Losing "this" context in JavaScript when passing around members
Upvotes: 1
Reputation: 138317
Your first code creates a global variable, so theres just one value. You might use this there too:
let _ = require('lodash');
function SafeRequestHandler(reqMappings) {
if (!(this instanceof SafeRequestHandler)) {
return new SafeRequestHandler((reqMappings));
}
this.mappings = reqMappings;
}
SafeRequestHandler.prototype.safeHandleReq = function(req, res) {
try {
let pair = _.find(this.mappings, {'url': req.url});
return pair.handler(req, res);
} catch (err) {
console.log(err);
}
}
module.exports = SafeRequestHandler;
Upvotes: 0