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...}]
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.
Related
Lately we have been getting a lot of javascript errors "can't redefine non-configurable property "userAgent"".
We don't attempt to redefine userAgent in our code. We barely even reference userAgent. The only places would be in code like the following:
var browser_msie = (navigator.userAgent.match(/msie/i) || navigator.userAgent.match(/trident/i)) ? true : false;
I am wondering if this error is rather coming from some bad browser behavior. It only started showing up recently.
Last evening we got over 20,000 of such error messages, and all from the same member of our service.
EDIT
The error information is as follows:
Error Message:
Message: TypeError: can't redefine non-configurable property "userAgent"
URL: https://www.rephunter.net/member-home.php
Line:1
Column:130
Stack:#https://www.rephunter.net/member-home.php:1:130
Error Traceback:
#0 Called backtrace in file /var/www/rephunter/www/webroot/include/error-handler-inc.php as line #68
#1 Called error_handler in file as line #
#2 Called trigger_error in file /var/www/rephunter/www/webroot/ajax/javascript-error.php as line #14
Unfortunately this offers no help, as line 1 of the page is just <!DOCTYPE html>. I don't see how to get to that part of the code. Of course if that were possible it might be easy to see the cause of the issue.
I recall in the past the Dev Tools might have given a "spiders view" of the page, but now I only see the DOM on the Elements tab, and Sources. Both of these are formatted and their is no way to see what "line 1 char 130" means.
I have just spent far too long trying to find a problem with the code below.
In turned out that because of the context that addRoute was called in, keys() was not returning the keys of the results object. To fix this I had to use Object.keys() despite it working without a problem in the JavaScript console (which I later realised was because of the context).
My question is, why didn't this show in my JavaScript console? It took me quite a while to realise (I have cropped the full code, the actual function is a lot bigger).
Wrong, but no error in the console:
Map.prototype.addRoute = function (results) {
var sectionsIDs = keys(results);
}
Correct
Map.prototype.addRoute = function (results) {
var sectionsIDs = Object.keys(results);
}
Your first function uses the keys console API function.
That "Command Line API Reference" page includes the warning:
Note: This API is only available from within the console itself. You cannot access the Command Line API from scripts on the page.
Thus, it is by design that the keys function only exists for code run directly on the console.
Chrome gives you a small hint about the keys function being a console-only function if you view it in the console:
> keys
function keys(object) { [Command Line API] }
Im working on a project to build a CRUD system using knockout and getting and saving my data via AJAX. Been having issues binding the select dropdown. When I try to edit an incident I get the following error:
Uncaught TypeError: Cannot read property 'push' of undefined
I created a jsfiddle http://jsfiddle.net/rqwku4kb/20/ to demonstrate the issue. I'm still working on the delete and add a new incident link so they are not working yet but im working on that seperately.
Here is the code that`s causing me issues at the moment.
self.ShowMeTheCurrentSelectedIncident = function(data) {
self.currentIncident();
self.chosen_composante.push([data.Composante]);
};
Would anyone have have any idea where the issue might be or be able to provide me some advice?
The method here is what's wrong:
self.ShowMeTheCurrentSelectedIncident = function(data) {
self.currentIncident(); // (1)
self.chosen_composante.push([data.Composante]); // (2)
};
What this does:
(1) get the value of the observable currentIncident and then throw it away. It's always null and never set so this is doubly redundant.
(2) Reference an undefined variable called chosen_composante which does not exist in IncidentList.
I could not fix this for you since I wasn't sure what values were to go where, but it should be enough to set you on the right track - you're confusing the properties of the IncidentList and Incident
Downvote people: Note that this question is n̲o̲t̲ about Google Maps API V3. <google-map> is a GoogleWebComponent that displays a map automagically upon declaration in dom.
var map = document.createElement("google-map");
By only executing this line, it throws an error saying:
Uncaught TypeError: latitude must be a number
I don't even get a chance to set the latitude property.
Is this because I'm creating multiple google-maps (in different dom-modules) within the same page? If not, why is this happening and how do I solve this?
Added
Even doing something like this still yields the same error:
var map = document.createElement("span");
map.innerHTML = "<google-map latitude='1'></google-map>";
I have been trying to figure out this particular problem in my developer tools, but I've had no luck thus far. I have an error on one of my js files that says
Uncaught TypeError: Cannot read property 'value' of null
The following error refers to the 1st variable of dt_version below. The particular thing is if I comment out the first line of code. I get the same error on the following variables of offload1 and offload2. The variable is a number that I am trying to get passed over. I run this function on my body when the page loads...onload=updatetotal();
function updatetotal() {
var dt_version = document.getElementById("dt_version").value-0;
var offload1 = document.getElementById("capacity_offload1").value-0;
var offload2 = document.getElementById("capacity_offload2").value-0;
var offload3 = document.getElementById("capacity_offload3").value-0;
}
If a run an if statement looking for document.getElementByID("dt_version");...it defaults to false..so its not being carried over though on the previous page, I can see its input fine with the value in it. What am I missing here guys?
This error means that the id dt_version does not exist. Check your html to make sure it is there:
var dt = document.getElementById("dt_version");
if (dt){
// do your stuff
}else {
console.log("dt does not exist")
}
Another cause for this error may be- as you are calling the javascript function on page load there is a possible chance that your control is not yet completely rendered to the page. A simple solution is just move that control to the beginning of the page. If it doesn't work then an reliable solution is, call the function inside jquery $(document).ready().