2

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?

4 Answers 4

2

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
}
Sign up to request clarification or add additional context in comments.

2 Comments

when you set the dropdown as the first argument of the bind, you can access it in populateGradesDropdown with the this keyword.
Yep, but populateGradesDropdown might be universal function and may use its context. But you are right.
2

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;
}

1 Comment

linking is good, but give a little explanation about the deffered.
0

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
}

Comments

0

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);
}

Comments

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.