Caching Webapp interface and restoring it using html5 localstorage - javascript

Okay. So i have heard plenty about building apps using phonegap and html5. the app works fine but it access a web service to populate the div for display. The service runs well what i want to implement is a caching mechanism for storing the last interface from the service using local-storage while a fresh request is going on in the background.
This is my javascript code. Please what am i doing wrong.
P.S am a html5/js intermediate user. However, i user php really well.
function loadHome()
{
$("#post_display").html(waitText);
$.get(api_url',{ app_key: my_app_key } ,
function(data){
if(('localStorage' in window) && window['localStorage'] !== null)
{
localStorage.setItem('data_home',data); alert(localStorage.getItem(data_home));
}
$("#post_display").html(data) }
);
}
so far, the alert works and shows me the data stored. Now how do i display the data when the user returns to the page. what conditional logic do i use?
sample
if(localstorage.data_home){ //display store data here }
else{//run the ajax call to the api service}
i dont know how to go about this. Help.

just check before you call ajax. It's just a sample, you need to refact your source code.
function loadHome()
{
$("#post_display").html(waitText);
if(('localStorage' in window) && window['localStorage'] !== null && localStorage.getItem('data_home')){
$("#post_display").html(localStorage.getItem('data_home'));
return;
}
$.get(api_url',{ app_key: my_app_key } ,
function(data){
if(('localStorage' in window) && window['localStorage'] !== null)
{
localStorage.setItem('data_home',data); alert(localStorage.getItem(data_home));
}
$("#post_display").html(data) }
);
}

Related

Local Storage using Dexie not staying persistent

I am using Dexie to access IndexedDB on a flash card maker project. I can manipulate the database as expected, and it stays in the database if I close and reopen the browser, but often when I open up the project after not working on it for a few days, the stored data I put into the database isn't there any longer.
I did some research and discovered that I need to make the database persistent, but I can't figure out how to do that.
I have pretty much copied the recommended code from the Dexie Storage Manager page into the onLoad function for the main page, index.js. Here is the relevant code:
//When the page loads, display the decks in ul on the webpage.
window.addEventListener('load', onLoad);
async function onLoad() {
//Check how much data is available.
showEstimatedQuota();
//Make sure the storage is persistent.
isStoragePersisted().then(async isPersisted => {
if (isPersisted) {
console.log(":) Storage is successfully persisted.");
} else {
console.log(":( Storage is not persisted.");
console.log("Trying to persist..:");
if (await persist()) {
console.log(":) We successfully turned the storage to be persisted.");
} else {
console.log(":( Failed to make storage persisted");
}
}
});
}
The above onLoad function references three functions I have saved on dexie-setup.js:
//This function makes the storage persistent.
//(Copied from https://dexie.org/docs/StorageManager)
async function persist() {
return await navigator.storage && navigator.storage.persist &&
navigator.storage.persist();
}
//This function checks if the storage is persistent.
//(Copied from https://dexie.org/docs/StorageManager)
async function isStoragePersisted() {
return await navigator.storage && navigator.storage.persisted &&
navigator.storage.persisted();
}
//This function logs to console how much data is available.
//(Copied from https://dexie.org/docs/StorageManager)
async function showEstimatedQuota() {
if (navigator.storage && navigator.storage.estimate) {
const estimation = await navigator.storage.estimate();
console.log(`Quota: ${estimation.quota}`);
console.log(`Usage: ${estimation.usage}`);
} else {
console.error("StorageManager not found");
}
}
My console logs:
dexie-setup.js:56 Quota: 6358499328
dexie-setup.js:57 Usage: 25370
index.js:30 :( Storage is not persisted.
index.js:31 Trying to
persist..:
dexie-setup.js:84 Done checking dexie.
index.js:33 :) We successfully turned the storage to be persisted.
However, if I refresh the page, I get the same thing logged on my console: the database is still set to not persistent.
The showEstimatedQuota function checks the data storage and confirms that the DataStorage API is functioning, so I don't think that's the problem. (I'm only storing small objects with text in them, so I don't expect to exceed the storage limit, anyway.)
So far, the project is entirely local on my chromebook, and I am viewing it on a Chrome browser.
Please let me know how to make my database persistent. I'm pretty new to this (this is my first question on stackoverflow!), so hopefully it's an easy problem to solve! Thanks in advance.
citing the documentation of Dexie: "Even though IndexedDB is a fully functional client-side database for the web, it is not a persistent storage by default. IndexedDB without StorageManager is just a “best-effort” database that can be erased in situations of low disk space on a device. The browser may delete your database without notifying the user in case it needs to free up space for other website’s data that was used more recently than yours."
So, you can't make the database persistent. Just make a “best-effort”.
This links can be of help:
https://web.dev/persistent-storage/
Chrome.Storage.Local Persistence
I hope it will be of help to you.
The only way I have found is that if the user bookmarks the site then it enables persistent storage using the persist function:
//This function makes the storage persistent.
//(Copied from https://dexie.org/docs/StorageManager)
async function persist() {
return await navigator.storage && navigator.storage.persist &&
navigator.storage.persist();
}
So you may prompt the user to bookmark your site when it loads.

How to add class "offline" to the body if page shown from cache using service worker

I am working on a progressive web app using service worker every thing is working perfectly. Now I want to hide some content on my pages if pages are served from cache so I need to add class "offline" to the body.
Please tell me how can I add document.body.classList.add("offline"); in the below code.
//Fetch from network failed
var fallback = function() {
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
return caches.match(event.request).then(function (response) {
// need to return the response and add class "offline" to the body here
return response || caches.match('offline-page.html');
})
}
}
If I am doing wrong please let me know proper way to do it.
I'm not sure if you can tamper a cached response's content. But I have an alternative solution.
navigator.onLine is the HTML5 API that can help you detect the online/offline status of browser. You can put this piece of code in your page:
window.addEventListener('load', () => {
if (!navigator.onLine) document.body.classList.add("offline");
}, false )

session storage does not working on different tab

I want to pass some data between different tabs using sessionStorage on my local server. I have tried some ways but could not succeed. Anyone please help me.
This is my one file where I am setting my data.
if (typeof(Storage) !== "undefined") {
var loggedInUserId = loggedInId;
console.log(loggedInUserId);
sessionStorage.clear();
sessionStorage.setItem("loggedin_id", loggedInUserId);
console.log(sessionStorage);
}
and I am trying to fetch the data from other file of another project of my local drive
var companyId = sessionStorage.getItem("loggedin_id");
The problem is, data is setting on the browser but when I check on my other project tab the storage remain empty.
note: my two projects are in two drives, dont know its makes difference or not. Please anyone give me some way to solve it. thank you .
Session storage is not the appropriate tool for your task you should be using local storage
For sessionStorage, changes are only available per window (or tab in browsers like Chrome and Firefox)
in your case you want the data to be shared throughout different tabs so you can do something like this :
if (typeof(Storage) !== "undefined") {
localStorage.setItem("firstname", "fady");
} else {
// Sorry! No Web Storage support..
}
and then you can retrieve it just the same you did with your session storage
var firstname = localStorage.getItem("firstname");
Fady Sadek's answer is the right way to do it, I would add a check if the localStorage is available before getting the value as well, and if the data is actually saved before trying to get it.
JS Fiddle
function saveText() {
if (typeof(Storage) !== "undefined") {
localStorage.setItem("myData", "Hello, Rajesh!");
alert('Data saved.');
} else {
alert('Local storage not available');
}
}
function getText() {
if (typeof(Storage) !== "undefined" && typeof(localStorage.getItem('myData')) !== "undefined") {
alert(localStorage.getItem('myData'));
} else {
alert('Local storage not available or the data is not saved.');
}
}
Keep in mind the scopes of the storage, you can only use it between tabs/windows within the same subdomain and/or the domain.

SharePoint JavaScript Desktop Notification Issue

I have a really strange JavaScript issue that I haven't found any precedent for so hoping someone has seen it.
I'm working on some JavaScript code that resides in SharePoint and I'm trying to use desktop notifications for my Firefox and Chrome users.
I have the following code as just a basic test
$(document).ready(function() {
if ((window.Notification) && (Notification.permission !== "granted")) {
Notification.requestPermission(function(status) {
if (Notification.permission != status) Notification.permission = status;
});
}
if (Notification.permission === "granted") {
var Notification = new Notification("This is a test");
}
});
If I use this code in a custom web page outside of SharePoint it works perfectly fine. If I load it in SharePoint though it's sporadic; some pages it will work just fine but other pages I get an error saying that Notifcation.requestPermission isn't a function. If I do a console.log on the Notification object and Notification.permission I get different results depending on whether I'm on a working page or not working page. On a working page I see Notification as a function with all the correct parameters and Notification.permission comes up as "granted"; the not working pages has Notification as a blank object and Notification.permission is undefined. This happens in both SharePoint 2010 and 2013.
Anyone experienced this before?
This is expected behaviour since you overwrite the Notification object with your own code.
As soon as you've run var Notification = new Notification("This is a test"); you've overwritten the native Notification function code with an instance of the Notification.
You should instead write something like (notice the lower case n)
if (Notification.permission === "granted") {
var notification = new Notification("This is a test");
}
The requestPermission function is declared in the Notification prototype, which is a property of it's constructor function but not the instance, thus you can never call requestPermission on the returned object from new Notification(...).

HTML5 Storage Problem

I have a notes box that can be used to store notes, originally I was using cookies to store the entries, then I tried HTML5 Storage and I can't get it to work, here is the code:
$(document).ready(function () {
$('#savesNotes').click(function () {
localStorage.nltwonotes=document.forms[0].todo1.value;
}
});
document.forms[0].todo1.value=localStorage.nltwonotes;
});
Here is some working code:
Preview (type in, then view your localStorage in your console) :
http://jsbin.com/exote5/
Source:
http://jsbin.com/exote5/edit
$(document).ready(function () {
$('#saveNotes').click(function () {
localStorage.nltwonotes=$('#note').val();
});
if(localStorage.nltwonotes){
$('#note').val(localStorage.nltwonotes);
}
else{
//Not set yet
}
});
== NOTE ABOUT THE FILE:/// PROTOCOL ==
You must have localStorage on a server (http or https). Firefox will not let you use them locally. If you are using a Mac you can use MAMP or on Windows you can use WAMP If you're on Linux you probably already know how to setup a local hosting enviroment with apache which is usually provided...
I'd recommend using the methods provided to access localStorage instead of how you're doing it:
localStorage.setItem("nltwonotes", document.forms[0].todo1.value);
Then to get a value:
document.forms[0].todo1.value = localStorage.getItem("nltwonotes");
Though, make sure you check to see if localStorage is even available:
function supports_html5_storage() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
}
Otherwise you'll want to fallback / tell the user to upgrade their browser to one that supports local storage.

Categories

Resources