5

I'm attempting to write a node module in order to clean up my code and separate it out into different files.

Consider the below code:

module.exports = {
    Hello : function(request, reply) {
        return reply("Hello " + World());
    },
    World : function() {
        return "World";
    }
}

If I import the above module and use the Hello function as handler for a specific route, i get an HTTP 500 internal server error.

I've narrowed the problem down to the call to World(), if I change the Hello function to

Hello : function(request, reply) {
    return reply("Hello World");
}

Then it works fine, so it seems that it is being tripped up when calling another function from within the export object

Does anyone know why this is happening and how to resolve it?

8
  • jsfiddle.net/rc62tuw8 Commented Aug 20, 2017 at 16:13
  • Stange. It works in fiddle with this. appended, however it my application doesn't seem to like it Commented Aug 20, 2017 at 16:24
  • @Michael: It depends on how Hello is called. If it's not called as method of the exported object, this won't refer to the object. Commented Aug 20, 2017 at 16:27
  • From where exactly do you call your myModule.Hello function..? Commented Aug 20, 2017 at 16:27
  • Its being called from my main app.js file, with the following server.route({ method: 'GET', path: '/user/new/{q}', handler: testy.Hello }); There seems to be something not quite right, however Ahmads answer works fine Commented Aug 20, 2017 at 16:35

3 Answers 3

5

You should call it as follows:

module.exports = {
    Hello: function(request, reply) {
        return reply("Hello " + module.exports.World());
    },
    World: function() {
        return "World";
    }
}

If you are aiming for cleaner code, I suggest that you change the code to this:

function World() {
  return "World";
}
function Hello(request, reply) {
  return reply("Hello " + World());
}
module.exports = {
    Hello,
}

This will make your code more readable and you will only be exporting what you actually need. This question has other solutions to your issue.

Sign up to request clarification or add additional context in comments.

1 Comment

Your second example works fine! Very strange, the first example does not.
3

Well let's demonstrate the this

this doesn't define the object that the function resides in. It defines from where the function is called. So while;

var obj = {
    Hello : function(request, reply) {
        return reply("Hello " + this.World());
    },
    World : function() {
        return "World";
    }
};
obj.Hello("test", console.log);

would work just fine; This wouldn't;

var obj = { Hello : function(request, reply) {
                      return reply("Hello " + this.World());
                    },
            World : function() {
                      return "World";
                    }
          };

setTimeout(obj.Hello,100,"test",console.log);

This is just because the obj.Hello will be assigned an argument in setTimeOut function's definition and that argument will be invoked as window being the this for that function. So you should instead do like;

var obj = { Hello : function(request, reply) {
                      return reply("Hello " + this.World());
                    },
            World : function() {
                      return "World";
                    }
          };

setTimeout(obj.Hello.bind(obj),100,"test",console.log);
//or 
setTimeout(obj.Hello.bind(obj,"test",console.log),100);
//or
setTimeout((x,y) => obj.Hello(x,y),100,"test",console.log);

2 Comments

This is very helpful explanation, i thought that the reply() function might be doing some 'magic' behind the scenes which was screwing it up, however Ahmads answer (2nd part) works fine and its pretty much exactly the same, just different syntax. I'm really baffled as to the cause, but nonetheless it is working
@Michael See my comment under your question. It should work regardless whatever magic reply does provided that you have return reply("Hello " + this.World()); instruction in your testy module's Hello method.
2

You'll need to add this to your invocation of World() -

module.exports = {
    Hello : function(request, reply) {
        return reply("Hello " + this.World());
    },
    World : function() {
        return "World";
    }
}

World is an attribute of the export object, not a variable within the accessible scope - so you need to specify that the function belongs to this.

3 Comments

I thought the same, however it has no effect - I still get an HTTP 500
Out of curiosity, where is reply defined?
This would only work if the Hello function is executed against the module, like someModule.Hello(). That is unlikely when exporting callback functions for a web server.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.