analyse : function (that) {
var a = new Array();
var x = 0;
$(that).children("li").each(function(){
console.log('test1');
a[x]['name'] = 'f';
a[x]['link'] = 'UUUUUUUUUUU';
console.log('test2');
x++;
})
return a;
}
I'm trying to create an array to store the hierarchy from my menu for PHP later on.
The console won't show me "test2", what did I do wrong?
Transformed into this with Didier G's Help:
analyse : function (that) {
return $(that).children('li').map(function() {
var b = {
name: $(this).children('a').text(),
link: $(this).children('a').attr('href')
};
if ($(this).children('ul').size() > 0) {
b.childs = mcms.module.analyse($(this).children('ul'));
}
return b;
});
}
So if i say var y = analyse('#menu'); I get the whole bunch! ^^
5 Answers 5
'a[x]' is undefined at that moment. You have to first build an object and assign it to 'i' position ('x' is indeed a not standard name for an iterator, thanks @Cito):
var a = new Array();
var i = 0;
$(that).children("li").each(function(){
console.log('test1');
a[i] = { name: 'f', link: 'UUUU' };
console.log('test2');
i++;
});
Note: your code misses a ; after the each(). Even though it is valid javascript to omit semi-colons, it is I think better to explicitly use them to avoid misinterpretations.
Creating array can be achieve by using .map()
var a = [];
// .map() returns a jquery array, to obtain a pure javascript array, you must call .toArray() afterwards
a = $(that).children('li').map(function() {
return { name: 'f', link: 'UUUU' };
}).toArray();
Here's a jsfiddle to illustrate
This article covers a the use of .each() and .map() for building data collections out of lists in jquery.
4 Comments
x is a poor name for an array index, and the each() method already passes an array index to your function so you don't need to maintain your own variable for that. But Didier is right, map() is the better solution anyway.name. BTW, b is unnecessary. Also, these languages are dynamic, so properties can be added at any time using the property accessor syntax as the OP did (provided the object permits it). Your toArray(...) does nothing useful until the return value is assigned to a.a = [] is pointless here. These languages are loosely typed. If you must, write var a = ....toArray();.a is empty, you are trying to set properties to an undefined object. Use this code instead:
var a = [];
$(that).children("li").each(function(x){
console.log('test1');
a[x] = {};
a[x].name = 'f';
a[x].link = 'UUUUUUUUUUU';
console.log('test2');
})
return a;
Even shorter would be this code (inside the callback):
a[x] = {name: 'f', link: 'UUUUUUUUUUU'};
Comments
SOLUTION: I had a similar scenario and was able to come up with a clean solution. I basically had a to make question object with several questions in them with individual properties.
Here was my solution:
$("li").each(function(i,e){
// Build Array
questionOb[i] = {
'questionSeq' : i,
'questionType' : $(this).find(".questionType").attr("rel"),
'questionLabel' : $(this).find(".questionLabel").attr("rel"),
'questionAnswers' : $(this).find(".questionAnswers").attr("rel"),
'questionMinimum' : $(this).find(".questionMinimum").attr("rel"),
'questionMaximum' : $(this).find(".questionMaximum").attr("rel"),
'questionInterval' : $(this).find(".questionInterval").attr("rel"),
};
});
var dataString = {
questionsSet : questionOb
};
This essential makes an array of questions for each "li" it finds. The data ends up looking something like this:
Array
(
[questions] => Array
(
[0] => Array
(
[questionSeq] => 0
[questionType] => email
[questionLabel] => Please enter your question here.
[questionRandom] => no
[questionRequired] => no
)
[1] => Array
(
[questionSeq] => 1
[questionType] => numeric
[questionLabel] => Please enter your question here.
[questionRandom] => no
[questionRequired] => no
)
[2] => Array
(
[questionSeq] => 2
[questionType] => singleselect
[questionLabel] => Please enter your question here.
[questionAnswers] =>
[questionRandom] => no
[questionRequired] => no
)
)
)
Comments
a[x] = {name: 'f', link: 'UUUUUUUUUUU'};
Comments
You have forgotten
a[x] = {};
to make the element at index x (a reference to) an object that can have a properties p to be added with
a[x][p] = ...;
You should not use each(...), it is very inefficient by comparison to a for loop.
1 Comment
.each()or .map() should be used wisely is more correct than you should not use. For large collections (1000+), it's more efficient to use pure javascript, otherwise, the gain is pretty trivial.Explore related questions
See similar questions with these tags.
new Array()but[]a[x]is not defined so you're trying to assign a property 'name' to an undefined variable.new Array()is perfectly fine per the ECMAScript Language Specification and its implementations, but[]is shorter and its reduced compatibility is hardly relevant today.