In a Chrome Extension, I'm trying to save a Date object to storage then read it back. According to the official documentation,
Values with a typeof "object" and "function" will typically serialize to {}, with the exception of Array (serializes as expected), Date, and Regex (serialize using their String representation).
I'm saving to storage as:
var value= new Date(Date.now());
chrome.storage.sync.set({"testdate":value}, function(){
console.log("saved testdate to storage:");
console.log(value);
});
The output of logging the value is
Tue Oct 16 2018 08:22:11 GMT-0700 (Pacific Daylight Time)
I'm later retrieving from storage as:
chrome.storage.sync.get("testdate", function(items){
console.log("test date from storage:");
console.log(items.testdate);
});
In this case, the value of logging items.testdate is:
Object proto: constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() defineGetter: ƒ defineGetter() defineSetter: ƒ defineSetter() lookupGetter: ƒ lookupGetter() lookupSetter: ƒ lookupSetter() get proto: ƒ proto() set proto: ƒ proto()
Can't figure out how to get my Date object back (or the string representation to convert back to a Date)
In a Chrome Extension, I'm trying to save a Date object to storage then read it back. According to the official documentation,
Values with a typeof "object" and "function" will typically serialize to {}, with the exception of Array (serializes as expected), Date, and Regex (serialize using their String representation).
I'm saving to storage as:
var value= new Date(Date.now());
chrome.storage.sync.set({"testdate":value}, function(){
console.log("saved testdate to storage:");
console.log(value);
});
The output of logging the value is
Tue Oct 16 2018 08:22:11 GMT-0700 (Pacific Daylight Time)
I'm later retrieving from storage as:
chrome.storage.sync.get("testdate", function(items){
console.log("test date from storage:");
console.log(items.testdate);
});
In this case, the value of logging items.testdate is:
Object proto: constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() defineGetter: ƒ defineGetter() defineSetter: ƒ defineSetter() lookupGetter: ƒ lookupGetter() lookupSetter: ƒ lookupSetter() get proto: ƒ proto() set proto: ƒ proto()
Can't figure out how to get my Date object back (or the string representation to convert back to a Date)
Share Improve this question edited Sep 17, 2021 at 19:20 ted 14.8k10 gold badges68 silver badges113 bronze badges asked Oct 16, 2018 at 15:27 KatieKatie 5083 silver badges16 bronze badges 3-
Only JSONifiable part of a value is stored. To view it, type
JSON.stringify(value)
and you'll see{}
because Date isn't JSONifiable. You can stored.valueOf()
which is a number then recreate the date likenew Date(items.testdate)
. – woxxom Commented Oct 16, 2018 at 17:41 -
Thanks, that worked in my example. In my "real" code, the date object is contained in a wrapper object (and I call JSON.stringify on the wrapper object), like
JSON.stringify(obj);
. If I'm stringifying the entire wrapper object like that, how do I override the Date object to call valueOf()? I triedDate.prototype.toJSON = function(){ return this.valueOf(); }
but that doesn't seem to have an effect. – Katie Commented Oct 16, 2018 at 21:24 - I don't know but I would make a wrapper for the storage set and get, that makes the necessary amendments in a deep copy of the object. – woxxom Commented Oct 17, 2018 at 4:45
2 Answers
Reset to default 7Setting side
const currentTime = (new Date()).toJSON();
const items = { 'testdate': currentTime };
chrome.storage.local.set(items, () => {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
}
});
Getting side
chrome.storage.local.get(['testdate'], (result) => {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.message);
} else {
const storedJSONDate = result['testdate'];
const testdate = new Date(storedJSONDate);
console.log(testdate);
}
});
Sources
I based my code off of Date.prototype.toJSON which says
var jsonDate = (new Date()).toJSON(); var backToDate = new Date(jsonDate); console.log(jsonDate); //2015-10-26T07:46:36.611Z
From the Chrome storage official documentation, I think it's saying that Date won't serialize as expected. Because it specifies how Array and Regex serialize to, but not how Date serializes, I think it serializes to {}
, which is what I got when I didn't include the toJSON()
parts.
An object which gives each key/value pair to update storage with. Any other key/value pairs in storage will not be affected. Primitive values such as numbers will serialize as expected. Values with a typeof "object" and "function" will typically serialize to {}, with the exception of Array (serializes as expected), Date, and Regex (serialize using their String representation).
Can also use getTime()
:
//set
const currentTime = (new Date()).getTime(); //equals (new Date()).valueOf()
const items = {'testdate': currentTime};
chrome.storage.local.set(items);
//get
chrome.storage.local.get('testdate', (items) => {
const time = items['testdate'];
const testdate = new Date(time);
console.log(testdate);
});