localStorage - append an object to an array of objects - javascript

I'm attempting to locally store an object within an array within an object.
If I try the following in my console it works perfectly:
theObject = {}
theObject.theArray = []
arrayObj = {"One":"111"}
theObject.theArray.push(arrayObj)
However if I do what I think is the equivalent, except storing the result in localStorage it fails:
localStorage.localObj = {}
localStorage.localObj.localArray = []
stringArrayObj = JSON.stringify(arrayObj)
localStorage.localObj.localArray.push(stringArrayObj)
I get the following error...
localStorage.localObj.localArray.push(stringArrayObj)
TypeError
arguments: Array[2]
message: "—"
stack: "—"
type: "non_object_property_call"
__proto__: Error
Any idea how I can get this to work?
Cheers

You can only store strings in localStorage. You need to JSON-encode the object then store the resulting string in localStorage. When your application starts up, JSON-decode the value you saved in localStorage.
localObj = {}
localObj.localArray = []
localObj.localArray.push(arrayObj)
localStorage.localObj = JSON.stringify(localObj);
...
localObj = JSON.parse(localStorage.localObj);

LocalStorage can store only key-value pairs where key is string and value is string too.
You can serialize your whole object hierarchy into JSON and save that as localStorage item.
According to V8 sources (I assume you using Google Chrome but hope this isn't different for other JS engines) TypeError with message 'non_object_property_call' occurs than method called on undefined or null value.

Related

sessionStorage not storing original object

I have an object which I'm getting by executing a function of SDK. When I try to store the object in session storage and the retrieve the object, the retrieved object looks same as original but when I perform operations on the new object I'm getting error.
var xyzObject = some_function();
sessionStorage.setItem("xyzObject",xyzObject);
var obj = JSON.parse(sessionStorage.getItem("xyzObject"));
obj.some_other_function();
It is showing an error as obj.some_other_function is not a function. Whereas xyzObject.some_other_function works perfectly.
Try
sessionStorage.setItem('xyzObject', JSON.stringify(xyzObject);
And retrieve using:
JSON.parse(sessionStorage.getItem('xyzObject'));
You cannot store an object in the sessionStorage or localStorage. The only possible method is to stringify the object and save that in sessionStorage and on receiving the object from sessionStorage you just parse the object to JSON.
var xyzObject = some_function();
sessionStorage.setItem("xyzObject",JSON.stringify(xyzObject));
var stringData = sessionStorage.getItem("xyzObject");
var obj = JSON.parse(stringData);
obj.some_other_function();
sessionStorage only stores strings as values.
If you want to store an object in sessionStorage, you must stringify the object into a JSON string, using the JSON.stringify() method.
const xyzObject = { name: "Juan" };
sessionStorage.setItem("xyzObject", JSON.stringify(xyzObject);
Then if you want to read the JSON string stored, you must parse it into a JavaScript object (or value, array, etc) , using the JSON.parse() method.
const xyzObjectRetrieved = JSON.parse(sessionStorage.get("xyzObject"));
// it should equal { name: "Juan" }
Source:
sessionStorage
JSON.stringify
JSON.parse

How do I attach JSON Stringify to a javascript variable

I have a variable :
var testData;
And I have a function that populates an array. Goes through an array and makes another array like so :
var person = {
"Name": obj.Name,
"Age": obj.Age,
}
partsObject.push(person);
I then want to make this array into JSON so I can use it with my D3 objects, so I do this :
testData = JSON.stringify(partsObject);
I can console log this variable, but when trying to go through it via D3's forEach method like so :
testData.forEach(function(d) // data is the JSON
{
I get the error Uncaught TypeError: testData.forEach is not a function
I don't understand how I can log the variable to the console yet it's as if I can't use it as JSON. Any ideas ?
As the name suggests stringify() converts a JavaScript object (the JSO in JSON) into a string of JSON. You can console.log() it because console.log expects to take a string, and anything that's not a string is converted to one to be displayed.
If you want to use it as an array again, you need to parse your string of JSON back to the JavaScript object: JSON.parse(testData).
You really dont need to stringify your Array to pass to d3. Do not to get confused with javascript objects, since forEach requires an array to loop through and you are passing a string to manipulate with forEach function
use:
partsObject.forEach(function(d)
{
...
JSON.stringify(partsObject); creates a string as"{'Name':'ABC','Age':23}"
Uncaught TypeError: testData.forEach is not a function caused because javascript was not able to find an Array
.stringify() turns a Javascript Object into a string. You would want to either run
partsObjects.forEach()
or alternativily you could turn the stringify'ed string back into an object with
(JSON.parse(testData)).forEach()
You are currently trying to loop through a String since you stringify your array.
Just do partsObject.forEach and don't stringify your Array.

Splice on copied array removes object from parent / master array

I have what you may call a parent array, a master array. On page load, a json_encoded PHP array containing information about every user on the site is assigned to a JS variable - var all_users = <?php echo $users;?>;. A console.log of this array looks like this...
[Object, Object, Object, Object, Object, Object, Object, Object, Object]
0: Object
user_id: "4"
registered: "2015-02-15 12:54:34"
...etc
1: Object
user_id: "5"
...etc
In an external .js file I have a few event handlers for various filtering options. At the moment these filters work by sending an AJAX request to the server, querying the database, and then returning the data. This is great, but it's unnecessary to query the database every single time (there will only be around 50 records) hence changing my approach to the JS array.
My solution therefore was to start by copying the contents of all_users to a new variable, display_users, every time the function below is called (so that to reset display_users to contain all users). The purpose of this new variable is to then be able to remove any records that do not match the user's filters. So for example a search for user_id = 4 would result in the second, third, fourth, ... objects being removed from display_users, leaving just those that match.
var display_users = [];
function update_users (type) {
display_users = all_users;
i = 0;
$.each(all_users, function() {
var user = this;
$.each(user, function(k, v) {
// show_admin_only is true or false
if (show_admin_only) {
// if the key is_admin has a value of 0 they are not an admin, remove them from the display users array
if (k == 'is_admin' && v == 0) display_users.splice(i,1);
}
});
i++;
});
// pass the array through to a jQuery template
}
The problem, however, is that the splice is causing an error. The first time the function is ran all is great, however on the second time Chrome reports two warnings, 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead. and 'webkitIndexedDB' is deprecated. Please use 'indexedDB' instead.. After these errors, any future runs of that function results in the removal of records from both arrays, the master and the copy.
Given this, I'd guess that display_users is acting as a pointer to the master array, all_users, but then that wouldn't make much sense to me, and is why I'm now at a complete loss. A console.log of both arrays after i = 0 outputs this...
Run 1
[Object, Object, Object, Object, Object, Object, Object, Object, Object]
[Object, Object, Object, Object, Object, Object, Object, Object, Object]
Run 2
[Object, Object, Object, Object, Object, Object, Object, Object]
[Object, Object, Object, Object, Object, Object, Object, Object]
// for every run, -1 Object from BOTH arrays
I added a console.log(user); within $.each(user, function(k, v) { and it is during these second, third, ... runs that it begins to output hundreds of Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…} as well as those expected, such as Object {user_id: "4", registered_date: "2015-02-15 12:54:34" ... }.
Has anyone any idea why this is happening? Sorry for the long post for what is probably a very simple fix...!
For duplication use:
display_users = all_users.slice();
Your problem is right here
display_users = all_users;
It is not copying the array but creating one more reference to the same array. If you wish to copy the array you ca use Array.slice() instead
var display_users = all_users.slice(0);

Why does push not work on this cookie array?

This works fine:
$cookies.animals = []
$cookies.animals.push({cat: 'meow'})
console.log($cookies.animals) -> [Object]
But identical code inside a factory function doesn't work:
addAnimal: function(id, name, price){
console.log($cookies.animals) //-> [object Object]
$cookies.animals.push({cat: 'meow'}) //-> TypeError: undefined is not a function
}
So why am I getting a TypeError?
If I do this
addAnimal: function(id, name, price){
$cookies.animals = []
console.log($cookies.animals) //-> []
$cookies.animals.push({cat: 'meow'}) //-> works
}
It works (though of course it resets the array) so some something weird is happening to $cookies.animals.
If we look at my console.log inside the factory function:
We get this:
[object Object]
Object with a capital O is my cat, but that weird object is doing something evil I think. Where does it even come from?
Really don't know what's going on to be quite honest. Help please. All I'm trying to do is append to an array...
Per the AngularJS $cookie documentation:
Only a simple Object is exposed and by adding or removing properties to/from this object, new cookies are created/deleted at the end of current $eval. The object's properties can only be strings.
Your initial code works because you can, at any time, set any type of property on any object. Angular does not hold onto your non-string values, though, so your animals property is no longer set in the latter use context. You'll have to serialize and deserialize (probably via JSON) when writing and reading (respectively).
So you'll need to do something like this to initialize the cookie:
var animals = [];
animals.push('Furry Cat');
$cookies.animals = JSON.stringify(animals);
Later when reading, you'd need to do this:
var animal_cookie_value = $cookies.animals,
animals = animal_cookie_value ? JSON.parse(animal_cookie_value) : [];
As for your added remark of:
Object with a capital O is my cat, but that weird object is doing something evil I think. Where does it even come from?
When you see
object Object
in JavaScript you are seeing the output of the default toString() method on JavaScript objects. In other words, you used an object in context of a string, so JS cast it to string (which results in the value you're questioning).
FWIW, I develop a JavaScript cookie library which allows you to pass in any data and it handles the serialization for you. It is currently hosted on Google code, but I am working on moving it to GitHub and hope to add an AngularJS module for it someday.

Javascript array object fails throwing "object error" in IE

I have a javascript array object like
{arr = {"0":{"name":"henry","role":"user"},"1":{"name":"mark","role":"admin"}}
I have a html which requests this array from my server( by including a script tag with url to my server function that serves this array}
The problem is that When I run my HTML file in firefox, it easily detects this array and does the further processing with it but On IE , when I try to access the elements of the array, it throws an exception (object is null or undefined).
Any idea why element detection could be failing in IE.
How do we find out the properties of an array object in IE?
That is not really an array, is simply an object literal with numeric properties, you should iterate it by using the for...in statement:
var arr = {"0":{"name":"henry","role":"user"},
"1":{"name":"mark","role":"admin"}};
for (var key in arr) {
if (arr.hasOwnProperty(key)) {
// value = arr[key];
}
}
But I think you should simply return a real Array:
var arr = [{"name":"henry","role":"user"},
{"name":"mark","role":"admin"}];

Categories