2

I need the function addColumns(which has an async call in it) to be executed as many times as limited in the for loop ,and when the for loop is done then i want to call the function InitData. The problem is that when it comes to the addColumns function,it calls the function but it wont go in to success,and therefore resolve is empty. Would appreciate any help.

        var index = 0;
        for (var i = 0; i < ListJoin.viewResponse.length; i++) {
            if (ListJoin.viewResponse[i].Navn == viewName) {
                ListJoin.json = JSON.parse(ListJoin.viewResponse[i].Json)
                //var keys=Object.keys(ListJoin.json).length;

                for (var list in ListJoin.json) {
                    $.when(addColumns(list, ListJoin.json[list], index, '#viewTable')).done(function () { index++ });
                    }

             }

               InitData($('#viewTable'));

        }



function addColumns(list, cols, listNr, tableInstance) {

var defer = $.Deferred();
var url = ListJoin.appweburl + "/_api/SP.AppContextSite(@target)/Web/Lists/getbytitle('" + list + "')/items?$select=" + cols + "&$top=5000&@target='" + ListJoin.hostweburl + "'";

ListJoin.executor.executeAsync({
    url: url,
    method: "GET",
    headers: {
        "Accept": "application/json; odata=verbose"
    },
    success: function (data) {
        var jsonObject = JSON.parse(data.body);
        var response = jsonObject.d.results;
        console.log(jsonObject);
        for (var y = 0; y < (response.length) ; y++) {

            var blabla = [];
            if (listNr < 1) {

                for (var i = 0, len = cols.length; i < len; i++) {

                    //var key = str[i];
                    //ListJoin.tmp[y][str[i]] = (ListJoin.SiteLists[selectedList].Items.results[y][str[i]]);

                    blabla[i] = (response[y][cols[i]]);

                };
                if (tableInstance == '#viewTable') {
                    tmp.push(blabla)
                }
                else {
                    ListJoin.tmpCreateView.push(blabla);
                }
                //newArray.push(tmp);
            }

            else {

                if (tableInstance == '#viewTable') {
                    for (var i = 0, len = tmp[0].length; i < len; i++) {

                        if (i < cols.length) {
                            blabla[i] = (response[y][cols[i]]);
                        } else {
                            blabla[i] = "";
                        }

                    };

                    tmp.push(blabla);
                }
                else {
                    for (var i = 0, len = ListJoin.tmpCreateView[0].length; i < len; i++) {

                        //var key = str[i];
                        //ListJoin.tmp[y][str[i]] = (ListJoin.SiteLists[selectedList].Items.results[y][str[i]]);
                        if (i < cols.length) {
                            blabla[i] = (response[y][cols[i]]);
                        } else {
                            blabla[i] = "";
                        }

                    };

                    ListJoin.tmpCreateView.push(blabla);
                }
            }


        };

        if (listNr < 1) {
            if (header.length == 0) {
                header = cols;
                $("#headerInput").children().remove();
                for (var item in header) {

                    $("" + tableInstance + " thead tr").append("<th>" + header[item] + "</th><button>test</button>");
                    if (tableInstance == '#example') {

                        $('#headerInput').append('<div class="form-group"><label>Column title</label><div class="fld" ><input type="text"  class="showHideColumns input-xs" value="' + header[item] + '""></input></div></div>');
                    }
                };

            }

        };
        //if (tableInstance == '#viewTable') {
        //    InitData($(tableInstance));
        //}
        $('.checkboxes').multiselect('deselectAll', true);
        $('.checkboxes').multiselect('updateButtonText');
        str = [];
        defer.resolve();
    },

    error: function (data) {
        console.log("Wait Wait Wait");
        defer.reject();
    }

});
return defer;


};
2

async:false

makes it work, but it ofcourse has the side-effect that all calls are in sequence (thus take longer)

Since it looks like your async calls are not dependent on each other:

  • you can issue them all at once (promise)

  • Stick all Promises in an Array

  • And wait for the whole Array of Promises to finish

see: https://stackoverflow.com/questions/4878887/how-do-you-work-with-an-array-of-jquery-deferreds

0

You can put async:false after method:"Get".

method:"Get",
async:false,
6
  • Thanx for answering so quick.Unfortunatelly that didnt solved my problem.When i debugg it , i see it going into the addColumns function,but not going to success,it directly goes to resolve. – S.M.B.D Jun 27 '16 at 8:47
  • If it is not going to Success, it should go to error block.. Did you put debugger inside Success and Error block and checked? – Ankit Kumar Jun 27 '16 at 9:00
  • Can you remove ListJoin.executor.executeAsync.... keep the URL ASYNC and METHOD and success without ListJoin.executor.executeAsync( – Ankit Kumar Jun 27 '16 at 9:07
  • I dont really understand, I need executor.executeAsync because i am making cross domain calls , from the appweb to the hostweb. Are you sayng i should make a normal ajax call? – S.M.B.D Jun 27 '16 at 10:18
  • yes..i would do that first to check if normal ajax call is running fine – Ankit Kumar Jun 27 '16 at 11:41
0

Can you calculate, before starting making the request, how many request will be made? For example by counting the items in your viewresponse. Is you know how many request are going to be made you can check whether you have performed the last query in your deferred.done in main loop (comparing it to the index) and call InitData after the last call. If you can't determine the number of calls to be made before hand, you could introduce a new counter that get's incremented every time the a call is made (in addColumns). This counter can then also be used in deferred.done to compare to the index.

0

I found a way out of this even it is not really what i wanted.What i did is i put InitData() into

$.when(addColumns(list, ListJoin.json[list], index, '#viewTable')).done(function () { index++ });

and now it looks like this:

$.when(addColumns(list, ListJoin.json[list], index, '#viewTable')).done(function () {InitData($('#viewTable')); index++ }); It is not the best solution because the DataTable is initialized everytime a restcall is done ,and some new data are added to the already shown Table.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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