Matthew Kaye
Matthew Kaye

Reputation: 465

Requirejs dynamic reference to sub module methods?

Using requires, I’ve split larger class structures down into modules that use other modules within directory. There’s a main file that instantiates the other sub modules. This is an API class with two modules. One that deals with posting data to the endpoint, and the other that holds functions that are helpers to that post module:

define([
'./Post',
   './Helper'
], function (PostModule, HelperModule) {
    'use strict';
    var module = function () {
        this.Post = new PostModule();
        this.Helper = new HelperModule();
    };
    return module;
});

Now I can chain these modules like this:

var foo = new ApiModule();
foo.Post.postToAPI();
foo.Helper.matchAPIactionToEvent();

which is exactly what I want..

BUT, the problem is within the Post.js file, is that it doesn’t know anything about the Helper.js file. So I can’t take advantage of any of those methods. What I would like to do within the Post.js file is to be able to reference the other functions within the same class like so:

define([
'../environment',
'loglevel',
'../utility/Utility',
'jquery'
], function (EnvironmentModule, log, UtilityModule, $) {
    'use strict';
    var module = function () {
        var environment,
            utility,
            api;

        environment = new EnvironmentModule();
        utility = new UtilityModule();

        this.postToAPI = function (event, payload, callback) {
            var apiEndpoint,
                requestIdString,
                eventAndAction;

            apiEndpoint = environment.getEnvironmentPath().API;
            requestIdString = utility.String.generateRandomString(32);

            /*** THIS IS HOW I WANT TO CALL THE HELPER METHODS ***/
            eventAndAction = this.Helper.matchAPIactionToEvent(event);
            /*** THIS IS HOW I WANT TO CALL THE HELPER METHODS ***/

            payload.event = eventAndAction.event;
            payload.action = eventAndAction.action;
            payload.requestID = requestIdString;
            payload = $.param(payload);

            $.post(apiEndpoint + '?' + payload, function (result) {
                if (callback) {
                    callback(result);
                }
            });
            return;
        };
    };
return module;
});

I figured out a working solution to the this, where I pass '../api/Helper' as one of the array values in the define statement of Post.js; but I don’t want to do that. What I want is to have Post.js be able to access any method from any other modules that are contained within the same directory. That way I don’t have to explicitly define them. It seems wrong to instantiate a new ApiModule() within Post.js. Here’s the directory structure:

Modules/api/Api.js
Modules/api/Post.js
Modules/api/Helper.js
...

I hope that makes sense. Is this possible?

Upvotes: 0

Views: 404

Answers (1)

Louis
Louis

Reputation: 151380

Since you want any of the child modules to access any other child modules, what you could do is pass the parent module as an argument to the constructors of the child modules:

var module = function () {
    this.Post = new PostModule(this);
    this.Helper = new HelperModule(this);
};

Have the child modules store this information:

var module = function (parent) {
    this.parent = parent;

Then use this this.parent to call the methods on other child modules:

eventAndAction = this.parent.Helper.matchAPIactionToEvent(event);

Note that if you would load '../api/Helper' with RequireJS in Post.js as you were thinking of doing, you would not be able to use the same object instance as the one defined on the parent module. You'd have to construct a new object for use in Post.js.

Upvotes: 1

Related Questions