0

This function fetches response and writes response to localStorage

function getSomething() {
    var d = $.Deferred();
    var payload = ...
    $.post(API, payload).done(function (data) {
        // addData is a wrapper for localStorage write
        addData(payload);
        d.resolve();
    }).fail(d.reject);
    return $.when(d).done(function () {
        console.log('API fetch OK');
    }).promise();
}

And then on document.ready the following executes

getSomething().done(function () {
    // getData is a wrapper for localStorage read
    var fs = $.grep(getData(), function (i) {
        return i.cid == getID();
    });               

    var fso = JSON.parse(fs[0].data);

    $('.button-list').each(function (i, v) {
        var buttonRow = '';
        for (i = 0 ; i < fso.length ; i++) {
            buttonRow += '<a id=' + getID() + '-' + fso[i].Content.Id + ' class=\'btn btn-default\'>' + fso[i].Form.Name + '</a>';
        }
        $(v).html(buttonRow);
    });

So the problem here is I'd like to add another function between the two which checks if something is already present in localStorage before calling getSomething(). This fails because getSomething is 'done' before localStorage is written to. After some fiddling around I found localStorage is available to read 200ms after getSomething is 'done'.

My question - is it possible to guarantee localStorage has been written to before getSomething enters 'done' state?

Thanks!

Ash G
  • 21
  • 5
  • first question why do you need localStorage, second question why do you need promises ? – madalinivascu Nov 16 '16 at 05:47
  • So (a) localStorage because there's more JS that will re-use that data got from AJAX call and (b) without a promise drawing elements fails. Line which defines **fs** fails as getData() is empty because the HTTP request hasn't finished yet. – Ash G Nov 16 '16 at 09:28
  • do all your logic in the success function of your ajax call – madalinivascu Nov 16 '16 at 09:52
  • @madalinivascu I would but there are events which are triggered later on after page load and all of those events use the response data, which is why response is stored in localStorage in the first place. – Ash G Nov 16 '16 at 11:55
  • delegate those events – madalinivascu Nov 16 '16 at 12:02
  • please can you elaborate? – Ash G Nov 16 '16 at 13:13
  • use event delegation to delegate any event (click/change/input/resize,etc) – madalinivascu Nov 16 '16 at 17:01
  • Avoid the [deferred antipattern](http://stackoverflow.com/q/23803743/1048572)! – Bergi Nov 20 '16 at 21:16
  • @AshG Please show us that other code that will re-use that data from the ajax call. In the code you posted it's not clear where the localstorage is written to and where it is read from. – Bergi Nov 20 '16 at 21:18

1 Answers1

1

Here is how to leverage the localStorage and Deferred object to make an alternate path to getSomething

  • This uses the Deferred object
  • It uses the $.ajax call returning the promise.
  • Uses the then call to populate the localStorage item after the API call is made.

var url = "https://jsonplaceholder.typicode.com/posts/1";

function getSomething() {
  var d = $.Deferred();
  var storageResult = checkStorage();
  debugger;
  if (storageResult) {
    console.log("Found in Storage");
    return d.resolve(
      storageResult
    ).promise();
  } else {
    return callAPI();    
  }
}

callAPI = function(){
var url = "https://jsonplaceholder.typicode.com/posts/1";
return $.ajax({
        url : url
    }).then(function(data, textStatus, promise){
        debugger;
      console.log("Made an API call");
      addDataToStorage(data);
      return promise;
    }).fail(function() {
      //fail handler
    });
}

addDataToStorage = function(data) {
  localStorage.setItem("tpiCode", data);
  console.log("Added to Storage");
}


checkStorage = function() {
  if (localStorage.getItem("tpiCode")) {
    return localStorage.getItem("tpiCode");
  }
}

var obj = getSomething();
debugger;
obj.done(function(data) {
  $("result").html(JSON.stringify(data));
});
Winter Soldier
  • 2,607
  • 3
  • 14
  • 18