0

Suggested duplicate does not sufficiently serve as an answer. link is better answer. And matches @deceze reply


I'm a convert to node from .net. Thus I'm loving the syntactic sugar provided by es6. I have run myself into a scoping problem during one of my complexity refactors.

I return my promises from inside classes. I refactored a little of PolicyMapper.mapDao() code into another class function (mapJSONtoDAO). Unit testing has no problem with this. The problem occurs during chaining with other promises. this.mapJSONtoDAO() becomes undefined.

route.js ->

const policyService = new PolicyService();
const policyMapper = new PolicyMapper();
const policyMapPromise = policyService.getPolicy(req.body.policyNumber, office)
    .then(policyMapper.mapDao, next);

PolicyMapper class ->

class PolicyMapper {
    mapDao(soapResponse) {
        return new Promise((resolve, reject) => {

            xml2js.parseString(soapResponse[config.responseProperty], {}, (error, json) => {
                resolve(this.mapJSONtoDAO(json));
            });
        });
    }

    mapJSONtoDAO(json) {
        let policyDAO = new PolicyDAO();
        policyDAO.givenName = json["policy-response"]["given-name"]
        return policyDAO;
    }
}

The below refactor of the route.js protects scope association between class and promise. Is there an simplier way to inplement this. I really want my code to be simple for any engineer maintaining my code.

const policyService = new PolicyService();
const policyMapper = new PolicyMapper();
const policyMapPromise = policyService.getPolicy(req.body.policyNumber, office)
    .then((soapResponse) => {
        return policyMapper.mapDao(soapResponse)
    }, next);
Community
  • 1
  • 1
David Stewart
  • 205
  • 2
  • 9
  • 1
    If your classes have no state, you probably shouldn't be using instance methods. And instead of static methods, just don't use classes at all. Then you won't have problems with `this` either. – Bergi Feb 01 '17 at 12:15
  • The `this` context is lost because you merely pass the callback as `policyMapper.mapDao`, at which point it's separated from its object. You need to `bind()` the object if you want to keep it. – deceze Feb 01 '17 at 12:20
  • Suggested duplicate does not sufficiently serve as an answer. [Here](http://stackoverflow.com/questions/38334062/why-do-you-need-to-bind-a-function-in-a-constructor) is better answer. And matches @deceze reply – David Stewart Feb 01 '17 at 15:46
  • Instead of `(soapResponse) => { return policyMapper.mapDao(soapResponse }`, you can use `(soapResponse) => policyMapper.mapDao(soapResponse) ` or `policyMapper.mapDao.bind(policyMapper)`. – JLRishe Feb 01 '17 at 15:57

0 Answers0