No jQuery.
I want to store an object or array in a cookie.
The object should be usable after page refresh.
How do I do that with pure JavaScript? I read many posts, but do not know how to serialize appropriately.
EDIT:
Code:
var instances = {};
...
instances[strInstanceId] = { container: oContainer };
...
instances[strInstanceId].plugin = oPlugin;
...
JSON.stringify(instances);
// throws error 'TypeError: Converting circular structure to JSON'
How do I serialize instances?
How do I maintain functionality, but change structure of instance to be able to serialize with stringify?
Try that one to write
function bake_cookie(name, value) {
var cookie = [name, '=', JSON.stringify(value), '; domain=.', window.location.host.toString(), '; path=/;'].join('');
document.cookie = cookie;
}
To read it take:
function read_cookie(name) {
var result = document.cookie.match(new RegExp(name + '=([^;]+)'));
result && (result = JSON.parse(result[1]));
return result;
}
To delete it take:
function delete_cookie(name) {
document.cookie = [name, '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=.', window.location.host.toString()].join('');
}
To serialize complex objects / instances, why not write a data dump function in your instance:
function userConstructor(name, street, city) {
// ... your code
this.dumpData = function() {
return {
'userConstructorUser': {
name: this.name,
street: this.street,
city: this.city
}
}
}
Then you dump the data, stringify it, write it to the cookie, and next time you want to use it just go:
var mydata = JSON.parse(read_cookie('myinstances'));
new userConstructor(mydata.name, mydata.street, mydata.city);
Use either object's own .toString() method if it gives meaningful serialization or JSON.stringify(). Do note, however, that cookies are usually limited in length and won't be able to hold big amounts of data.
A cookie adaptation class from :
http://www.sitepoint.com/cookieless-javascript-session-variables/
All you need to do is to set and get variables you need to store in cookie.
Work with: int, string, array, list, Complex object
Exemple:
var toStore = Session.get('toStore');
if (toStore == undefined)
toStore = ['var','var','var','var'];
else
console.log('Restored from cookies'+toStore);
Session.set('toStore', toStore);
Class:
// Cross reload saving
if (JSON && JSON.stringify && JSON.parse) var Session = Session || (function() {
// session store
var store = load();
function load()
{
var name = "store";
var result = document.cookie.match(new RegExp(name + '=([^;]+)'));
if (result)
return JSON.parse(result[1]);
return {};
}
function Save() {
var date = new Date();
date.setHours(23,59,59,999);
var expires = "expires=" + date.toGMTString();
document.cookie = "store="+JSON.stringify(store)+"; "+expires;
};
// page unload event
if (window.addEventListener) window.addEventListener("unload", Save, false);
else if (window.attachEvent) window.attachEvent("onunload", Save);
else window.onunload = Save;
// public methods
return {
// set a session variable
set: function(name, value) {
store[name] = value;
},
// get a session value
get: function(name) {
return (store[name] ? store[name] : undefined);
},
// clear session
clear: function() { store = {}; }
};
})();
If you can serialize your object into its canonical string representation, and can unserialize it back into its object form from said string representation, then yes you can put it into a cookie.
Related
I am attempting to create a cookie. I suspect that my cookie isnt saving or being retrieved properly. What am I doing wrong?
I tried 2 methods to save this cookie:
Cookie gets saved in this function:
function(config) {
var config_copy = JSON.parse(JSON.stringify(config));
setCookie('key',config_copy);
}
Use setCookie();
function(config) {
var config_copy = JSON.parse(JSON.stringify(config));
setCookie();
}
Then trigger this function:
function setCookie(key,config_copy){
document.cookie = key + "=" + config_copy;
console.log("cookie saved");
console.log(config_copy);
}
console.log(config_copy); returns undefined in the console.
How would I correctly save the value of config_copy into a JavaScript cookie?
JSON.parse() returns an object, not a JSON string. You should put the JSON string into the cookie, not the result of JSON.parse.
function saveConfig(config) {
var config_copy = JSON.stringify(config);
setCookie("key", config_copy);
}
Otherwise, you'll just set the cookie to [Object object].
Document.cookie only accepts primitive values, if you pass an object it calls Object.toString() which returns [ object Object ].
You have too options for storing an object in cookie form.
Multiple cookies from an object's properties
If you want to make a cookie out of each property of an object, you have to loop through the object and create a cookie out of each property.
var saveConfig = function(config) {
var cookies = [];
for(var i in config)
cookies.push(document.cookie = i + '=' + config[i]);
return cookies;
}
saveConfig({hello: 'world', foo: 'bar'});
console.log(document.cookie);
Outputs: hello=world; foo=bar;
One cookie from an object converted to a string
You can convert the object to a string and store it in one cookie using JSON.stringify().
var saveConfig = function(config) {
return document.cookie = 'config=' + JSON.stringify(config);
}
saveConfig({hello: 'world', foo: 'bar'});
console.log(document.cookie);
Outputs: config={"hello":"world","foo":"bar"};
In your second "option" you have to send a value for the parameters like this:
function(config) {
var config_copy = JSON.parse(JSON.stringify(config));
setCookie("key", config_copy);
}
if you call it without the parameters, they will have an undefined value
You need to pass your variables to setCookie() in order for the function to use them.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Calling_functions
I have following code I use Jquery cookie plugin to set cookie.I need to store multiple values to a a cookie variable using jquery but every time its overwrite so multiple value doesn't store.please have a look into my code and help me.I have a select box and its name is inserted into a cookie variable every time.
$(".cookieul").on("click",function(){
var a ='';
var myCookies = [];
var newValue = $(".client option:selected").text();
a += newValue;
myCookies.push(a);
$.cookie("example", JSON.stringify(myCookies), { expires: 7 });
});
You may write like this -
$(".cookieul").on("click",function(){
var newValue = $(".client option:selected").text();// your new selected text
var old_value_json = $.cookie("example"); // check your plugin get cookie syntax
var old_value_arr = [];
old_value_arr = $.parseJSON(old_value_json); //converting your stored JSON string to javascript array
old_value_arr.push(newValue ); // pushing new value to array
$.cookie("example", JSON.stringify(old_value_arr ), { expires: 7 });//setting new value to cookie
});
This solves the issue.Any other better way
var myCookies = [];
$(".cookieul").on("click",function(){
var newValue = $(".client option:selected").text();
var old_value_json = $.cookie("example");
myCookies = $.parseJSON(old_value_json)
myCookies.push(newValue);
$.cookie("example", JSON.stringify(myCookies), { expires: 7 });
var storedAry = JSON.parse($.cookie('example'));
console.log(unique(storedAry));
function unique(list) {
var result = [];
$.each(list, function(i, e) {
if ($.inArray(e, result) == -1) result.push(e);
});
return result;
}
});
I have the need to store users initial query string parameters during their stay on a webpage. I decided to parse the query string parameters and stick them in a session cookie so when I have code that needs the initial query parameters I call the cookie.
This seems to not always work, esp in IE. Can anyone give me some suggestions? I thought maybe to store it in the dom storage but I'm not sure if that is the right approach.
The code lives in my page header and is accessible on all the pages of the site.
Here is what I put together:
var urlParams;
(window.onpopstate = function () {
var match,
pl = /\+/g,
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = window.location.search.substring(1);
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]);
})();
function set_cookie(name, value) {
var cookie = [name, '=', JSON.stringify(value), '; domain=.', window.location.host.toString(), '; path=/;'].join('');
document.cookie = cookie;
}
function read_cookie(name) {
var result = document.cookie.match(new RegExp(name + '=([^;]+)'));
result && (result = JSON.parse(result[1]));
return result;
}
if(read_cookie('tbts') === null){
set_cookie('tbts', urlParams);
}
var urlParamsCookie = read_cookie('tbts');
You don't specify which version of IE, but according to Can I Use, popstate isn't available until IE10.
I have been looking for an answer to this all afternoon and i cant seem to find the best way to accomplish what i need to.
My JSON string (returned from a web service) has circular references in it (#ref) which point to $id in the string. Now i know that if use jquery parseJSON it creates the javascript object and i can access properties a la myObject.MyPropertyName. However, when i get to a #ref, i am unsure how to get the object that ID points to (which i assume is already created as a result of the de-serialization...
Should i be iterating though the object and all its child objects until i find it, or is there an easier way?
$.ajax({
type: "POST",
url: "/Task.asmx/GetTask",
data: "{'id':'" + '27' + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
_Data = $.parseJSON(msg.d ? msg.d : msg);
_this.Company = _Data[0].t_Program.t_Company;
_this.Program = _Data[0].t_Program;
_this.Task = _Data[0];
},
complete: function () {
}
});
The area in question is _Data[0].t_Program because it does not return an object but rather returns
_Data[0].t_Program
{...}
$ref: "12"
I dont exactly know the best way to get the object with $id "12". Based on the posts below it seems i should loop through the existing object, but i was hoping there was a jquery function that did that...
Many Thanks!
No, jQuery is not natively capable of resolving circular references in objects converted from JSON.
The only library for that which I know is Dojo's dojox.json.ref module.
But, your server application serializes that JSON somehow. Don't tell me that the solution it uses does not offer a deserialisation algorithm!
As my friend Alan, the author of the Xerox Courier (RPC over the net) library, used to say to me, "there are no pointers on the wire."
In other words, it is impossible for a JSON representation of a data structure to be circular. (But a circular structure can be flattened into a non-circular JSON structure.) As the JSON site says:
JSON is built on two structures:
A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
No pointers!
So the entire JSON will have been turned into Javascript Objects and/or Arrays after the jQuery parseJSON operation completes.
If the original stucture's ref_id values were used as the property names in the JSON / Javascript object, then they'll all be there.
The real issue is that you need to understand how your server serialized its data structure into the JSON data structure. Look in your server-side code to determine that.
Then use Javascript to de-serialize the JSON structure back into the best Javascript structure to fit your needs.
Re: Should i be iterating though the object and all its child objects until i find it, or is there an easier way?
The easier way would be to go through the Javascript structure once, and build up an additional "indexing" object whose properties are the #ref_id and the values are the original structure/value.
Sample:
var jsonCyclicReferenceFixed = JsonRecursive.parse(jsonWithRefAndId);
(function(){
function type(value){
var t = typeof(value);
if( t == "object" && value instanceof Array) {
return "array";
}
if( t == "object" && value && "$id" in value && "$values" in value) {
return "array";
}
return t;
}
function TypeConverterFactory(){
var converters = {};
var defaultConverter = {
fromJson: function(value){ return value; },
toJson: function(value){ return value; },
};
this.create = function(type){
var converter = converters[type];
if(!converter) return defaultConverter;
return converter;
};
this.register = function(type, converter){
converters[type] = converter;
converter.valueConverter = this.valueConverter;
};
}
function ObjectConverter(){
this.fromJson = function(obj){
if( obj == null ) return null;
if( "$ref" in obj ){
var reference = this.dictionary[obj.$ref];
return reference;
}
if("$id" in obj){
this.dictionary[obj.$id] = obj;
delete obj.$id;
}
for(var prop in obj){
obj[prop] = this.valueConverter.convertFromJson(obj[prop]);
}
return obj;
}
this.toJson = function(obj){
var id = 0;
if(~(id = this.dictionary.indexOf(obj))){
return { "$ref" : (id + 1).toString() };
}
var convertedObj = { "$id" : this.dictionary.push(obj).toString() };
for(var prop in obj){
convertedObj[prop] = this.valueConverter.convertToJson(obj[prop]);
}
return convertedObj;
}
}
function ArrayConverter(){
var self = this;
this.fromJson = function(arr){
if( arr == null ) return null;
if("$id" in arr){
var values = arr.$values.map(function(item){
return self.valueConverter.convertFromJson(item);
});
this.dictionary[arr.$id] = values;
delete arr.$id;
return values;
}
return arr;
}
this.toJson = function(arr){
var id = 0;
if(~(id = this.dictionary.indexOf(arr))){
return { "$ref" : (id + 1).toString() };
}
var convertedObj = { "$id" : this.dictionary.push(arr).toString() };
convertedObj.$values = arr.map(function(arrItem){
return self.valueConverter.convertToJson(arrItem);
});
return convertedObj;
}
}
function ValueConverter(){
this.typeConverterFactory = new TypeConverterFactory();
this.typeConverterFactory.valueConverter = this;
this.typeConverterFactory.register("array", new ArrayConverter);
this.typeConverterFactory.register("object", new ObjectConverter);
this.dictionary = {};
this.convertToJson = function(valor){
var converter = this.typeConverterFactory.create(type(valor));
converter.dictionary = this.dictionary;
return converter.toJson(valor);
}
this.convertFromJson = function(valor){
var converter = this.typeConverterFactory.create(type(valor));
converter.dictionary = this.dictionary;
return converter.fromJson(valor);
}
}
function JsonRecursive(){
this.valueConverter = new ValueConverter();
}
JsonRecursive.prototype.convert = function(obj){
this.valueConverter.dictionary = [];
var converted = this.valueConverter.convertToJson(obj);
return converted;
}
JsonRecursive.prototype.parse = function(string){
this.valueConverter.dictionary = {};
var referenced = JSON.parse(string);
return this.valueConverter.convertFromJson(referenced);
}
JsonRecursive.prototype.stringify = function(obj){
var converted = this.convert(obj);
var params = [].slice.call(arguments, 1);
return JSON.stringify.apply(JSON, [converted].concat(params));
}
if(window){
if( window.define ){
//to AMD (require.js)
window.define(function(){
return new JsonRecursive();
});
}else{
//basic exposition
window.jsonRecursive = new JsonRecursive();
}
return;
}
if(global){
// export to node.js
module.exports = new JsonRecursive();
}
}());
Sample:
// a object recursive
// var parent = {};
// var child = {};
// parent.child = child;
// child.parent = parent;
//
//results in this recursive json
var json = '{"$id":"0","name":"Parent","child":{"$id":"1","name":"Child","parent":{"$ref":"0"}}}'
//Parsing a Recursive Json to Object with references
var obj = jsonRecursive.parse(json);
// to see results try console.log( obj );
alert(obj.name);
alert(obj.child.name);
i want to store form on clientside, in json in cookie, after that deserialize it back to form.
what i'm doing:
serialization to JSON:
function formToJSON(selector) {
var form = {};
$(selector).find(':input[name]:enabled').each(function () {
var self = $(this);
var name = self.attr('name');
if (name.indexOf('TextBox', 0) == 0) {
if (form[name]) {
form[name] = form[name] + ',' + self.val();
}
else {
form[name] = self.val();
}
}
});
return form;
}
then on form change, i'm trying to save form to cookie:
$('#form1 :input').change(function () {
var eba = formToJSON($('#form1'));
$.cookie.set('fo', eba, {json:true});
var a = $.cookie.get('fo',true);
alert(a);
//$.cookie.set('form123', { "ksf": "saf", "tt": "" }, { json: true });
//var b = $.cookie.get('form123', true);
//alert(JSON.stringify(b));
});
in debugger - eba is json object, but alert(a) gives null.
commented code works, this json serialized, and i'm gettin it from cookies.
but why code doesnt work for form???
cookie plugin taken from jquery.com
Use this library to stringify/parse JSON http://json.org/js.html
remember that there is an approx 4KB size limit on cookies , http://support.microsoft.com/kb/306070
AFAIK browser cookies cannot be read using javascript(except for your own domain), to prevent Cross Site Reeuqest Forgery
But you can still set them.