views:

232

answers:

2

I just learned about jquery's .makeArray and I am trying to use JSON.stringify to store the array in localStorage but I am having unexpected results.

This works:

var links = {'one': 1, 'two': 2 };
var setstr = JSON.stringify(links);

localStorage.setItem('strlinks', setstr);
var getstr = localStorage.getItem('strlinks');
console.log(getstr); //Returns what's expected - '{"one":1, "two":2}'

This doesn't:

var links = $.makeArray($('a'));

alert(links); //Returns list of links
var setstr = JSON.stringify(links);

localStorage.setItem('strlinks', setstr);
var getstr = localStorage.getItem('strlinks');
console.log(getstr); //Returns '[]'

Any ideas about what I'm doing wrong?

+1  A: 

links contains circular references, so it can't be serialized to JSON. Chrome 5.0.375.99 gives the error:

TypeError: Converting circular structure to JSON

You have to somehow remove these circular references. Of course, it depends what info you care about. Here's a simplified version:

var flatLinks = $.map(links, function(el)
                             {
                              return {href: el.href, text: el.textContent};
                             }); 
var setstr = JSON.stringify(flatLinks);
Matthew Flaschen
A: 

$('a') selects all the links (HTMLAnchorElements) on the page.

Elements are DOM nodes defined by their identity and presence in the document. They are not simple values that JSON can represent. If you look at what JSON.stringify() returns for them, it's just {}: JSON says all it knows about the object is that it's an Object.

It doesn't make any sense to attempt to put a Node inside a localStorage; what do you expect to get back when you read the storage tomorrow? A Node object that was part of a document the user closed and destroyed yesterday?

If you want to remember where the links pointed to, you should get that from their href properties, as a String—a simple value type that can safely be remembered by localStorage.

bobince
Maybe I am barking up the wrong tree but this is for a chrome extension. My thought was to add the array to localStorage from a content script, then when the user clicks the browser icon, loop through the links and display them in a popup. I am new to chrome extensions, but it is my understanding that a popup can't directly access the variables from a content script, thus the need for local storage. But I could be way off the mark.
Jim
A reference to a link cannot be put in a `String`, the only thing `localStorage` will store. But the popup doesn't need to touch the link itself, does it? It only needs to know the URL that the link is pointing to (`href`), surely? That's only a `String`, so can certainly be JSON-stringified. Not that I think you actually need `localStorage` at all. I don't know about Chrome, but most browser extensions should have no trouble opening a new window and populating it with a list of strings, without having to mediate through any kind of `localStorage` database.
bobince
You can use a background page as a controller, and access the stored values from there. See my New Tab Redirect's code for examples (I am using JSON.stringify in trunk's code) http://code.google.com/p/newtabredirect/
Jim Schubert