1
\$\begingroup\$

I have a tree view with a list of cars and a webservice to get the details for each car.

On page load, there are no cars selected so the details footer is loaded with all cars.

$.ajax({
        type: 'POST',
        url: '@Url.Content("/GTracker/Cars/CarTreeDetails")',
        data: { "id": [] }, // not cars filter
        traditional: true,
        success: function (data) {
            $('#footer-details').html(data);
        }
    });

When the user select cars from the treeview, the details are then updated with only those cars.

This is the changed.jstree event:

    var ajaxDetails;

    $('#carTree').on('changed.jstree', function (e, data) {
        var i, j, p = [];

        // create the id[] array 
        for (i = 0, j = data.selected.length; i < j; i++) {
            node = data.instance.get_node(data.selected[i]);
            if (node.data.type != 'root') {
                p.push(parseInt(data.instance.get_node(data.selected[i]).id));
            }
        }

        // cancel previous request
        if ((ajaxDetails && ajaxDetails.readyState != 4)) {
            ajaxDetails.abort()
        }

        // get only selected cars info.
        ajaxDetails = $.ajax({
            type: 'POST',
            url: '@Url.Content("/GTracker/Cars/CarTreeDetails")',
            data: { "id": p },  //cars list
            traditional: true,
            success: function (data) {
                $('#footer-details').html(data);
            }
        });
    });

But I feel I'm repeating myself. How may I merge those two functions together?

  • one for the on_load.
  • the other for the js_tree change event.
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I think this is a good case for refactoring the ajax call out into its own method. I have given some suggested changes in the code below. My comments are inside /* ... */ comments.

/*
 * use more meaningful and specific name
var ajaxDetails;
*/
var carTreeXHR;

$('#carTree').on('changed.jstree', function (e, data) {
    /*
     * why initialize to i and j here?
     * use more meaningful name for selected ID's array
    var i, j, p = [];
    */
    var selectedIds = [];

    // create the id[] array
    /*
     * initialize i and j here.
     * simplify call to get node id from existing 'node' object
    for (i = 0, j = data.selected.length; i < j; i++) {
        node = data.instance.get_node(data.selected[i]);
        if (node.data.type != 'root') {
            p.push(parseInt(data.instance.get_node(data.selected[i]).id));
        }
    }
    */
    for (var i = 0, j = data.selected.length; i < j; i++) {
        var node = data.instance.get_node(data.selected[i]);
        if (node.data.type != 'root') {
            selectedIds.push(parseInt(node.id));
        }
    }
    /*
     * remove from this location and put inside  new function
    // cancel previous request
    if ((ajaxDetails && ajaxDetails.readyState != 4)) {
        ajaxDetails.abort()
    }
    */

    // get only selected cars info.
    /* call new function */
    updateCarTreeDetails(selectedIds);

   /*
   * remove to function
   ajaxDetails = $.ajax({
        type: 'POST',
        url: '@Url.Content("/GTracker/Cars/CarTreeDetails")',
        data: { "id": p },  //cars list
        traditional: true,
        success: function (data) {
            $('#footer-details').html(data);
        }
    });
    */
});

/* New function. Include in appropriate scope */
function updateCarTreeDetails(selectedIds) {
    // abort existing request if needed
    if ((carTreeXHR && carTreeXHR.readyState != 4)) {
        carTreeXHR.abort()
    }
    // execute new request
    // not shown - consider handling ajax failure case as well
    carTreeXHR = $.ajax({
        type: 'POST',
        url: '@Url.Content("/GTracker/Cars/CarTreeDetails")',
        data: { "id": selectedIds },  //cars list
        traditional: true,
        success: function (data) {
            $('#footer-details').html(data);
        }
    });
}

/* In your document.ready handler, you can call this function
 * just like you did inside the change handler */
updateCarTreeDetails([]);

One additional note - it seems odd to be executing a 'POST' method if a case where you are just reading data from the remote data source (i.e. you are not performing a create, update, or delete operation). If you have control over this API, you might consider implementing as GET.

\$\endgroup\$
6
  • \$\begingroup\$ What XHR stand for? This line var i, j, p = []; also make i, j as array? I tough was only p ... will fix that!!. Ok, I think I understand the rest. Look very good, will check later at home. Thanks \$\endgroup\$ Commented Jul 6, 2016 at 15:51
  • \$\begingroup\$ @JuanCarlosOropeza XHR is to indicate that the variable holds a jqXHR (XMLHttpRequest) object. That is the object type that is returned from a call to .ajax() and what you are inspecting when doing things like looking at the readyState of a request. I should also note that in the new function, you should consider handling cases where AJAX call fails. \$\endgroup\$
    – Mike Brant
    Commented Jul 6, 2016 at 15:58
  • \$\begingroup\$ @JuanCarlosOropeza Sorry I misread original line of code where i,j,p where initialized. i and j would not be arrays as you originally had shown. I would consider still moving variable initialization to where loop is instantiated as these variables are really on relevant to the loop and not one of the variables you are going to work with throughout the function. \$\endgroup\$
    – Mike Brant
    Commented Jul 6, 2016 at 16:05
  • \$\begingroup\$ Yes, I have the habit of declare the variable at the begining. Just to be clear can you add the suggested code as one EDIT for declare the variables in one additional code at the end? Because I declare I, J just before the loop. Unless you mean I remove it completly because are only use on the Loop? \$\endgroup\$ Commented Jul 6, 2016 at 16:24
  • \$\begingroup\$ Regarding the POST. Yes I have control over the API. I will revisit that, but last time when try to use GET didnt work. So I just copy a working example. But I have learn a lot since then, so I think can give it another try. \$\endgroup\$ Commented Jul 6, 2016 at 16:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.