Pass additional parameters to jQuery each() callback

70,781

Solution 1

You should be able to create a reference to your survey before you iterate over the questions.

function Survey() {
    this.questions = new Array();
    var survey = this;
    $('.question').each(function(i) {
        survey.questions.push(new Question(this));
    });
}

function Question(element) {
    this.element = $(element);
}

var survey = new Survey();

$.each(survey.questions, function() {
    $("ul").append("<li>" + this.element.text() + "</li>");
});

Working example on jsfiddle

Solution 2

Though this may not be relevant answer , But since the question is how to pass parameter to jQuery each function .

First Approach : Using Partial Function - more on this and from closure library

jsfiddle:

var param = 'extra-param';   

var partial = function(fn, var_args) {
  var args = Array.prototype.slice.call(arguments, 1);
  return function() {
    // Clone the array (with slice()) and append additional arguments
    // to the existing arguments.
    var newArgs = args.slice();
    newArgs.push.apply(newArgs, arguments);
    return fn.apply(this, newArgs);
  };
};

$(['joe','james','rick','kirk']).each(partial (function (index,value) {
    alert(arguments.length);
    alert(arguments[0]);
 },param));

Second Approach is

$.each function can take either 2 parameters Index and Element(which can also be referred as this) OR if you do not need Index then you can pass Array as argument to $.each and element can referred as this

CAUTION : args is for internal use only - by jQuery

// Execute a callback for every element in the matched set.
// (You can seed the arguments with an array of args, but this is
// only used internally.)
each: function( callback, args ) {
    return jQuery.each( this, callback, args );
},

Which will call each: function( obj, callback, args )

then call callback.apply( obj[ i ], args ); if you pass array as argument otherwise callback.call( obj[ i ], i, obj[ i ] );

please note the difference of apply and call

Sample code : http://jsfiddle.net/dekajp/yA89R/1/

var param = 'rick';
$(['joe','james','rick','kirk']).each(function (arg1 , arg2 ,arg3) {
    //alert('[this: '+this +'] [arg1: '+ arg1 +'] [arg2:'+arg2+'] [param:'+param+']');
},['hello 1','hello 2','hello 3']);

For Reference jQuery Each Code version 1.9

// args is for internal usage only
    each: function( obj, callback, args ) {
        var value,
            i = 0,
            length = obj.length,
            isArray = isArraylike( obj );

        if ( args ) {
            if ( isArray ) {
                for ( ; i < length; i++ ) {
                    value = callback.apply( obj[ i ], args );

                    if ( value === false ) {
                        break;
                    }
                }
            } else {
                for ( i in obj ) {
                    value = callback.apply( obj[ i ], args );

                    if ( value === false ) {
                        break;
                    }
                }
            }

        // A special, fast, case for the most common use of each
        } else {
            if ( isArray ) {
                for ( ; i < length; i++ ) {
                    value = callback.call( obj[ i ], i, obj[ i ] );

                    if ( value === false ) {
                        break;
                    }
                }
            } else {
                for ( i in obj ) {
                    value = callback.call( obj[ i ], i, obj[ i ] );

                    if ( value === false ) {
                        break;
                    }
                }
            }
        }

        return obj;
    },

Solution 3

I encountered a similar issue. to pass param to an each function:

var param1 = "one";
var param2 = "two";

var params = [ param1, param2 ];


$( '#myTable > tbody  > tr' ).each(function( index ) {

     var param1back = params[0];
     var param2back = params[1];

},params);

Solution 4

//Create extra data
var dataArray = ["A", "B", "C"];

//Send default arguments from jQuery's each (index and item) along
//with our new data argument to a named function handler.
$("#myList").children().each(function(jqIndex, jqItem)
                            {
                              listItemsHandler(jqIndex, jqItem, dataArray[jqIndex]);
                            });    

//Named function handler accepting 3 arguments.
function listItemsHandler(index, item, data)
{
    console.log(index + " " + item + " " + data);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ol id = "myList">
  <li>First</li>
  <li>Second</li>
  <li>Third</li> 
</ol>

Share:
70,781
MarioVW
Author by

MarioVW

Updated on May 21, 2020

Comments

  • MarioVW
    MarioVW almost 4 years

    I'm working on an app that will present surveys to the user. The markup looks something like this:

    <body>
        <div class="question" id="q1">
            Question 1
        </div>
        <div class="question" id="q2">
            Question 2
        </div>
        <!-- etc -->
    </body>
    

    I want to construct the JavaScript objects from the DOM using jQuery, so in the Survey constructor I'm traversing the jQuery set using the each() method. The problem is that within the callback function I'm unable to get a reference to the Survey object in order to append each Question object to the Survey.questions array. How can get a reference to the Survey object? Is there a way to pass an additional parameter (e.g. a reference to the Survey object) to the callback function?

    function Survey() {
        this.questions = new Array;
        $('.question').each(function(i) { (/* Survey object */).questions.push(new Question(this)); });
    }
    
    function Question(element) {
        this.element = $(element);
    }
    
  • axlotl
    axlotl over 8 years
    This answer is a far more thoroughgoing discussion of the issues raised in the question.
  • Oleksii Zymovets
    Oleksii Zymovets over 7 years
    Worked for me. Just wanted to stress, that params should always be of type array. Not working if params is of any other type.
  • 0leg
    0leg over 6 years
    This should be the accepted answer, since it is actually how jQuery parameters with methods like each was designed. Other answers are just over complicate things.
  • Paul Allsopp
    Paul Allsopp almost 6 years
    This should not be the accepted answer. We can add variables to the global scope all we want, but that just pollutes the global space...that is not good coding! I think what the OP is asking is how to pass an instance variable into .each(), which will not be defined at the global level and so needs to be passed in.
  • some_groceries
    some_groceries over 4 years
    @OleksiiZymovets works for me even if params is a string