Problems with multidimensional array and loops - javascript

This script crashes randomly with the message "unable to get property .length of undefined or null reference" referring to "matched_array_pics.length". It crashes for sure if I clone, append the same image twice to the #train div.
$(document).ready(function () {
var starting_pics = ["AN.gif", "CN.gif", "EN.gif", "GN.gif"];
var an_array_pics = ["CN.gif", "EN.gif", "GN.gif", "AN.gif"];
var cn_array_pics = ["EN.gif", "GN.gif", "AN.gif", "CN.gif"];
var en_array_pics = ["GN.gif", "AN.gif", "CN.gif", "EN.gif"];
var gn_array_pics = ["AN.gif", "CN.gif", "EN.gif", "GN.gif"];
var grand_array_pics = [an_array_pics, cn_array_pics, en_array_pics, gn_array_pics];
var i = 0;
for (i = 0; i < starting_pics.length; i++) {
$("<img/>").attr("src", "images/" + starting_pics[i]).load(function () {
$(this).appendTo("#main");
$(this).addClass("pics");
});
}
$("#main").on("click", ".pics", function () {
var j = $(".pics").index(this); // gets the index for the matched_array_pics...
console.log(j);
$("#sidebar .pics").remove();
$(this).clone().appendTo("#train");
$(this).clone().appendTo("#sidebar");
$("#main .pics").remove();
var matched_array_pics = grand_array_pics[j]; // ... in grand_array_pics.
var k = 0;
for (k = 0; k < matched_array_pics.length; k++) {
$("<img/>").attr("src", "images/" + matched_array_pics[k]).load(function () {
$(this).appendTo("#main");
$(this).addClass("pics");
});
}
});
}); //end ready

I think the problem is in this line: var j = $(".pics").index(this); and I think it should be rewritten like this: var j = $(this).index(); It'd be helpful if you could add console.log(j); just after the line in question to see what j ends up being. When this line executes var matched_array_pics = grand_array_pics[j]; I think you're getting undefined because j is not a number when your code runs.

Related

Having Trouble Parsing Results of Array

I'm having a bit of trouble trying to parse the results of an array and print to the console. It's a two part problem actually. When I build the array it's adding "undefined" to the results. When I try to loop through the individual strings in the array it isn't parsing, just returning the full array object.
What I'm trying to do is collect all the field values selected from a list view and write them to another child list as separate items. When displaying results in a console it shows as an object array. When I run the typeof method against it I believe it shows as a string.
To reiterate, why am I getting undefined and why is my array not printing to console correctly. Below is an example of what is being returned thus far (when two records are selected) and my code.
Results:
undefinedDaffy DuckBugs Bunny
undefined
Code:
// Grabs selected items from getSelected function and passes parameters to writeSelected function
function callAccepted() {
getSelected().done(function(varObjects) {
for (var k in varObjects) {
console.log(varObjects[k]);
}
}); // End getSelected
} // End callAccepted
// Grabs selected items, accepts input from callAccepted or callRejected functions
function getSelected() {
var dfd = $.Deferred(function(){
var ctx = SP.ClientContext.get_current();
var clientContext = new SP.ClientContext();
var targetList = clientContext.get_web().get_lists().getByTitle(ListName);
var SelectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
var items = [];
var arrItems = [];
for (var i in SelectedItems) {
var id = SelectedItems[i].id;
var item = targetList.getItemById(id);
clientContext.load(item, "Title");
items.push(item);
} // End for
clientContext.executeQueryAsync(
function(){ // Return to button click function
var itemLength = 0;
var itemObjects = [];
for (var j = 0; j < items.length; j++) {
itemObjects = items[j].get_item("Title");
itemLength += itemObjects;
arrItems.push(itemObjects);
}
dfd.resolve(arrItems, itemLength);
},
function(){ // Return to button click function
dfd.reject(args.get_message());
}
); // End ClientContext
}); // End dfd
return dfd.promise();
} // End getSelected
Why are you writing "var itemObjects;" in 1 line and add one string "itemObjects += items[j].get_item("Title");" in another? There'll be only 1 string anyway, so when you change those 2 lines into one, "undefined" should disappear:
function callAccepted() {
getSelected().done(function(varObjects, iLength) {
// Stuff
for (var k = 0; k < iLength; k++) {
console.log(varObjects[k]);
}
}); // End getSelected
} // End callAccepted
// Get user information function
function getSelected() {
var dfd = $.Deferred(function(){
var ctx = SP.ClientContext.get_current();
var clientContext = new SP.ClientContext();
var targetList = clientContext.get_web().get_lists().getByTitle(ListName);
var SelectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
var items = [];
var arrItems = [];
for (var i in SelectedItems) {
var id = SelectedItems[i].id;
var item = targetList.getItemById(id);
clientContext.load(item, "Title");
items.push(item);
} // End for
clientContext.executeQueryAsync(
function(){ // Return to button click function
for (var j = 0; j < items.length; j++) {
var itemObjects = items[j].get_item("Title");
var itemLength = items.length;
arrItems.push(itemObjects);
}
dfd.resolve(arrItems, itemLength);
},
function(){ // Return to button click function
dfd.reject(args.get_message());
}
); // End ClientContext
}); // End dfd
return dfd.promise();
} // End getSelected
The reason for this is that after creating the variable without any value, it's undefined, so += 'Unicorn' will give us ugly 'UndefinedUnicorn'. If you wish to make variable for this purpose, write it "var x = ''".
And if - for example - you want to sum length of all "items", then this one function should look like:
function(){ // Return to button click function
var itemLength = 0;
for (var j = 0; j < items.length; j++) {
var itemObjects = items[j].get_item("Title");
itemLength += itemObjects;
arrItems.push(itemObjects);
}
dfd.resolve(arrItems, itemLength);
}
But I'm not exactly sure what are you trying to get here.

Closure function is appending all index from loop

I am trying to append index value to element using the loop. i made a closure to avoid the multiple index appended.
but my closure function still adding the multiple(previous) index to dom
var $newdiv = $('.div').clone().removeClass('div').addClass('show')
$col = $('<div />');
var add = function () {
for(var i=1; i<=10; i++){
(function x (n) {
return function () { //not working!
$newdiv.find($('a span').append(n)).end().clone().appendTo($col);
}();
}(i));
}
}
$col.appendTo('#content');
$('button').click(function () { add()});
$('#content').slimScroll({});
Live
I updated my code like this. it works fine.
var $newdiv = $('.div').clone().removeClass('div').addClass('show')
$col = $('<div />');
var n = 0;
var add = function () {
for(var i=1; i<=10; i++){
$newdiv.clone().removeClass('div').addClass('show')
.find('span').append(n = n < 9 ? '0'+(++n) : ++n).end().clone().appendTo($col);
}
}
$col.appendTo('#content');
$('button').click(function () { add()});
$('#content').slimScroll({});

Javascript adding 2nd dimension not returning results

I have a site made as shown in this jsfiddle:
http://jsfiddle.net/bAz3y/
$.getJSON('eventbrite.json', function(data) {
var events = [];
var j = 0;
for (var i in data) {
events[i][0] = data[i].event.title;
}
$('.btn-lg').click(function() {
$('#tester').replaceWith("<div id='tester'>" + events[j][0] + "</div>");
j = j + 1;
})
$("div.swiper").on("swipe",function() {
$('#tester').replaceWith("<div id='tester'>" + events[j][0] + "</div>");
j = j + 1;
})
});
I'm trying to get the 2nd dimension to store the event title, so that I can then add event date and distance in events[j][1] and events[j][2].
However, adding the second dimension (ie the events[i][0]) means no results are returned.
The problem is the for loop, events[i] is undefined so events[i][0] will fail
1.Solution is
for (var i in data) {
events[i] = [data[i].event.title, data[i].event.some];
}
2.Another is to use $.each() and do
var events = [];
var j = 0;
$.each(data, function(_,item){
events.push([item.event.title, data[i].event.some])
});
3.A third way is to use $.map()
var j = 0;
var events = $.map(data, function (item) {
return [[item.event.title, data[i].event.some]]
});

Find index in array different from the array that loaded

Line 35, just before the alert, returns -1. I also tried $(this).index() with the same result. Here is what it should do: Clicking EN.gif should return 4, then grand_array_pics[4] should give me en_array_pics and load the .gifs in that array.
$(document).ready(function () {
var main_pics = ["AN.gif", "BN.gif", "CN.gif", "DN.gif", "EN.gif", "GN.gif"];
var starting_pics = ["AN.gif", "CN.gif", "EN.gif"];
var an_array_pics = ["BN.gif", "EN.gif", "GN.gif", "AN.gif","DN.gif"];
var bn_array_pics = ["CN.gif", "DN.gif", "GN.gif"];
var cn_array_pics = ["DN.gif", "GN.gif", "AN.gif", "CN.gif"];
var dn_array_pics = ["EN.gif", "AN.gif", "CN.gif"];
var en_array_pics = ["GN.gif", "AN.gif", "CN.gif", "EN.gif"];
var gn_array_pics = ["AN.gif", "CN.gif", "EN.gif", "GN.gif"];
var grand_array_pics = [
an_array_pics,
bn_array_pics,
cn_array_pics,
dn_array_pics,
en_array_pics,
gn_array_pics
];
var i = 0;
for (i = 0; i < starting_pics.length; i++) {
$("<img/>").attr("src", "images/" + starting_pics[i]).load(function () {
$(this).appendTo("#main");
$(this).addClass("pics");
});
}
$("#main").on("click", ".pics", function () {
var j = $.inArray(this, main_pics);
alert(j);
$("#sidebar .pics").remove();
$(this).clone().appendTo("#train");
$(this).clone().appendTo("#sidebar");
$("#main .pics").remove();
var chosen_pics_array = grand_array_pics[j];
var count = chosen_pics_array.length;
var k = 0;
for (k = 0; k < count; k++) {
$("<img/>").attr("src", "images/" + chosen_pics_array[k]).load(function () {
$(this).appendTo("#main");
$(this).addClass("pics");
});
}
});
}); //end ready
this is the DOM <img> element, while main_pics is an array of strings. It will never be found inside there. Use
var j = $.inArray(this.src.split("/").pop(), main_pics);
Give this a try. You need to get the name of the file and you're passing the element itself into $.inArray
var j = $.inArray(this.src.substring(this.src.lastIndexOf('/')+1), main_pics);

Cannot set property '0' of 2D array

Can anyone tell me why I'm getting this error for the code below:
Uncaught TypeError: Cannot set property '0' of undefined
var vehicles = [];
$.get('../poll/index.php?data=vehicles', function(data) {
var rows = $(data).find('row').length;
for (var i = 0; i < rows; i++) {
vehicles[i][0] = $(data).find('row').eq(i).find('stage').text();
vehicles[i][1] = $(data).find('row').eq(i).find('direction').text();
vehicles[i][2] = $(data).find('row').eq(i).find('stageName').text();
vehicles[i][3] = $(data).find('row').eq(i).find('atco').text();
vehicles[i][4] = $(data).find('row').eq(i).find('service').text();
vehicles[i][5] = $(data).find('row').eq(i).find('journey').text();
vehicles[i][6] = $(data).find('row').eq(i).find('fleet').text();
vehicles[i][7] = $(data).find('row').eq(i).find('longitude').text();
vehicles[i][8] = $(data).find('row').eq(i).find('latitude').text();
vehicles[i][9] = $(data).find('row').eq(i).find('operator').text();
vehicles[i][10] = $(data).find('row').eq(i).find('position').text();
}
}, 'xml');
You need to define each child array, e.g.
var vehicles = []; // parent array;
vehicles[0] = []; // first child array;
so you would need:
for (var i = 0; i < rows; i++) {
var vehicles[i] = [];
... rest of code here ...
}
vehicles[i] has no value assigned to it.
Add a line:
vehicles[i] = [];
at the top of the loop.

Categories

Resources