I am working on an Angular 4 project and I'm a bit stuck on how to implement the following.
Steps:
User uses the application and things change on it
These changes are saved locally using localStorage
A Service listens for changes in the data and if there are changes it uploads the changes to the server.
My idea behind saving the data locally is that the user doesn't have to get involved on sending the data to the server and also if the serve was to go offline, the user can still continue working via the local data available.
My question is...Is this a good idea or are there better ways of doing this with Angular ?
Your idea is good, here are steps to implement it:
1、Create a storage service, e.g. StorageService, to save data in localStorage
2、Create a update service, e.g. UpdateService, to get data from localStorage and upload to server
3、In StorageService, every time the data changed, call UpdateService
4、In UpdateService, you can detect whether network is online or offline, and you probably want a lastUpdateTime field, to record the last time when you successfully update the data to server, so you can control the frequency of update
I suggest you to make an entry in the server first, if you do not have a network or your save call to server fails your local storage will never have the correct data. My suggestion will be,
User uses the application and things change on it,
A Service listens for changes in the data and if there are changes it uploads the changes to the server.
if above call succeed save it in your LocalStorage,
still if you wish to save the data I suggest you try to keep it away from the view logic.
Related
Intro:
I've got a complex and long lasting query on the back-end, feeding back the angular app on the front-end.
Currently the angular app uses the cached data on the back-end rather than reading directly from the complex query, which would take few minutes. The cache gets warm every morning and every night.
As users make changes to the UI, and save the data, which is then passed onto the server side, and saved to database. At that time the UI is up to date until the user refreshes the page. At the same time database is up to date, but the cache is stale.
So when the user refreshes the page the stale cache values are displayed on the page.
More info:
I'm now thinking of ways to refresh the cache, and any advice from more experienced folks would be most welcome.
My idea is to refresh the cache by a cache job (one at a time), which is queued as soon as user saves something. The job will have the relevant info what changed, and the whole cache won't have to be recalculated but rather just the bit which changed.
Question part:
What technique can I use to keep the user up to date with the data even if the user refreshes the page? Should I save the 'deltas', on the client side in a form of indexedDB or localstorage, at the same when the data is sent to server. So when the page refreshes the user reads the data from the localstorage or indexed db.
I'm still thinking this through, obviously I don't have much experience in this, any comments on the directions I've taken so far?
Basically I can change anything including back-end/front-end/caching it's still in the POC phase, I'm just trying to be as informed as possible to what worked for other people.
Update
Little more background. I'm working on a index like page, so there are more than one records that can be edited inline.
Also I'm doing some transformation of the flat db records on the back-end, before dumping them into the map like structure, and passing it to the front-end in a form of json.
I would think the simplest way would be to make sure you know the time the cache was created. When you make changes, save the current state of the page in localStorage, along with the time of the cache. When you load the page, you get the cached data, check it's time to see if it is more recent than your localStorage version. If it is, use the cache, if not, reload your data from localStorage since it has the cached data PLUS your changes already.
Your question is too long, let me summarize the facts.
You have a lot of information in the database
Direct search query takes several minutes
To provide fast search, you use cache which is updated two times a day
When user changes the data, database is updated and cache is not, so web page shows outdated information from cache.
This looks like a typical cache using scenario and the solution is obvious: you should update the cache with deltas as soon as database is changed. The real implementation will depend on your application architecture and cache structure.
The typical workflow for your problem would be:
def updateRequest(Request req) {
def tx = db.startTransaction();
tx.execute(createUpdate(req.getData()));
tx.commit(); // if transaction fails, cache is not updated
cache.update(req.getData()); // can be done in background, if you return delta
}
It seems that you are storing your data in tables and you use those tables with a complex query to build a JSON configuration to render your index.html file. I avoided this problem by avoiding tables and using a NoSQL solution. I build the JSON configuration object on the client side and store that JSON configuration object in a NoSQL collection. I do a simple query using the URL to grab the JSON configuration object and render the index.html file.
I have a little experience storing the JSON configuration object with AWS DynamoDB, and if I need to get faster I will probably switch to AWS ElastiCache.
The key is that you need to cache your JSON configuration object with a useful key like the site hostname or some other base URL and use that as your source of truth for index.html rendering.
I know that similar questions have been asked before. But, I do not find a satisfactory answer. So, I am posting this.
I have an app, that pulls data from a server using REST API calls. I have 4 primary list views / tabs. Now here are a few scenarios:
Internet is available - All is good. You navigate back and forth between the views and you fetch the any new data on the server. Previously fetched data is part of the cache view that Ionic provides. All good.
Internet is disconnected. Immediately user navigates to another view. I am not able to use the Offline / Online event that Cordova / Angular provides as it takes a while after the disconnection for the event to fire. Meanwhile, the screen navigation has fired some $http calls (on view Enter event) to my server and returns an error because internet is not available.
I dont think it is wise to generalize all $http errors as Internet not available (is there a way to find that error is because of NO INTERNET?). It could be that the error is because of some other error on server side. I want to be able to navigate to a generic error page if this happens.
Internet is disconnected, user tries to navigate to a new view. If this new view is loaded with data then just show the data that was cached previously when internet was available. If no data was loaded, then show a popup saying "Please fix your internet". On click of Ok, navigate back to the view where the user came from. I haven't found any good solution to achieve this. Ofcourse, I can handle this in the Controller of every view, but I would like to make a generic service or use an httpinterceptor who can do all this for me once for all the views.
Any robust solutions on how all the above scenarios can be handled gracefully?
for 2:
for any http call, if failed, call 'AnotherApi' which is a 'Very simple Api that is very unlikely to fail on the Server side', if this 'AnotherApi' fails, it's a no internet problem, otherwise you can show your generic Server error page.
to make sure this 'AnotherApi' works, you can place it in Another Domain/Another physical location or simply call any Services available in the internet.
for 3:
in my case, i do not retrieve data from Api directly, in all my views, retrieve data and display data are handled separately. after retrieve data from webservices and/or signalr, I put the data in internal arrays or internal storage or cookie or client side sqlite. To display data, I always retrieve data from client side storage.
I have a signalr connection (something like socket connection) to make sure the display data is the possible newest data since last success internet connection available, the signalr Server tells me if there is any new data in the Server.
I have an ionic app and a Parse.com backend. My users can perform CRUD functions on exercise programmes, changing every aspect of the programme including adding, deleting, editing the exercises within it.
I am confused about when to save, when to call the server and how much data can be held in services / $rootScope?
Typical user flow is as below:
Create Programme and Client (Create both on server and store data in $localStorage).
User goes to edit screen where they can perform CRUD functions on all exercises within the programme. Currently I perform a server call on each function so it is synced to the backed.
The user may go back and select a different programme - downloading the data and storing it localStorage again.
My question is how can I ensure that my users data is always saved to the server and offer them a responsive fast user experience.
Would it be normal to have a timeout function that triggers a save periodically? On a mobile the amount of calls to the server is quite painful over a poor connection.
Any ideas on full local / remote sync with Ionic and Parse.com would be welcome.
From my experience, the best way to think of this is as follows:
localStorage is essentially a cache layer, which if up to date is great because it can reduce network calls. However it is limited to the current session, and should be treated as volatile storage.
Your server is your source of truth, and as such, should always be updated.
What this means is, for reads, localstorage is great, you don't need to fetch your data a million times if it hasn't changed. For writes, always trust your server for long term storage.
The pattern I suggest is, on load, fetch any relevant data and save it to local storage. Any further reads should come from local storage. Edits, should go directly to the server, and on success, you can write those changes to localstorage. This way, if you have an error on save, the user can be informed, and/or you can use localstorage as a queue to continue trying to post the data to the server until a full success.
This is called "offline sync" or sometimes "4 ways data binding". The point is to cache data locally and sync it with a remote backend. This is a very common need, but the solutions are unfornately not that common... The ideal flow would follows this philosophy:
save data locally
try to sync it with server (performing auto merges)
And
Periodically sync, along with a timer and maybe some "connection resumed" event
This is very hard to achieve manually. If been searching modules for a long time, and the only ones that come to my mind don't realy fit your needs (become they often are backend providers that give you frontend connectors; and you already have an opiniated backend), but here they are anyway:
Strongloop's Loopback.io
Meteor
PouchDB
I'm controlling a d3JS interface from another platform. The workflow: Data->Python to create JSON->d3JS to generate graphic->load the html page locally in a browser.
Is anyone aware of a way within this workflow to force a page reload when the JSON data is updated?
This is essentially a problem of how to push updates from the server to the client.
There are two approaches:
Fake it. You could use AJAX polling to periodically ask the server whether new data is available.
Do it for real. You could use WebSockets to push the data from the server to the client when an update occurs.
With the new data in hand, it should be simple to bind in D3 via the General Update Pattern. See http://bl.ocks.org/mbostock/3808218
If you must reload the page, you can also use either of these approaches to trigger it.
In the application I am writing, a user captures information about a person via an online form. When they have completed the form they save their work, repeating this process several times in a session. When they hit 'Save and End Session' they are returned a list of the several person instances they have just saved, all data being saved to a server.
I wish to replicate this functionality in an offline app. Using HTML5 I understand how to cache pages, and how store the JSON form data in localStorage using raw Javascript (or perhaps Angular.js cache).
But is it possible to dynamically update cached webpages with cached data while offline? how, for example, can I write the the cached form data to a cached copy of the list page, updating that page with the data just produced, all during the offline session?
I cannot find an answer to this one. All suggestions are much appreciated!
If I understood this correctly, you want to dynamically update the html view while offline.
If you are using Angular, this is pretty simple.
You just have to cache also the JS controller, not only the html file (set it in the cache.manifest). The page will have the same functionality as the online app then. But if you want to send the stored offline data back to the server when offline, you can write a simple code that will:
Save the parameter in localStorage, which will mark if the data was saved while running online/offline app (you can recognize onine/offline by sending AJAX request to an existing part of the app, which is not available offline (so not cached one))
When app runs then in online mode, it will collect all the data stored offline and send it to the server