1

How to ensure that "Test Data" text get displayed in the console only after books details are loaded in vm.books, basically want to perform synchronous ajax call.

Below mention code is not working as expected. any suggestion how to achieve this expected functionality.

$(document).ready(function() {
  var vm = new obj.Books();
  vm.loadBooks();
  console.log("Test Data");
});

var obj = obj || {};
obj.Books = function() {
  var self = this;

  self.books = [];

  self.loadBooks = function() {
    $.ajax({
        url: "somewebapiurl",
        dataType: 'jsonp',
        async: false
      })
      .done(function(data) {
        $.each(data, function(idx, item) {
          self.books.push(item);

        });
      })
      .fail(function(xhr, status, error) {
        alert(status);
      });
  };
};
Seth
  • 10,198
  • 10
  • 45
  • 68
sameer
  • 1,635
  • 3
  • 23
  • 35
  • 2
    Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. http://api.jquery.com/jquery.ajax/ – jcubic Jul 01 '16 at 11:18
  • http://stackoverflow.com/questions/5943630/basic-example-of-using-ajax-with-jsonp – mplungjan Jul 01 '16 at 11:20
  • any suggestion how to achieve the expected functionality. – sameer Jul 01 '16 at 11:39
  • Definitely don't block the thread. Bad perf and bad UX... and bad JavaScript. Use callbacks or the better option is to use jQuery's ajax deferred object. – Seth Jul 01 '16 at 11:47
  • Do you want to make the request synchronous, or do you want to solve your problem? Because a synchronous call is the wrong solution to your problem. – JJJ Jul 01 '16 at 11:50
  • @juhana just want to find the solution to this requirement, ideally we can pass the success and error callback for loadBooks function. – sameer Jul 01 '16 at 13:41

2 Answers2

1

How to ensure that "Test Data" text get displayed in the console only after books details are loaded in vm.books, basically want to perform synchronous ajax call.

Just leverage the jQuery Deferred Object's .done function.

self.loadBooks = function() {
  $.ajax({
    url: "somewebapiurl",
    dataType: 'jsonp',
  })
  .done(function(data) {
    $.each(data, function(idx, item) {
      self.books.push(item);

    });
    //do what you want or call the function you want
    console.log("Test Data");
  })
  .fail(function(xhr, status, error) {
    alert(status);
  });
};
Seth
  • 10,198
  • 10
  • 45
  • 68
Mikel
  • 361
  • 1
  • 9
  • Many thanks for the edit, i have to improve my answers – Mikel Jul 01 '16 at 11:54
  • We cannot modify the self.loadBooks function, responsibility of the loadBooks is to load the self.books array. We have to just invoke loadBooks and expect books array to have values in it and then display the text and work with books array i.e we can display the list of books in the array. – sameer Jul 01 '16 at 13:34
  • @sameer you can return ajax promise from loadBooks and then use `vm.loadBooks().done(function() { console.log("Test Data"); });` – jcubic Jul 01 '16 at 14:47
0

@jcubic was right , jsonp does not support synchronous call with async=false.

Therefore,

  • Enabled the CORS in Service side (i.e. somewebapiurl)
  • Set origin details (i.e. origins="http://localhost:19410" headers="*" methods="get" )
  • Removed the datatype='jsonp'
  • Retained async=false

Now it is working as expected.

sameer
  • 1,635
  • 3
  • 23
  • 35