Travis Kean
Travis Kean

Reputation: 51

JavaScript Callbacks for multiple functions

I'm currently trying to take results I have from an api controller, and have that json data added to a table in my razor view. I had some issues with the array I was using to fill the table not being filled with data before the table was created. I've tried to absolve that problem with callbacks, but I'm still inexperienced, and having trouble understanding from tutorials.

Here are the javascript function I have (and in order they must go 1. the $.getJson 2. the fillArray function 3. the AddToTable function) :

  $(document).ready(function ()
{


    $.getJSON('api/GetRestaurants/detroit').done(fillArray(data))


});

function fillArray(data, callback)
{
    var restaurant =
     {
         Name: "",
         PhoneNumber: "",
         PlaceID: "",
         Rating: 0,
         Website: ""
     };

    var dataArray = new Array();

    for (var k = 0; k < data.length; k++) {
        restaurant.Name = data[k].Name;
        restaurant.PhoneNumber = data[k].PhoneNumber;
        restaurant.PlaceID = data[k].PlaceID;
        restaurant.Rating = data[k].Rating;

        dataArray.push(restaurant);

    }
    callback(AddToTable(dataArray));
}
function AddToTable(dataArray) {
    document.getElementById("tbl").innerHTML =
        '<tr>' +
        '<th>Restaurant Name</th>' +
        '<th>Restaurant PlaceID</th>'
    for (var i = 0; i < dataArray.length; i++) {
        +'<tr>'
        + '<td>' + dataArray[i].Name + '</td>'
        + '<td>' + dataArray[i].PlaceID + '</td>'


        + '</tr>';
    }
}

The data is there, and the api controller call is successful, I just need to data to fill the array before the table uses that array.

I appreciate any help and/or comments, thanks guys :].

Upvotes: 0

Views: 142

Answers (2)

John S
John S

Reputation: 21482

When you do the following:

 $.getJSON('api/GetRestaurants/detroit').done(fillArray(data))

You are calling the fillArray() function and passing its result to the .done() function. Instead, you should be passing the fillArray function to the .done() function.

 $.getJSON('api/GetRestaurants/detroit').done(fillArray)

I prefer to use an anonymous function when setting a callback. Then the named functions can have the signatures that make sense for them. The anonymous callback function, of course, has the signature required for it. The named functions are then called inside the anonymous callback function.

$(document).ready(function() {
    $.getJSON('api/GetRestaurants/detroit').done(function(data) {
        var restaurants = createRestaurantArray(data);
        addRestaurantsToTable(restaurants);
    });
});

function createRestaurantArray(apiData) {
    var restaurants = []; // Preferred syntax over "new Array()"
    for (var i = 0; i < apiData.length; i++) {
        restaurants.push({
            Name: apiData[i].Name,
            PhoneNumber: apiData[i].PhoneNumber,
            PlaceID: apiData[i].PlaceID,
            Rating: apiData[i].Rating,
            Website: ""
     });
    return restaurants;
}

function addRestaurantsToTable(restaurants) {
    var html = '<tr>'
        + '<th>Restaurant Name</th>'
        + '<th>Restaurant PlaceID</th>'
        + '</tr>';
    for (var i = 0; i < restaurants.length; i++) {
        html += '<tr>'
            + '<td>' + restaurants[i].Name + '</td>'
            + '<td>' + restaurants[i].PlaceID + '</td>'
            + '</tr>';
    }
    $('#tbl').html(html);
}

Also, your fillArray() function was creating a single restaraunt object and pushing that same object to the array for each iteration of the for-loop. That means the resulting array would contain the same object over and over, and that object would have the property values set by the last iteration of the loop.

Upvotes: 1

Zak
Zak

Reputation: 2058

All the commands in your fillArray function appear to be synchronous (i.e. the code does not move on until they are completed) so as long as this is called before your function to add the data you should be okay.

Upvotes: 0

Related Questions