I am trying to understand the Observable/Observer design pattern.
This is the code I have so far (code from Javascript Patterns book):
var publisher = {
subscribers: {
any: [] // event type: subscribers
},
publications: {
any: []
},
subscribe: function (fn, type) {
type = type || 'any';
if (typeof this.subscribers[type] === "undefined") {
this.subscribers[type] = [];
}
this.subscribers[type].push(fn);
if(typeof this.publications[type] === "undefined"){
return;
}
var pubs = this.publications[type],
i,
max = pubs.length
for(i = 0;i<max;i++){
this.subscribers[type][i](pubs[i]);
}
},
unsubscribe: function (fn, type) {
this.visitSubscribers('unsubscribe', fn, type);
},
publish: function (publication, type) {
var pubtype = type || 'any';
this.visitSubscribers('publish', publication, type);
if(typeof this.publications[pubtype] === "undefined") {
this.publications[pubtype] = [];
}
this.publications[pubtype].push(publication);
},
visitSubscribers: function (action, arg, type) {
var pubtype = type || 'any',
subscribers = this.subscribers[pubtype],
i,
max;
if(typeof subscribers === 'undefined') {
return;
}
max = subscribers.length;
for (i = 0; i < max; i += 1) {
if (action === 'publish') {
subscribers[i](arg);
} else {
if (subscribers[i] === arg) {
subscribers.splice(i, 1);
}
}
}
}
};
function makePublisher(o) {
var i;
for (i in publisher) {
if (publisher.hasOwnProperty(i) && typeof publisher[i] === "function") {
o[i] = publisher[i];
}
}
o.subscribers = {any: []};
o.publications = {any: []};
}
var paper = {
daily: function () {
this.publish("big news today");
},
monthly: function () {
this.publish("interesting analysis", "monthly");
},
yearly: function () {
this.publish("every year","yearly");
}
};
makePublisher(paper);
var joe = {
drinkCoffee: function (paper) {
console.log('Just read ' + paper);
},
sundayPreNap: function (monthly) {
console.log('About to fall asleep reading this ' + monthly);
},
onHolidays: function(yearly) {
console.log('Holidays!'+yearly);
}
};
paper.daily();
paper.monthly();
paper.yearly();
paper.subscribe(joe.drinkCoffee);
paper.subscribe(joe.onHolidays,'yearly');
paper.subscribe(joe.sundayPreNap, 'monthly');
I wonder if it is possible somehow to allow clients to receive the notifications
even if they registered themselves after such notifications had been broadcast.
Should I modify the publisher.subscribe and make it check if undefined and if yes publish the event type?
Thanks in advance.
*EDIT 1 *
I've added a publications object to save the publications in the publish function. I also check if there are subscribers for the publication type and if not I call return. Now I need to figure out how to notify them for older publication on subscribe.
*EDIT 2 *
New version of a working script added. Is it thought correct or the best way to do it?
If you want to allow subscribers to get the notifications after they are sent, what you need to do is just
For each different publication type, keep a list of all notifications you get for it.
(When publishing, add the publication to the appropriate list)
Change the subscribe function so that it also sends all the appropriate stored notifications to the late-arriving subscriber.
2.1 Perhaps you should also create a separate send_notification_to(arg, type, subscriber) method, to avoid code duplicatio with visitSubscribers
Related
Soo, I keep getting slammed with cautions from Chrome about how synchronous XmlHttpRequest calls are being deprecated, and I've decided to have a go at trying to convert my use-case over in order to keep up with this fad...
In this case, I have an ~9 year old JS object that has been used as the central (and exemplary) means of transporting data between the server and our web-based applications using synchronous XHR calls. I've created a chopped-down version to post here (by gutting out a lot of sanity, safety and syntax checking):
function GlobalData()
{
this.protocol = "https://";
this.adminPHP = "DataMgmt.php";
this.ajax = false;
this.sessionId = "123456789AB";
this.validSession = true;
this.baseLocation = "http://www.example.com/";
this.loadResult = null;
this.AjaxPrep = function()
{
this.ajax = false;
if (window.XMLHttpRequest) {
try { this.ajax = new XMLHttpRequest(); } catch(e) { this.ajax = false; } }
}
this.FetchData = function (strUrl)
{
if ((typeof strURL=='string') && (strURL.length > 0))
{
if (this.ajax === false)
{
this.AjaxPrep();
if (this.ajax === false) { alert('Unable to initialise AJAX!'); return ""; }
}
strURL = strURL.replace("http://",this.protocol); // We'll only ask for data from secure (encrypted-channel) locations...
if (strURL.indexOf(this.protocol) < 0) strURL = this.protocol + this.adminPHP + strURL;
strURL += ((strURL.indexOf('?')>= 0) ? '&' : '?') + 'dynamicdata=' + Math.floor(Math.random() * this.sessionId);
if (this.validSession) strURL += "&sessionId=" + this.sessionId;
this.ajax.open("GET", strURL, false);
this.ajax.send();
if (this.ajax.status==200) strResult = this.ajax.responseText;
else alert("There was an error attempting to communicate with the server!\r\n\r\n(" + this.ajax.status + ") " + strURL);
if (strResult == "result = \"No valid Session information was provided.\";")
{
alert('Your session is no longer valid!');
window.location.href = this.baseLocation;
}
}
else console.log('Invalid data was passed to the Global.FetchData() function. [Ajax.obj.js line 62]');
return strResult;
}
this.LoadData = function(strURL)
{
var s = this.FetchData(strURL);
if ((s.length>0) && (s.indexOf('unction adminPHP()')>0))
{
try
{
s += "\r\nGlobal.loadResult = new adminPHP();";
eval(s);
if ((typeof Global.loadResult=='object') && (typeof Global.loadResult.get=='function')) return Global.loadResult;
} catch(e) { Global.Log("[AjaxObj.js] Error on Line 112: " + e.message); }
}
if ( (typeof s=='string') && (s.trim().length<4) )
s = new (function() { this.rowCount = function() { return -1; }; this.success = false; });
return s;
}
}
var Global = new GlobalData();
This "Global" object is referenced literally hundreds of times across 10's of thousands of lines code as so:
// Sample data request...
var myData = Global.LoadData("?fn=fetchCustomerData&sortByFields=lastName,firstName&sortOrder=asc");
if ((myData.success && (myData.rowCount()>0))
{
// Do Stuff...
// (typically build and populate a form, input control
// or table with the data)
}
The server side API is designed to handle all of the myriad kinds of requests encountered, and, in each case, to perform whatever magic is necessary to return the data sought by the calling function. A sample of the plain-text response to a query follows (the API turns the result(s) from any SQL query into this format automatically; adjusting the fields and data to reflect the retrieved data on the fly; the sample data below has been anonymized;):
/* Sample return result (plain text) from server:
function adminPHP()
{
var base = new DataInterchangeBase();
this.success = true;
this.colName = function(idNo) { return base.colName(idNo); }
this.addRow = function(arrRow) { base.addRow(arrRow); }
this.get = function(cellId,rowId) { return base.getByAbsPos(cellId,rowId); }
this.getById = function(cellId,rowId) { return base.getByIdVal(cellId,rowId); }
this.colExists = function(colName) { return ((typeof colName=='string') && (colName.length>0)) ? base.findCellId(colName) : -1; }
base.addCols( [ 'id','email','firstName','lastName','namePrefix','nameSuffix','phoneNbr','companyName' ] );
this.id = function(rowId) { return base.getByAbsPos(0,rowId); }
this.email = function(rowId) { return base.getByAbsPos(1,rowId); }
this.firstName = function(rowId) { return base.getByAbsPos(2,rowId); }
this.lastName = function(rowId) { return base.getByAbsPos(3,rowId); }
this.longName = function(rowId) { return base.getByAbsPos(5,rowId); }
this.namePrefix = function(rowId) { return base.getByAbsPos(6,rowId); }
this.nameSuffix = function(rowId) { return base.getByAbsPos(7,rowId); }
this.companyName = function(rowId) { return base.getByAbsPos(13,rowId); }
base.addRow( [ "2","biff#nexuscons.com","biff","broccoli","Mr.","PhD","5557891234","Nexus Consulting",null ] );
base.addRow( [ "15","happy#daysrhere.uk","joseph","chromebottom","Mr.","","5554323456","Retirement Planning Co.",null ] );
base.addRow( [ "51","michael#sunrisetravel.com","mike","dolittle","Mr.","",""5552461357","SunRise Travel",null ] );
base.addRow( [ "54","info#lumoxchemical.au","patricia","foxtrot","Mrs,","","5559876543","Lumox Chem Supplies",null ] );
this.query = function() { return " SELECT `u`.* FROM `users` AS `u` WHERE (`deleted`=0) ORDER BY `u`.`lastName` ASC, `u`.`firstName` LIMIT 4"; }
this.url = function() { return "https://www.example.com/DataMgmt.php?fn=fetchCustomerData&sortByFields=lastName,firstName&sortOrder=asc&dynamicdata=13647037920&sessionId=123456789AB\"; }
this.rowCount = function() { return base.rows.length; }
this.colCount = function() { return base.cols.length; }
this.getBase = function() { return base; }
}
*/
In virtually every instance where this code is called, the calling function cannot perform its work until it receives all of the data from the request in the object form that it expects.
So, I've read a bunch of stuff about performing the asynchronous calls, and the necessity to invoke a call-back function that's notified when the data is ready, but I'm a loss as to figuring out a way to return the resultant data back to the original (calling) function that's waiting for it without having to visit every one of those hundreds of instances and make major changes in every one (i.e. change the calling code to expect a call-back function as the result instead of the expected data and act accordingly; times 100's of instances...)
Sooo, any guidance, help or suggestions on how to proceed would be greatly appreciated!
I might seem really dumb but this piece of code is really frustating me.
if(fs.exist(parametters[0])){
fs.remove(parametters[0]);
return "removed";
}else{
return "doesn't exist"
}
The thing is, the fs.remove() is actually called but the function is returning "doesnt't exist", Am I missing something?
I'm not using nodejs, this is from one library i made, is asynchronously.
It's not modifying the parametters but it does change the condition, might be that?
Well I'm posting my fs object although I don't think this will change anything.
fs = {
load: function() {
if (localStorage[0] == undefined || localStorage[0] == "undefined" || localStorage[0] == "") {
localStorage[0] = JSON.stringify(fs.files);
} else {
fs.files = JSON.parse(localStorage[0]);
}
},
save: function() {
localStorage[0] = JSON.stringify(fs.files);
},
files: [],
newFile: function(name, content, overwrite) {
if (overwrite == undefined)
overwrite = true;
if (fs.exist(name) && overwrite) {
fs.find(name).content = content;
fs.save();
}
if (!(fs.exist(name))) {
fs.files.push({
name: name,
content: content
});
fs.save();
}
},
exist: function(fileName) {
for (var i = 0; i < fs.files.length; i++) {
if (fs.files[i].name == fileName)
return true;
}
return false;
},
find: function(fileName) {
for (var i = 0; i < fs.files.length; i++) {
if (fs.files[i].name == fileName)
return fs.files[i];
}
return false;
},
format: function() {
fs.files = [];
localStorage[0] = undefined;
},
write: function(name, content, overwrite) {
if (overwrite == undefined)
overwrite = true;
if (fs.exist(name) && overwrite) {
fs.find(name).content = content;
fs.save();
}
if (!(fs.exist(name))) {
fs.files.push({
name: name,
content: content
});
fs.save();
}
},
remove: function(file) {
var arrToreturn = [];
for (var i = 0; i < fs.files.length; i++) {
if (fs.files[i].name != file)
arrToreturn.push(fs.files[i]);
}
fs.files = arrToreturn;
fs.save();
return arrToreturn;
}
}
Resolved -
After a few days of inspecting the code I found the bug where the function was called twice, the amount of code was really huge so it took me a while.
You need to add a semi-colon to return "doesn't exist", it should read return "doesn't exist";
If this is an Object, still it works.
We can assume this to be an File object ARRAY, indexOf still works to find if the item exists.
Please have a look upon below example:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var a = fruits.indexOf("Apple");
Result is 2 in case Apple is found
Result is -1 in case Apple is not found
You can have some more options at this link: http://www.w3schools.com/jsref/jsref_indexof_array.asp
Thanks
Use This Code For Solving This Problam. thanks
var fs = require('fs-extra')
fs.remove('/tmp/myfile', function (err) {
if (err) return console.error(err)
console.log('success!')
})
fs.removeSync('/home/jprichardson') //I just deleted my entire HOME directory.
You can try javascript indexOf function to check if the value really exists, BEFORE REMOVE Operation.
Example below:
var str = "Hello world, welcome to the universe.";
var n = str.indexOf("welcome");
=> Gives 13 if found
if we search for "welcome1" -> will give -1
Can't quite figure out how to solve my current situation. I have a complex javascript objects representing an 'organization'. In the page, a list of these organizations are loaded up via ajax get request and pushed into a ko observable array, like so:
$.getJSON(apiBaseUrl + "?userId=" + userId, function (data) {
$.each(data, function () {
var dropdownOrg = new DropdownOrg();
var org = new Organization();
$.each(this, function (k, v) {
if (k === "UserGuid") {
org.userGuid = v;
}
if (k === "OrgId") {
dropdownOrg.orgId = v;
org.orgId = v;
}
if (k === "OrgName") {
dropdownOrg.name = v;
org.orgName = v;
}
if (k === "IsHiring") {
org.isHiring = v;
}
if (k === "Blurb") {
org.blurb = v;
}
if (k === "HqLocCity") {
org.hqLocCity = v;
}
if (k === "HqLocCountry") {
org.hqLocCountry = v;
}
if (k === "NumberOfEmployees") {
org.numberOfEmployees = v;
self.selectedEmployee(v);
}
if (k === "OrgImg") {
org.orgImg = v;
}
if (k === "Ownership") {
org.ownership = v;
self.selectedOwnership(v);
}
if (k === "Website") {
org.website = v;
}
});
self.orgDdl.push(dropdownOrg);
self.orgs.push(org);
});
});
self.OrgDdl is an observable array that only holds enough data so I can switch which organization I am viewing on the page (visibility toggling). self.orgs is the ko observable array that is holding all the data i need to save via an ajax PUT. The organization object looks like this (beware, is ugly):
function Organization(userGuid,
orgId,
orgName,
orgImg,
isHiring,
blurb,
numberOfEmployees,
hqLocCity,
hqLocCountry,
website,
ownership)
{
var self = this;
self.userGuid = userGuid;
self.orgId = orgId;
self.orgName = ko.observable(orgName);
self.isHiring = ko.observable(isHiring);
self.blurb = ko.observable(blurb);
self.numberOfEmployees = ko.observable(numberOfEmployees);
self.hsLocCity = ko.observable(hqLocCity);
self.hsLocCountry = ko.observable(hqLocCountry);
self.website = ko.observable(website);
self.ownership = ko.observable(ownership);
self.orgImg = ko.observable(orgImg);
}
Told you, pretty ugly, but I don't really know how to make that cleaner, and it binds alright, so good enough for now. In the current situation I have 3 organizations being loaded into the orgs observable array. In each of the organizations views I will be placing a button (haven't done it yet, need to figure this out first) that will take the currently visible org and post it.
I have a shell of a PUT request, but I am not sure how to get the current org that I am view out of the array.
self.updateOrganization = function () {
$.ajax({
type: "PUT",
contentType: "application/json; charset=utf-8",
url: apiBaseUrl + "?userId=" + userId,
data: ko.toJSON(?????),
dataType: "json",
success: function (msg) {
alert('success');
},
error: function (err) {
alert('Error updating information, please try again!');
}
});
Any idea?
Got it:
self.selectedOrgId.subscribe(function (currentOrgId) {
//alert(currentOrgId);
var org = ko.utils.arrayFirst(self.orgs(), function (item) {
if (currentOrgId == item.orgId) {
return item;
}
});
alert(ko.toJSON(org));
}, self);
So I can subscribe to changed to my selectedOrgId which gets updated each time I change my drop down list item. Then I can take that id in, use the ko.util.arrayFirst functions to find the item in my observable array that has that id.
Credit to: this guy
Hello!
I learning Ember.js as Web-Client Windows Azure Mobile Services from this tutorial.
When I write:
Tothevoidjs.ApplicationRoute = Ember.Route.extend({
// admittedly, this should be in IndexRoute and not in the
// top level ApplicationRoute; we're in transition... :-)
model: function(params) {
return Tothevoidjs.Secret.findAll();
}
});
I get this error:
Uncaught TypeError: Object function () {
if (!wasApplied) {
Class.proto(); // prepare prototype...
}
o_defineProperty(this, GUID_KEY, undefinedDescriptor);
o_defineProperty(this, '_super', undefinedDescriptor);
var m = meta(this), proto = m.proto;
m.proto = this;
if (initMixins) {
// capture locally so we can clear the closed over variable
var mixins = initMixins;
initMixins = null;
this.reopen.apply(this, mixins);
}
if (initProperties) {
// capture locally so we can clear the closed over variable
var props = initProperties;
initProperties = null;
var concatenatedProperties = this.concatenatedProperties;
for (var i = 0, l = props.length; i < l; i++) {
var properties = props[i];
Ember.assert("Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.", !(properties instanceof Ember.Mixin));
for (var keyName in properties) {
if (!properties.hasOwnProperty(keyName)) { continue; }
var value = properties[keyName],
IS_BINDING = Ember.IS_BINDING;
if (IS_BINDING.test(keyName)) {
var bindings = m.bindings;
if (!bindings) {
bindings = m.bindings = {};
} else if (!m.hasOwnProperty('bindings')) {
bindings = m.bindings = o_create(m.bindings);
}
bindings[keyName] = value;
}
var desc = m.descs[keyName];
Ember.assert("Ember.Object.create no longer supports defining computed properties.", !(value instanceof Ember.ComputedProperty));
Ember.assert("Ember.Object.create no longer supports defining methods that call _super.", !(typeof value === 'function' && value.toString().indexOf('._super') !== -1));
Ember.assert("`actions` must be provided at extend time, not at create time, when Ember.ActionHandler is used (i.e. views, controllers & routes).", !((keyName === 'actions') && Ember.ActionHandler.detect(this)));
if (concatenatedProperties && indexOf(concatenatedProperties, keyName) >= 0) {
var baseValue = this[keyName];
if (baseValue) {
if ('function' === typeof baseValue.concat) {
value = baseValue.concat(value);
} else {
value = Ember.makeArray(baseValue).concat(value);
}
} else {
value = Ember.makeArray(value);
}
}
if (desc) {
desc.set(this, keyName, value);
} else {
if (typeof this.setUnknownProperty === 'function' && !(keyName in this)) {
this.setUnknownProperty(keyName, value);
} else if (MANDATORY_SETTER) {
Ember.defineProperty(this, keyName, null, value); // setup mandatory setter
} else {
this[keyName] = value;
}
}
}
}
}
finishPartial(this, m);
this.init.apply(this, arguments);
m.proto = proto;
finishChains(this);
sendEvent(this, "init");
} has no method 'findAll'
My app.js:
var Tothevoidjs = window.Tothevoidjs = Ember.Application.create();
var client = new WindowsAzure.MobileServiceClient(
"link",
"key"
);
Tothevoidjs.WAMAdapter = Ember.Object.extend({
table: null,
init: function() {
this.table = this.get('table');
},
find: function(record, id) {
var query = this.table.where({
id: id
});
return query.read().then(function(data) {
Ember.run(record, record.load, data);
});
},
findAll: function(klass, records) {
var _self = this;
return _self.table.read().then(function(data) {
Ember.run(records, records.load, klass, data);
});
},
findQuery: function(klass, records, params) {
var query = this.table.where(params);
return query.read().then(function(data) {
Ember.run(records, records.load, klass, data);
});
},
createRecord: function(record) {
return this.table.insert(record.toJSON()).then(function(data) {
Ember.run(function() {
record.load(data.id, data);
record.didCreateRecord();
});
});
}
});
/* Order and include as you please. */
require('scripts/controllers/*');
require('scripts/store');
require('scripts/models/*');
require('scripts/routes/*');
require('scripts/views/*');
require('scripts/router');
My model file:
var attribute = DS.attr;
Tothevoidjs.Secret = DS.Model.extend({
id: attribute('number'),
body: attribute('string')
});
var client = new WindowsAzure.MobileServiceClient(
"link",
"key"
);
Tothevoidjs.Secret.adapter = Tothevoidjs.WAMAdapter.create({
table: client.getTable('secret')
});
And router:
Tothevoidjs.ApplicationRoute = Ember.Route.extend({
// admittedly, this should be in IndexRoute and not in the
// top level ApplicationRoute; we're in transition... :-)
model: function(params) {
return Tothevoidjs.Secret.findAll();
}
});
I do not understand what I did wrong. :(
Please tell me how to avoid this error or what I should read to understand it.
If you need to know version of Ember.js - it's from yeoman generator - 1.0.0
P.S. I'm newbie in web-dev.
Your tutorial is using the ember-model libray. But your current code use ember-data version 1.0.0.beta.x. Both are data libraries for ember, have similar api, but are different.
I recommend you to use the ember-model libray, so you will be able to finish the tutorial.
So, import the ember-model script, the source is here, make sure it comes after the ember.js script, and change your model definition to use ember-model:
var attribute = Ember.attr;
Tothevoidjs.Secret = Ember.Model.extend({
id: attribute('number'),
body: attribute('string')
});
I hope it helps
I need to verify that Web Storage API is supported and available (it may be disabled due to security issues).
So, I thought it would suffice to check whether the type sessionStorage or localStorage is defined or not:
if (typeof sessionStorage != 'undefined')
{
alert('sessionStorage available');
}
else
{
alert('sessionStorage not available');
}
However, I was wondering if it could be possible that the type exists, but I wouldn't been able to use the Web Storage API anyway.
Remarks:
I know Firefox will throw a security error if cookies are disabled and sessionStorage or localStorage are accessed.
Why don't you use the Modernizr library to detect if local storage is supported or not? Any differences between browers will be taken care of for you, you can then just use code like this:
if (Modernizr.localstorage) {
// browser supports local storage
} else {
// browser doesn't support local storage
}
I think you're on the right track with your original code, no need to make this too fancy.
Using the KISS principle with no additional dependencies in your code:
var storageEnabled = function() {
try {
sessionStorage.setItem('test-key','test-value');
if (sessionStorage.getItem('test-key') == 'test-value'){
return true;
}
} catch (e) {};
return false;
};
alert(storageEnabled() ? 'sessionStorage available' : 'sessionStorage not available');
try{
ssSupport = Object.prototype.toString.call( sessionStorage ) === "[object Storage]";
}
catch(e){
ssSupport = false;
}
So, because Modernizr.localstorage respectively Modernizr.sessionstorage will return true while Firefox might be used with disabled Cookies (which will lead into an security error) or any other proprietary (unexpected) behavior could occur: I've written my own webStorageEnabled function which seems to work very well.
function cookiesEnabled()
{
// generate a cookie to probe cookie access
document.cookie = '__cookieprobe=0;path=/';
return document.cookie.indexOf('__cookieprobe') != -1;
}
function webStorageEnabled()
{
if (typeof webStorageEnabled.value == 'undefined')
{
try
{
localStorage.setItem('__webstorageprobe', '');
localStorage.removeItem('__webstorageprobe');
webStorageEnabled.value = true;
}
catch (e) {
webStorageEnabled.value = false;
}
}
return webStorageEnabled.value;
}
// conditional
var storage = new function()
{
if (webStorageEnabled())
{
return {
local: localStorage,
session: sessionStorage
};
}
else
{
return {
local: cookiesEnabled() ? function()
{
// use cookies here
}() : null,
session: function()
{
var data = {};
return {
clear: function () {
data = {};
},
getItem: function(key) {
return data[key] || null;
},
key: function(i)
{
var index = 0;
for (var value in data)
{
if (index == i)
return value;
++index;
}
},
removeItem: function(key) {
delete data[key];
},
setItem: function(key, value) {
data[key] = value + '';
}
};
}()
};
}
}
Hope this will be useful for someone too.
My version (because IE 9 running in IE 8 more on an intranet site is broken).
if (typeof (Storage) != "undefined" && !!sessionStorage.getItem) {
}
a longer version that adds setObject to allow storing objects:
var sstorage;
if (typeof (Storage) != "undefined" && !!sessionStorage.getItem) {
Storage.prototype.setObject = function (key, value) {
this.setItem(key, JSON.stringify(value));
};
Storage.prototype.getObject = function (key) {
return JSON.parse(this.getItem(key));
};
if (typeof sessionStorage.setObject == "function") {
sstorage = sessionStorage;
}
else {
setupOldBrowser();
}
}
else {
setupOldBrowser();
}
function setupOldBrowser() {
sstorage = {};
sstorage.setObject = function (key, value) {
this[key] = JSON.stringify(value);
};
sstorage.getObject = function (key) {
if (typeof this[key] == 'string') {
return JSON.parse(this[key]);
}
else {
return null;
}
};
sstorage.removeItem = function (key) {
delete this[key];
};
}
Here's what I do to use session storage if available if it's not, use cookies..
var setCookie;
var getCookie;
var sessionStorageSupported = 'sessionStorage' in window
&& window['sessionStorage'] !== null;
if (sessionStorageSupported) {
setCookie = function (cookieName, value) {
window.sessionStorage.setItem(cookieName, value);
return value; //you can introduce try-catch here if required
};
getCookie = function (cookieName) {
return window.sessionStorage.getItem(cookieName);
};
}
else {
setCookie = function (cookieName, value) {
$.cookie(cookieName, value);
return value; // null if key not present
};
getCookie = function(cookieName) {
console.log("using cookies");
return $.cookie(cookieName);
};
}