javascript undefined error, but alert toSource shows the object exists - javascript

I grabbed a bit of code to do some paging with jQuery, via Luca Matteis here
Paging Through Records Using jQuery
I've made some edits to the paging script so that I can use the same code to provide paging of different content in different locations on the same site.
For the most part, I think it works, except that I get a jsonObj is undefined error in firebug.
When I use alert(jsonObj.toSource()), I am shown the variables that I am trying to populate, but at the same time, the script dies because of the error.
I can't figure out why I am getting this conflict of 'undefined' and yet I can easily out put the 'undefined' values in an alert. I can even say alert(jsonObj.name), and it will give me that value, but still launch an jsonObj is undefined error.
Here's the code I'm using
var pagedContent = {
data: null
,holder: null
,currentIndex : 0
,init: function(data, holder) {
this.data = data;
this.holder=holder;
this.show(0); // show last
}
,show: function(index) {
var jsonObj = this.data[index];
if(!jsonObj) {
return;
}
var holdSubset='';
for(i=0;i<=4; i++){
jsonObj=this.data[index+i];
this.currentIndex = index;
if(this.holder=='div#firstList'){
var returnedId = jsonObj.id;
var returnedName = jsonObj.name;
var calcScore=this.data[index+i].score/this.data[0].score*100;
var resultInput="<div ' id='"+returnedId+"'><div class='name'>"+returnedName+"</div><div class='score'><div style='width:"+calcScore+"%;'></div></div>";
}
if(this.holder=='div#secondList'){
var name=jsonObj.name;
var city=jsonObj.city;
var region=jsonObj.state;
var resultInput='<li><div>'+name+'</div<div>'+city+'</div><div>'+region+'</div></li>';
}
holdSubset= holdSubset+resultInput;
}
jQuery(this.holder).html('<br/>'+holdSubset);
if(index!=0){
var previous = jQuery("<a>").attr("href","#").click(this.previousHandler).text("< previous");
jQuery(this.holder).append(previous);
}
if(index+i<this.data.length){
var next = jQuery("<a style='float:right;'>").attr("href","#").click(this.nextHandler).text("next >");
jQuery(this.holder).append(next);
}
}
,nextHandler: function() {
pagedContent.show(pagedContent.currentIndex + 5);
return false;
}
,previousHandler: function() {
pagedContent.show(pagedContent.currentIndex - 5);
return false
}
};
I call the function like this
pagedContent.init(json.users.locations, 'div#secondList');
The json looks like this
{"locations" : [ {"id":"21319","name":"Naugatuck American Legion","city":"Ansonia","region":"Connecticut"},{"id":"26614","name":"Studio B789","city":"Acton","region":"Maine"},{"id":"26674","name":"Deering Grange Hall","city":"Bailey Island","region":"Maine"},{"id":"27554","name":"Accu Billiards","city":"Acushnet","region":"Massachusetts"}]}

I may have found the problem with your code:
for(i=0;i<=4; i++){
jsonObj=this.data[index+i];
(...)
When you call show(0) you set index to 0. You expect a fixed number of items in the array (5 in the range [0..4]) but there are only 4 locations in your data.

If you are using console.log to trace the problems in firebug you might find that it is a problem with firebug. Try just running console.log on it's own.
If it is a problem with firebug try updating it. There are some development versions around which might fix the problem.
I had a similar problem and fixed it by doing the above.

Related

Getting this error Uncaught RangeError: Maximum call stack size exceeded

I am getting this error while uploading the CSV files in my website.
Screenshot attached below.
I can see my data of csv file while debugging but it is stopping me to proceed further but i am not able to get this error, I have searched that on google to but they are not relevant to this.
I am using the library
https://d3js.org/d3-dsv.v1.min.js
The code I am trying to upload file is below.
function file(event){
var uploadFileEl = document.getElementById('upload');
if(uploadFileEl.files.length > 0){
var reader = new FileReader();
reader.onload = function(e) {
fileProcess(reader.result.split(/\[\r\n\]+/));
}
reader.readAsText(uploadFileEl.files\[0\]);
}
}
function fileProcess(data) {
var lines = data;
//Set up the data arrays
var time = \[\];
var data1 = \[\];
var data2 = \[\];
var data3 = \[\];
var headings = lines\[0\].split(','); // Splice up the first row to get the headings
var headerCheckbox = document.getElementById('includeHeader');
if(headerCheckbox.checked == true){
for (var j=1; j<lines.length; j++) {
var values = lines\[j\].split(','); // Split up the comma seperated values
// We read the key,1st, 2nd and 3rd rows
time.push(values\[0\]); // Read in as string
// Recommended to read in as float, since we'll be doing some operations on this later.
if (values\[0\] =="" || values\[0\] == null )
{
delete values\[0\];
delete values\[1\];
delete values\[2\];
delete values\[3\];
}
else{
data1.push(parseFloat(values\[1\]));
data2.push(parseFloat(values\[2\]));
data3.push(parseFloat(values\[3\]));
}
}
The error I am getting is on this line
fileProcess(reader.result.split(/[\r\n]+/));
What could be the reason for this.
That error means that you are filling the call stack.
If you call a function that returns a function recursively and doesn't have a stop condition or it never fulfils it's stop condition that error will be throwed.
It appears that fileProcess(reader.result.split(/[\r\n]+/)) it's being called recursively and it's filling the call stack.
Don't know exactly where, as I don't see any recursive calls in the code you posted, so I can't help you farer, but I hope this can shed light into your problem.
P.S: If you think there's some relevant extra code that you didn't post and edit your question leave me a comment and I'll update my answer aswell.

Check for duplicate record in Chrome Storage extension before saving

I'm developing a small Chrome extension that would allow me to save some records to chrome.storage and then display them.
I've managed to make the set and get process work as I wanted (kinda), but now I'd like to add a duplicate check before saving any record, and I'm quite stuck trying to find a nice and clean solution.
That's what I came up for now:
var storage = chrome.storage.sync;
function saveRecord(record) {
var duplicate = false;
var recordName = record.name;
storage.get('records', function(data) {
var records = data.records;
console.log('im here');
for (var i = 0; i < records.length; i++) {
var Record = records[i];
if (Record.name === recordName) {
duplicate = true;
break;
} else {
console.log(record);
}
}
if (duplicate) {
console.log('this record is already there!');
} else {
arrayWithRecords.push(record);
storage.set({ bands: arrayWithRecords }, function() {
console.log('saved ' + record.name);
});
}
});
}
I'm basically iterating on the array containing the records and checking if the name property already exists. The problem is it breaks basic set and get functionality -- in fact, when saving it correctly logs 'im here' and the relative record object, but it doesn't set the value. Plus, after a while (generally after trying to list the bands with a basic storage.get function) it returns this error:
Error in response to storage.get: TypeError: Cannot read property
'name' of null
I'm guessing this is due to the async nature of the set and get and my incompetence working with it, but I can't get my head around it in order to find a better alternative. Ideas?
Thanks in advance.

.gBrowser is undefined

I'm writing a restartless Firefoxextension where I have to enumerate all open tabs and work with them.
Here's the code-part that throws the error:
getInfoString : function ()
{
infos = "";
HELPER.alerting("url", "URL-Function");
var winMediator = Components.classes["#mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
HELPER.alerting("url", "Mediator initialized");
var mrw = winMediator.getEnumerator(null);
while(mrw.hasMoreElements())
{
var win = mrw.getNext();
var t = win.gBrowser.browsers.length;
HELPER.alerting("url", "browsers: " + t);
for (var i = 0; i < t; i++)
{
var b = win.gBrowser.getBrowserAtIndex(i);
if(b.currentURI.spec.substr(0,3) != "http")
{
continue;
}
HELPER.alerting(b.title,b.currentURI.spec);
var doc = b.contentDocument;
var src = doc.documentElement.innerHTML;
infos = infos + src
HELPER.alerting("doc", src);
}
}
return infos;
}
I have a JavascriptDebugger-Addon running while testing this and Firefox executes everything fine to the line
HELPER.alerting("url", "browsers: " + t);
But AFTER this line, the debugger-addons throws an error, saying that:
win.gBrowser is undefined
... pointing to the line:
var t = win.gBrowser.browsers.length;
But before it throws the error I get my alertmessage which gives me the correct number of tabs. So the error is thrown after the line was executed and not directly WHEN it was executed.
Does anyone has an idea how to fix this, because the extension stops working after the error has been thrown.
Greetz
P.S.: If someone has a better headline for this, feel free to edit it.
Using winMediator.getEnumerator(null) would give you all types of window, that may or may not be browser windows. You should try changing the following line
var mrw = winMediator.getEnumerator(null);
with
var mrw = winMediator.getEnumerator('navigator:browser');
I finally figured out that this behavior can happen sometimes.
I just rearranged the code a bit, removing some alerts inside the for-loop and it works just fine again.
So if someone has this error too, just rearrange your code and it should work like a charm again.

Loop through JSON array in jquery

I have an external JSON file that has this in it:
{
"Home": [
{ "link":"index.php" , "text":"Home" },
{ "link":"index.php?page=aboutus" , "text":"About Us" }
]
"Games": [
{ "link":"games.php" , "text":"All Games" },
{ "link":"games.php?name=game" , "text":"Game" }
]
}
That is the basic setup of my JSON file. I plan on adding more as my site expands. I am using that as part of my menu bar setup. It has 3 buttons, Home, Games, and Forum. When you mouse over the Home button I want to turn the stuff in "Home" into links and show it up on my site, same with the Games button, nothing is going to show up when you mouse over the Forum button. I have tried this:
Edit: changed the function slightly again, trying to keep it from calling the server on each mouse over, as well as loop through them all and show them in the .navDD div tag.
$(document).ready(function(){
var menu
$.getJSON('menu.json', function(data) {
menu = data;
});
$(".navlink").mouseenter(function(){
var find=$(this).text();
$.each(data,function(index){
$(".navDD").html(menu[find][index]['text']);
});
});
});
I am sure I mess something up still. Now I getUncaught TypeError: Cannot read property 'length' of undefined. I am not sure at all what I am doing wrong. Though I have never worked with JSON before this.
Could someone please help me?
Thanks,
Legobear154
You could try doing it this way:
$(".navlink").mouseenter(function(){
var find=$(this).text;
$.getJSON('menu.json', function(data) {
$(".navDD").html(data[find][0].text);
});
});
Access a property via it's name. This is assuming that the text value you are using matches the JSON property of your object.
I would also suggest not doing the $.getJSON() on every mouse enter. That is a lot of server traffic. Users could be "mouse entering" hundreds of times.
Are you sure that this is correct?
var find=$(this).text;
I'd do:
var find=$(this).text();
And then
$.getJSON('menu.json', function(data) {
$(".navDD").html(data.[find][0].text);
});
There is no find property in your object, so that's giving you undefined. You're then trying to read the 0th index of this undefined property, which is giving you the error.
If you want to access the the text property of the 0th element in the home object, you would say data.home[0].text
for (var key in data) {
if (key == 'Home'){
$(".navDD").html(data[key]['text']);
}
}
you should also make sure that you are working with an object when using for loops. That might be where your 'undefined' error is coming from.
if (typeof data === 'object'){
for (var key in data) {
if (key == 'Home'){
$(".navDD").html(data[key]['text']);
}
}
}
You are using var find=$(this).text to get the content of the element, you need to use var find=$(this).text() to call the text method.
You are using data.find[0].text to get a value from the object, you need to use menuData[find][0].text.
You should not request the JSON file every time the mouseenter event happens, you should only request it the first time, then hold on to it.
$(document).ready(function(){
var menuData = null;
$(".navlink").mouseenter(function(){
var find = $(this).text();
if (menuData != null) {
$(".navDD").text(menuData[find][0].text);
} else {
$.getJSON('menu.json', function(data) {
menuData = data;
$(".navDD").text(menuData[find][0].text);
});
}
});
});

Passing result from .getJSON() to another function results in undefined

Good day everyone,
I am pulling back some data from a database (via a PHP script) using jQuery's .getJSON() method. This is all well and good, the data comes back just fine and as expected. The problem occurs when I try to pass the data to a secondary function, no matter how I try to access the values of that data they come back as undefined. I have a feeling I am overlooking something very simple but after a lot of trial and error I come to SO asking for an extra set of eyes.
Here is a simple example of the JavaScript code.
function fnCheck_Vis(Row, sField, sMode)
{
sField = sField+"_vis";
sTest = Row.sField.val();
alert(sTest); // Comes back as undefined.
}
$(document).ready(function()
{
$("#btnSearch").click(function()
{
$("#divResults").empty();
var ssearch = $("#ssearch").val();
var i = 0;
$.getJSON("get_results.php?keywords=" + ssearch,
function(Data)
{
var iRec = 0;
$.each(Data, function(i, Row)
{
fnCheck_Vis(Row, "slinkpic1", "Int");
var content = Row.slast;
$("#divResults").append(content);
iRec++;
});
alert(iRec + " records retrieved using AJAX.");
});
});
});
The first piece of the fnCheck_Vis() function works fine and "_vis" is appended to the field name, this is proper behavior. No matter how I try to access that member in the dataset (Row) I can not get a value back.
I really appreciate any insight that can be given on this issue.
Thanks,
Nicholas
It looks like you want to access the property of Row whose name is stored in sField, not its actual sField property. Try:
function fnCheck_Vis(Row, sField, sMode)
{
sField = sField + "_vis";
var sTest = Row[sField];
alert(sTest);
}

Categories