1

I am learning about javascript modules and how to write them. I ran into the issue that im not 100% sure that my pattern is correct. Any comments that might make it easyer for me later on will be nice, but my problem is im not sure how to use the prototype correctly.

I use my module like this:

        var cm = CodeMirror.fromTextArea(document.getElementById("code"), {
            lineNumbers: true,
            matchBrackets: true,
            mode: "text/x-csharp"
        });
        var adapt = new $.codeMirrorSignalRAdapter(cm, $.connection.codeHub);

but in my adapter.prototype hubChange, the this.silent is undefined. I would like to think that the var adapter = function(cm,hub) is the constructor and i do not know how i access the properties, self.[cm,hub,silent] from the prototype functions.

(function ($, window) {
    "use strict";

    if (typeof ($) !== "function") {
        // no jQuery!
        throw new Error("CodeMirrorAdapter: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.");
    }
    if (typeof ($.signalR) !== "function") {
        throw new Error("CodeMirrorAdapter: SignalR is not loaded. Please ensure jquery.signalR-x.js is referenced before ~/signalr/hubs.");
    }

    var adapter = function (cm, hub) {
        var self = this;
        self.cm = cm;
        self.hub = hub;
        self.silent = false;

        cm.on("change", function (_, change) { self.onChange(change); });
        hub.client.Change = self.hubChange;

        return self;
    };

    adapter.fn = adapter.prototype = {
        init: function (cm, hub) {

        },
        onChange: function (change) {
            if (!this.silent) {
                this.hub.server.change(change)
                        .done(function () { })
                        .fail(function (ee) { alert(ee) });
            }
        },
        hubChange: function (change) {
            alert(this.silent);
            this.silent = true;
            this.cm.replaceRange(change.text[0], change.from);
            this.silent = false;
        },
    };


    $.codeMirrorSignalRAdapter = adapter;
}(window.jQuery, window));

Other than the problem with this keyword, does the module design look somewhat okay?

1 Answer 1

1

The value of this can be any of 5 possible options. Read this article on MDN for more info: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this

In your particular case, hub.client.Change = self.hubChange;, you are registering hubChange as the handler. The issue is when the handler is called, there is no code to ensure this has been set to the correct adapter object.

How do we ensure that?

hub.client.Change = function () { self.hubChange.apply(self, arguments);};

You can read more about apply here https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply

What we have done is similar to what you did with the cm.on("change") binding.

Thoughts on the code

Your constructor function ends with a return self; That is not needed. When the function is called as a constructor, ie with the new keyword, it will implicitly return a new instance. When the function is called without the new keyword, it will return whatever the function is returning, which in this case will NOT be a new instance. It will be whatever this has been set to. Most likely it will return window. Suggestion, remove that line. That way if you accidentally call it without the new, you will get back undefined.

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

2 Comments

Thank you, i will take a moment to read up on it. The apply solves the problem.
@s093294, if my attempt answers your question, I would appreciate if you could mark it as the accepted answer. If not, please comment on what is left unanswered.

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.