Stupid JavaScript Thread



  • This is the thread where people can ask stupid questions about JavaScript.

    Here goes!

    I have:

    var ViewModel = function (data) {
      var self = this;
      
      ko.mapping.fromJS(data, {}, self);
    
      var Current = function (idx) {
        this.index = ko.observable(idx);
        this.number = ko.computed (function () { return this.index + 1 });
        this.question = ko.computed({
          read: function () {
            return self.questions()[this.index()];
          },
          write: function (question) {
            self.questions()[this.index()](question);
          },
          owner: self
        });
      };
      self.current = Current(0);
    };
    

    My browser is telling me that index is undefined in

    read: function () {
            return self.questions()[this.index()];
          },
    

    W-T-F?

    Edit: I think I get it. Each function must have its own this in scope. I told you it was a stupid question.


  • :belt_onion:

    @Captain said:

    Edit: I think I get it. Each function must have its own this in scope. I told you it was a stupid question.

    In order to reference the originator object from inside the internal closures, you need a local reference to the originator's this.



  • Perhaps...

    var ViewModel = function (data) {
      var self = this;
    
      ko.mapping.fromJS(data, {}, self);
    
      var Current = function (idx) {
        var that = this;
        this.index = ko.observable(idx);
        this.number = ko.computed (function () { return this.index + 1 });
        this.question = ko.computed({
          read: function () {
            return self.questions()[that.index()];
          },
          write: function (question) {
            self.questions()[that.index()](question);
          },
          owner: self
        });
      };
      self.current = Current(0);
    };
    


  • JavaScript, the client-side PHP WTF.



  • (expletive)

        var cliList = clientListProperties.ClientList;
    
        clientListProperties.ClientArray.length = 0;
    
        cliList.length = 0;
        clientArrayMaster.length = 0;
    


  • @chubertdev said:

    var cliList = clientListProperties.ClientList;

    clientListProperties.ClientArray.length = 0;
    
    cliList.length = 0;</blockquote>
    

    Why do you have a client list andcontaining a client array?



  • @ben_lubar said:

    Why do you have a client list andcontaining a client array?

    I don't, the co-worker that I'm going to smack around with a trout for a bit does.



  • @chubertdev said:

    cow-orker

    FTFY. If you're going to hyphenate it, at least hyphenate it correctly.


  • ♿ (Parody)

    TypeScript! It like going from explosive diarrhea to a pile of feces.



  • @cartman82 said:

    var that = this;

    That would work.



  • @darkmatter said:

    reference the originator object from inside the internal closures

    Victimized by this simple (of course...yea...makes sense) thing once before...In google maps development.

    Very nice explanation BTW.



  • And if we are all getting smarter...Might as well reference the Mozilla closures explanation page with some examples and approaches


  • 🚽 Regular

    Haven't used Knockout, only read about it, but try this:

    var ViewModel = function (data) {
      var self = this;
    
      ko.mapping.fromJS(data, {}, self);
    
      var Current = function (idx) {
        this.index = ko.observable(idx);
        this.number = ko.computed (function () { return this.index() + 1 }, this);
        this.question = ko.computed({
          read: function () {
            return self.questions()[that.index()];
          },
          write: function (question) {
            self.questions()[that.index()](question);
          },
          owner: this
        });
      };
      self.current = Current(0);
    };
    

    Note that:

    a) ko.observable and ko.computed return functions, so references to properties should be function calls;

    b) the owner Current object is passed to ko.computed() either as second argument (in the case of this.number) or as the "owner" attribute (in the case of this.question)

    In any case, "self" and "that" are terrible names and you should use something like "thisModel" and "thisCurrent".


  • :belt_onion:

    @Zecc said:

    "self" and "that" are terrible names

    "self" is a bit of a lie, "that" isn't too bad. "owner" probably makes the most sense. Or "objectInstanceXs_this" to be overly verbose ;)?


  • I survived the hour long Uno hand

    I usually see "currThis" as in "The current context's 'this' if we ignore the fact that we've entered a closure". But then, this is from the same people who insist that "x" is the best variable name for aliasing foo.bar.baz.someotherbar.foo.bar[i].bat inside a loop because "x marks the spot"



  • @Zecc said:

    In any case, "self" and "that" are terrible names and you should use something like "thisModel" and "thisCurrent".

    In my own code, I'm always using thisTheNameOfTheConstructor. If I have to use this at all (IMO it's best to avoid it altogether).


  • BINNED

    @chubertdev said:

    JavaScript, the client-side PHP WTF.

    We have that. We have that in stereo baby!

    http://phpjs.org/about/



  • x or i or j or all three in a nice obfuscated clever function usually a placeholder var and a loop within a loop.

    I try to be verbose on such things. Especially if things are nested and confusing to begin with.

    Filed under: I preach but I have done it too.


  • BINNED

    So yeah, I have a stupid question. FF started screaming at me for having a synchronous request in my main loop, and that I shouldn't do that. I agree FF, I agree.

    But how in the heck do I force a function into another thread in JS?


  • I survived the hour long Uno hand

    i and j and sometimes k are for storing the loop counter. "x" is for referring to a deep object without having to repeat the lookup every time you want to access it. For whatever reason I'm fine with i but not okay with x.


  • BINNED

    @Yamikuronue said:

    For whatever reason I'm fine with i but not okay with x.

    It's your indispensable incremental iterator.

    If anything, it needs more is. Maybe a regular one followed by the Turkish one, followed by the Ukrainian one?


    Filed under: Too lazy to look up unicode values



  • What does the code look like?


  • BINNED

    It's just jQuery's $.ajax with asyc: false. It's getting templates and required data to render them so I can't really do much before they are fetched (other than doing some stupid loop or something until variables populate).

    The pattern is pretty much:

    function getStuff(param, ... )
    {
        var stuff = null;
    
        $.ajax(
        {
            type: 'get',
            async: false,
            dataType: 'json',
            url: 'getStuff.php',
            data: {someparam: value, ...},
            success: function(data, textStatus, jqXHR)
            {
                // Do stuff to it if needed
                stuff = data;
            },
            error: function(jqXHR, textStatus, errorThrown)
            {
                // Error handling gubbins
            }
        });
    
        return stuff;
    }
    

    Only one function is always called on "reload", templates get cached when possible, but it's still annoying.



  • @Yamikuronue said:

    the same people who insist that "x" is the best variable name ... because "x marks the spot"

    Please tell me that they were making a joke or that you immediately conducted some workplace violence upon them (and preferably some other violence on family members there of).



  • Don't understand the question.

    If you want something to happen async, pretty much the only solutions (outside of node.js) are setInterval and setTimeout. Not sure how this fits with your problem.


  • BINNED

    I have synchronous requests running. Which is fine, I'm fetching stuff I need to render the page, no point in async, so I have the obligatory spinner while it loads, and that's fine.

    But FF complains about synchronous requests being run "in main thread". And if I incur a large data load, it does indeed seem to cause FF to stutter while request waits for completion.

    I want to know if I can spin it off in a different thread so it:

    1. Stops FF from complaining
    2. Stops FF choking on larger requests

    Now, how to force a JS engine to dispatch a function to a different thread, I have no idea. I'm pretty sure they can do that, can't they?



  • Sorry, I wrote that before I saw your code.

    Not gonna preach about using deprecated WTF-y patterns.

    The only thing that comes to mind is:

    setTimeout(function () {
       $.ajax( {
          async: false,
          /*...*/
        });
    }, 1);
    

    That will defer the execution into the next run cycle. By then, the browser might finish whatever it was doing in DOM and let you run your wait cycle in peace. Other than that, there's no way to tell the browser to run something in a different thread as javascript is, I believe, single-threaded.


  • BINNED

    @cartman82 said:

    Not gonna preach about using deprecated WTF-y patterns.

    Don't worry, known and in the process of cleaning all that shit up, ASAP.

    Granted, I am the source of this, but I poked around jQuery looong time ago (1.4?), then left it be, and then had to take it up again as this project was starting up. So I made more than one error since I was still basically learning both jQuery and Javascript proper.

    I pretty much have it all working now, and since it's feature freeze right now I'm slowly going through all the code, cleaning it up and fixing my fuckups as I go.

    @cartman82 said:

    Other than that, there's no way to tell the browser to run something in a different thread as javascript is, I believe, single-threaded.

    Wait, just thought of something. A bit of googling suggest that you can do threading in FF's addons. I'll try disabling them tomorrow and see what happens. I have this nagging suspicion it might be Firebug doing something wonky.



  • It's not Firebug. It's intended behavior.

    It looks like you have to use a Worker, whatever that is. Looks like it's a monad for running synchronous calls in order, in their own thread. (But I haven't read more than the page I linked)



  • @chubertdev said:

    I don't, the co-worker that I'm going to smack around with a trout for a bit does.

    Is that going to hurt? Also if you are in US of A, will he not sue you to the bone?


  • BINNED

    @Captain said:

    It looks like you have to use a Worker, whatever that is. Looks like it's a monad for running synchronous calls in order, in their own thread. (But I haven't read more than the page I linked)

    Ok, now that looks like a standard multithreading deal. The question is, how's the support?

    Well... surprisingly good in fact. I think I can use it then! IE10 should be the minimum for our app anyway and I'm not worried about other browsers that much since they are mostly always updated.

    Thanks for the link.



  • It's a thing from IRC @Nagesh. Look it up, I'm sure you can find things explaining it.



  • /trout @Nagesh



  • @Yamikuronue said:

    currThis

    this
    this2
    currThis
    currThis_real
    this_donotuse
    this_20140517
    


  • @Maciejasjmj said:

    this
    this2
    currThis
    currThis_real
    this_donotuse
    this_20140517

    curThis
    currrThis
    THIS


  • I survived the hour long Uno hand

    @ben_lubar said:

    curThis

    Not to be confused with thisCur, who inherits the Dog prototype



  • I feel dirty writing this, even though I have a technical reason:

    <!--​ ko if: state.notReviewing -->
    

    Unfortuantely, Knockout's if binding only refreshes when consumes observables. And while state.reviewing is an observable, logical combinations of observables are not observable. So instead of doing:

    <!--​ ko if: !state.reviewing() -->
    

    or

    <!--​ ko if: state.writing() || state.paused() -->
    

    I have to roll the logic into a function and make it observable.


  • Discourse touched me in a no-no place

    Necroing this thread so I can say that the last post is entertaining; it puts me in mind of what I assume someone who speaks only Mandarin feels like when hearing Cantonese.



  • So Knockout is a pretty neat Javascript templating system that consumes what it calls "observables". These are functions that return data for the system to render (and you can update the values and their dependencies by setting the observable). I complained because static bool values aren't observables" and JavaScript isn't rich enough to make them observable. So I have to wrap logic into a function called notReviewing.


  • Discourse touched me in a no-no place

    @Captain said:

    So Knockout is a pretty neat Javascript templating system that consumes what it calls "observables".

    https://www.youtube.com/watch?v=acI12jO0HSQ


Log in to reply