Print Page | Close Window

Local storage strategy

Printed From: IdeaBlade
Category: Breeze
Forum Name: Community Forum
Forum Discription: Build rich JavaScript apps using techniques you already know
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3697
Printed Date: 27-Feb-2020 at 9:03am


Topic: Local storage strategy
Posted By: kolpation
Subject: Local storage strategy
Date Posted: 06-Oct-2012 at 5:49am
Can you suggest me a strategy to cache all data to local storage after every fetch and save transaction and restore it from local if there is no connection at some point.
I want the program works online but if the connection is broken it has to load from local storage. I know you have export and import functionality. I tried to put them in error handlers. But this is not the way, it doesn't work. What is the best practice?



Replies:
Posted By: jtraband
Date Posted: 06-Oct-2012 at 11:59am
When you say it doesn't work, what is the problem? What was the code you tried to put in the error handler?

Export/import is described in more detail here: http://www.breezejs.com/documentation/exportimport - http://www.breezejs.com/documentation/exportimport 

But, I think the short answer is that in order to store the data into the cache after each of your queries and saves, you would write something like this.

var exportedData = manager.exportEntities();
window.localStorage.setItem("myLocalStorageName", exportedData);

With this code being executed in both the query or save promise 'then()' callback.

Then, when you detect a 'lost' connection, you could restore the data like this

var importedData = window.localStorage.getItem("myLocalStorageName");
manager.importEntities(importedData);

or you could import it into a completely new EntityManager.

One thing to remember, if you have lost your connection, you might want all future queries (until the connection comes back) to go to the local cache by default.  This can be accomplised by calling

manager.defaultQueryOptions = new QueryOptions({ fetchStrategy: FetchStrategy.FromLocalCache });

Going forward, one of the features we've been considering is raising an EntityManager event on each 'Save' or 'Query'; with this you could simply store the exported cache each time the event was called instead of having to add this code to the callback of each query or save.

Please feel free to add your vote to this feature using the feedback mechanism on the web site. ( small icon on the right side of any Breeze website page labeled "Feedback").  This allows other breeze users to vote on the feature and obviously helps us decide which ones to work on next. 





Posted By: kolpation
Date Posted: 08-Oct-2012 at 1:17am
I've put two functions in my dataservice.js file:
function saveToLocalStorage() {
 var metadataAsString = manager.metadataStore.export();
 window.localStorage.setItem("metadata", metadataAsString);
 var storageName = "entities";
 var exportData = manager.export();
 window.localStorage.setItem(storageName, exportData);
};
function getFromLocalStorage() {
 var metadataFromStorage = window.localStorage.getItem("metadata");
 manager.metadataStore.import(metadataFromStorage);
 var bundleFromStorage = window.localStorage.getItem("entities");       
 manager.import(bundleFromStorage);
};

I think they work. But where to call these functions?

I've put the call to saveToLocalStorage in saveChanges function like:
function saveChanges() {
 saveToLocalStorage();
 if (manager.hasChanges()) {
  manager.saveChanges()
   .then(function (saveResult) {
    logger.success("# of Records saved = " + saveResult.entities.length);
    logger.log(saveResult);
   })
   .fail(handleSaveError);
 } else {
  logger.info("Nothing to save");
 };
};
 
I think it works & saves. But I can't figure where to put getFromLocalStorage() call in a situation where the connection is broken. You can give your example in BreezeDocCode project example. I try to make it work :)


Posted By: kolpation
Date Posted: 08-Oct-2012 at 1:18am
By the way I want to implement this algorithm:
 
-make remote query
      -if it fails make local query
-save to local storage


Posted By: jtraband
Date Posted: 08-Oct-2012 at 10:03am
Ok, per your your request, to implement this

-make remote query
      -if it fails make local query
-save to local storage

Try this, ( I didn't actually test it so ... )

var results;

myEntityManager.executeQuery(query)
       .then( function(data) {
            results = data.results;
            processResultsAndStoreLocally(results);
       })
       .fail( function(e) {
            // maybe log the error ...
            results = entityManager.executeQueryLocally(query);
            processResultsAndStoreLocally(results);
       });
}

function processResultsAndStoreLocally(results) {
   // process your results
   saveToLocalStorage();

}

Two additional issues.
   1) We recently changed the import/export method names from 'import' and 'export' to importMetadata/exportMetadata and importEntities/exportEntities to avoid conflict with javascript vNext reserved words. 

   1) In your example you are importing and exporting metadata and data separately. You only really need to import/export the entities; by default, the metadata gets imported and exported with it.  The metadata import/export methods are really intended for use cases where you want to create a new empty entityManager with the same metadata as another entityManager.





Print Page | Close Window