2

I'm trying to persist an observable array to localStorage. To do this I'm using ko.toJSON.

var that = this;
this.items = ko.observableArray();
this.items.subscribe(function(){
    localStorage.setItem("items", ko.toJSON(that.items()));
});

All that gets persisted to localStorage is false.

It throws a very random looking error: knockout-3.4.2.js:55 Uncaught DOMException: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules.

Any idea what's going on here?

I get the error as well with a simple var json = ko.toJSON(that.items()); so it clearly comes from that. However, I do not get that error when simply doing this: var json = ko.toJSON([{'key': 'value'}]);.

UPDATE: Here's the full error message:

Uncaught DOMException: Failed to read the 'cssRules' property from 
'CSSStyleSheet': Cannot access rules
at http://localhost:8080/js/knockout-3.4.2.js:55:405
at c (http://localhost:8080/js/knockout-3.4.2.js:56:172)
at b (http://localhost:8080/js/knockout-3.4.2.js:55:380)
at http://localhost:8080/js/knockout-3.4.2.js:56:23
at c (http://localhost:8080/js/knockout-3.4.2.js:56:172)
at b (http://localhost:8080/js/knockout-3.4.2.js:55:380)
at http://localhost:8080/js/knockout-3.4.2.js:56:23
at c (http://localhost:8080/js/knockout-3.4.2.js:56:172)
at b (http://localhost:8080/js/knockout-3.4.2.js:55:380)
at http://localhost:8080/js/knockout-3.4.2.js:56:23

UPDATE2: Here's the actual section of code where the problem lies:

This is the exact context of the problem:

    this.savedPlaces.subscribe(function() {
    // Add all places to filteredPlaces
    that.filterPlaces();
    // Reinitialize the filter
    that.filterString("");
    // Update the markers
    that.updateMarkers();
    // Store itself in localStorage
    localStorage.setItem("savedPlaces", ko.toJSON(that.savedPlaces()));
});

When I comment out that last line, I get no issue.

I also get no issue if I replace it with: localStorage.setItem("savedPlaces", ko.toJSON([{item: "item"}]));

I tried to give an example of content for items but apparently observableArrays are deep (recursive) objects, making it impossible for me to copy paste for the DevTools console on Chrome. However it looks something like:

[{'marker': a_google_maps_marker_object,
  'place': {data: mostly strings...}]
  • Is `items` also bound to the view? I can't imagine `ko.toJSON` being the cause of this error... – user3297291 Mar 11 '18 at 20:39
  • The code looks fine so far. Is `cssRules` a property in each `item` in the array? What is `CSSStyleSheet`? Can you show more of the relevant code? – Joe Wilson Mar 11 '18 at 23:10
  • Actually apparently I don't use `items` in the view so I guess I could actually simply store it as a regular array, which would likely solve my problem! But I still don't understand why I get that issue! cssRules and CSSStyleSheet have nothing to do with my code... I'll update the original post to include the full error. – Antoine Guenet Mar 12 '18 at 22:09
  • Second earlier comments. The problem is going to be in code that we can't see in this question. Please try to create an [mcve] from your actual codebase, if possible. – Jeroen Mar 12 '18 at 22:19
  • Thing is I just don't see what else could be relevant. I'll edit the post again, trying to include more details. – Antoine Guenet Mar 12 '18 at 22:40
  • Ok I got the issue. Still don't understand why it throws that specific error but I at least get why it throws _an_ error... My observable array is recursive so it can't convert it to json (I tried with making it a regular array then using `JSON.stringify` on it and that didn't work either). It comes from the Google Maps marker object that I store in it. So I'll try to fix my Array so it can be converted properly. If that works I'll post it as an answer. – Antoine Guenet Mar 13 '18 at 00:10

1 Answers1

3

I found the issue. My observable array contained a Google Maps marker. These are recursive arrays, which cannot be JSONified.

I removed the Google Maps marker from my array and everything was fine.

Still strange though that Knockout throws this cryptic error.