Reputation: 1181
I'm trying to write functions for storing and retrieving window state but cannot figure out how to do that. The idea is that user could make at any time a "snapshot" of the screen and with next login to the app he could retrieve it back, also he can store as many snapshots as he want. For example: on the page I have 4 different closed panels with some kind of filters and 6 different tabs with grid inside (by default the first tab is opened). Now let's say, I have opened 2 of 4 panels, set some filters and worked with 5th tab. I want to be able to store whole window state (For example "My state 1"), and when I logged in at next time, just choose "My state 1" and get back my window state. I already store and retrieve all grid properties in DB with next functions:
Store:
$scope.state = {}
$scope.saveStateString = function(store) {
$scope.state = JSON.stringify($scope.gridApi.saveState.save(store));
// console.log("function save state string")
};
Retrieve
if(objNode.folderId){
eventService.singleFilter(nodeId)
.then(function (res) {
if (res.body){
$scope.restoreStateString(JSON.parse(res.body));
}
});
}
else if (typeof objNode.folderId === "undefined"){
return false
}
$scope.restoreStateString = function(restore) {
$scope.gridApi.saveState.restore( $scope, restore );
};
For now I'm trying to store window state in localstorage and do next:
var storeValue = null;
var keyName = null;
var _window = {};
$scope.storeWorkspace = function (){
for (prop in window)
_window[prop] = window[prop];
storeValue = JSON.stringify(_window)
keyName = prompt("put your key name");
localStorage.setItem(keyName, storeValue);
};
but I get this error
angular.js:13708 TypeError: Converting circular structure to JSON at Object.stringify (native)
I clearly understand, why I'm getting this error, it cause JSON doesn't accept circular objects - objects which reference themselves also I see from
console.log(_window)
how the "window" has many objects inside, so I decided to ask:
How to store and retrieve window state?
Upvotes: 1
Views: 4875
Reputation: 96
Don't mix application data and resources to store, its huge, hard to reuse and will lead to running into other issues.
Keep it simple!
Construct appState object with what you required to reload the views
var appState ={config:{}, data:{}};
Store it in internalStorage / sessionStorage based on how long you to retain forever vs per session
localStorage.setItem("appState", appState);
On initial app start logic, load data from internalStorage / sessionStorage or server and you may modify existing controller code for binding it to the view.
getApplicationData(){
var appState = localStorage.getItem("appState");//get it from browser storage
if(!appState)
//get it from server
return appState;
}
This is more robust and performant approach.
Upvotes: 2
Reputation: 42490
Do not try to store the whole window
. Store your application's state in a separate object, e.g. state
, which you can then attach to the global object if you absolutely have to:
window.state = {}; // your application's state goes here
var serializedState = JSON.stringify(window.state); // To be put into localStorage
Make sure that all the information you need to rebuild your app during the next launch is contained in this object, and nothing more than that. Avoid global state where possible.
Also make sure that your state
object only contains serializable data. E.g. functions or symbols cannot be serialzied to a JSON string and will get lost in the process.
Upvotes: 1
Reputation: 3577
The vast majority of values stored on the window
object are simply not serializable. You will not be able to use JSON
for this. You should instead track all changes you make to window
and store those in a separate JSON object as POJOs. Alternatively, you can copy the initial window
object when your application starts and then only store the differences between the current window
object and the original copy.
In any case, this is probably going to be a hunt of trial and error, depending on what libraries you are using, and how they are using global variables. You will probably find you need to manually filter out some stuff when you serialize. Best practices would suggest nothing should write to the window
object. If you have things writing to the window
object, you're probably dealing with badly behaving code.
Upvotes: 1