-1

I have encountered the following problem:

    function Conclude (thing){
        this.quant = thing.find('#quantity_material').val();
        this.thing = thing;
        this.material =[];
        this.finish = [];
        this.make = function (){
            var i=0;
            this.thing.each(function(){
                this.material [i]= $(this).find('#material_val').val();
                //Conclude.material doesn't work either
                i++;
            });
        }
    }

I want to assign conclude.material the values of an input out of several tables so that conclude.material[1] is value of #material_val from the first table and so on. The problem is that when I write this, it doesn't refer to function conclude inside .each().

What am I doing wrong?

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
funny
  • 83
  • 1
  • 14

2 Answers2

4

Every function statement in JS gets its own this variable. You have two functions, one is called Conclude and the other one is an anonymous function (there are two anonymous functions really, but the thing I'm about to explain applies still).

Your error is here:

this.thing.each(function(){ -> the this does not "belong" to Conclude function. It belongs to the anonymous function.

Easiest way out, at least for you, is to change the scope of anonymous function so that this in anonymous function refers to the outer, Conclude function. Seeing you are using jQuery already, use jQuery.proxy method to do so.

Code:

function Conclude (thing){
    this.quant = thing.find('#quantity_material').val();
    this.thing = thing;
    this.material =[];
    this.finish = [];   

    this.make = $.proxy(function (){
        this.thing.each($.proxy(function(index, item){
            this.material[index] = $(item).find('#material_val').val();             

        }, this));
    }, this);
}
N.B.
  • 13,688
  • 3
  • 45
  • 55
  • @maze-le - well, that's one of the language rules, and by them - we must abide. I agree it's counter-intuitive at first, but with experience comes the muscle memory as well :) – N.B. May 21 '15 at 15:01
  • 1
    the `$(this).find('#material_val')` in the each loop here will refer to the Conclude object, so you will need to alter the function args line in the example to `this.thing.each($.proxy(function(index, item) {` and then `$(this)` to `$(item)`. (note: also by adding the index arg you can remove the `var i = 0` and `i++` and use the `index` arg instead of `i` – MugiwaraUK May 21 '15 at 15:07
4

Try this one, pretty simple.

     function Conclude (thing){
       var _this = this;
       this.quant = thing.find('#quantity_material').val();
       this.thing = thing;
       this.material =[];
       this.finish = [];
       this.make = function (){
        var i=0;
        this.thing.each(function(){
            _this.material [i]= $(this).find('#material_val').val();

            i++;
        });
    }
}
arnabkaycee
  • 1,634
  • 13
  • 26
  • You can make this better by altering `this.thing.each(function(){` to `this.thing.each(function(index){`. use the `index` instead of `i` and remove the variable and increment – MugiwaraUK May 21 '15 at 15:11