0

I'm making a project that includes web api and JQuery. One of the html pages has to show store and the manager's name of the store.

Every store has:
ID,
StoreName,
ManagerID.

Every Manager has:
ID,
ManagerName.

The store isn't hold the manager name directly.

The code looks like this:

// There is a html code with <table id='table'>...</table> before the script.
var storesUri = 'api/stores' //The stores uri
$(document).ready(function() {
    $.getJSON(storesUri)
        .done(function(data) {
            $.each(data, function(key, item) {
                $('#table).append(
                    '<tr>' +
                    '<td>' + item.ID + '</td>' +
                    '<td>' + item.storeName + '</td>' +
                    '<td>' + findManagerNameByID(item.ManagerID) + '</td>' + //get the manager name by the manager id
                    '</tr>');
            });
        });
});

var managersUri = 'api/managers' //The managers uri
function findManagerNameByID(id) {
    var res = 'N/A';
    $getJSON(managersUri + '/' + id)
        .done(function(data) {
            res = data.ManagerName; //puts in res the fit manager name
        })
        .fail(function(jqXHR, testStatus, err) {
            res = 'None';
        });
    //alert('1');
    return res;
}    

After this code the table has to include for each store the store ID, store name and the store manager name. Instead of that the table includes for each store the store ID, the store name and 'N/A' (the default value of res).

The thing is that, if I add to the code "alert('1');" right before the return (You can see it in commant) the table will be okay and it'll include for each store the store ID, store name and the store manager as I wanted.

I think this is happen becase the 'return res;' line somehow happens before the 'res=data.ManagerName;' line (I think that because when the code has the little delay of the alert before the return, everything is okay). How can I make the table be filled correctly without the alert? thanks.

naveen
  • 53,448
  • 46
  • 161
  • 251
ShaqD
  • 63
  • 1
  • 10
  • 1
    A much more efficient approach will be to change the `SELECT` in your API to something like `SELECT S.ID, S.StoreName, M.ManagerName FROM Stores S, Managers M WHERE S.ManagerID = M.ID` – naveen Jun 15 '16 at 00:32

3 Answers3

1

The problem here is that the request (getJSON) runs asynchronously, and so the code initiates the request and registers the callback handlers for each result, and then returns the current value of res (which is 'N/A').

You can force it to run synchronously, but maybe not using that convenience function. I don't remember the exact syntax for it, but the jQuery docs are pretty good. If getJSON doesn't have a 'sync' mode then you could always go back to the ajax function, that is used by getJSON internally.

ToVine
  • 560
  • 5
  • 16
1

The function getJSON is asynchronous so I suggest you to change your function from:

function findManagerNameByID(id){

to:

function findManagerNameByID(id, callback){

So, when the getJSON returns a value (done) you can use it in your callback function like in:

var managersUri='api/managers' //The managers uri
function findManagerNameByID(id, callback){
  var res = 'N/A';
  $getJSON(managersUri+'/'+id)
  .done(function(data){
    // use the callback
    res=data.ManagerName;    //puts in res the fit manager name
    callback(res);
  })
  .fail(function(jqXHR, testStatus, err){
    res='None';
  });
}


// when you call your function pass the callback....
findManagerNameByID('thisId', function(res) {
  // use your res value right now
})
gaetanoM
  • 41,594
  • 6
  • 42
  • 61
0

Instead of putting the return in a var you can just return from done or fail. I think that "None" will be the same as "N/A" eliminating the need for the var. So that part of the code will look like

$getJSON(managersUri+'/'+id)
            .done(function(data){
                return data.ManagerName;    //puts in res the fit manager name
            })
            .fail(function(jqXHR, testStatus, err){
                return 'None';
            });
clurect
  • 359
  • 3
  • 12