Peck3277
Peck3277

Reputation: 1423

Passing parameters to a callback

I'm trying to figure out how to pass my callback additional parameters. So far I have the following code.

$("#refine_mp_type").change(function(){
    var mp_type = $(this).val();
    var country_id = $('#refine_country').val();
    var dropdown = $('#refine_grade').find('select');
    getMPTypeGrades(country_id, mp_type, populateGradesDropdown);
});

function getMPTypeGrades(country_id, mp_type, callback){
    display_wait_dialog ("Please Wait", "Loading grades...");
    $.ajax(
    {
        //do ajax
    })
    .done(function(data){
        callback(data);
    })
    .fail(//do something)
    .always(//do something);
}

populateGradesDropdown(data){
    //populate the dropdown with the returned data
}

My thoughts so far on how to achieve this are:

  1. I could set the dropdown variable to global scope and access it that way(Will pollute global scope).
  2. I could pass the dropdown element to getMPTypeGrades function and then pass it to the callback function. (I want to keep getMPTypeGrades as generic as possible. I don't know if I'll always be passing a callback that accepts a JQuery element.)

What is the best method for passing the JQuery element and the Ajax response as parameters for my callback?

Upvotes: 2

Views: 147

Answers (4)

springrolls
springrolls

Reputation: 1331

Try to use jQuery Deferred and jQuery when. Basically you create a deferred object with a pending state and return it to the caller. jQuery when executes the callback function only when the deferred object has been resolved or rejected. When your ajax request is finished, .resolve or .reject will be called. This will trigger the callback method in the caller.

I haven't tested this code, but it should work more or less.

$("#refine_mp_type").change(function() {
    var mp_type = $(this).val();
    var country_id = $('#refine_country').val();
    var dropdown = $('#refine_grade').find('select');
    $.when(getMPTypeGrades(country_id, mp_type)).then(function(result) {
       //populate dropdown
    });
});

function getMPTypeGrades(country_id, mp_type) {
    var def = $.Deferred();   
    display_wait_dialog ("Please Wait", "Loading grades...");
    $.ajax(
    {
        //do ajax
    })
    .done(function(data) {
        def.resolve(data);
    })
    .fail(function(err) {
        def.reject(err);
    })
    .always(function() {
        hide_wait_dialog();
    });
    return def;
}

Upvotes: 2

Joe Enos
Joe Enos

Reputation: 40393

You can reference the original dropdown variable in the callback function body:

var dropdown = /*whatever*/;
getMPTypeGrades(country_id, mp_type, function(data) {
    populateGradesDropdown(data, dropdown);
});

$.ajax({
}).done(function(data){
    callback(data);
})

function populateGradesDropdown(data, dropdown){
    alert("data=" + data);
    alert("dropdown=" + dropdown);
}

Upvotes: 0

paddybasi
paddybasi

Reputation: 82

Rather than passing a callback (which can create a 'pyramid' code of callbacks), you should just return the deferred ajax object in getMPTypeGrades. You can then just use the standard .done()/.then() functions within the change handler:

$("#refine_mp_type").change(function(){
    var mp_type = $(this).val();
    var country_id = $('#refine_country').val();
    var dropdown = $('#refine_grade').find('select');
    getMPTypeGrades(country_id, mp_type).then(populateGradesDropdown);
});

function getMPTypeGrades(country_id, mp_type){
    display_wait_dialog ("Please Wait", "Loading grades...");
    return $.ajax(
    {
        //do ajax
    })
    .fail(//do something)
    .always(//do something);
}

populateGradesDropdown(data){
    //populate the dropdown with the returned data
}

Upvotes: 0

Maxx
Maxx

Reputation: 1748

You can bind dropdown to callback function:

$("#refine_mp_type").change(function(){
    var mp_type = $(this).val();
    var country_id = $('#refine_country').val();
    var dropdown = $('#refine_grade').find('select');
    getMPTypeGrades(country_id, mp_type, populateGradesDropdown.bind(null, dropdown));
});

Then

populateGradesDropdown(dropdown, data){
    //populate the dropdown with the returned data
}

Upvotes: 2

Related Questions