1
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! ^^

3
  • Additionally you shouldn't use new Array() but [] Commented Nov 27, 2011 at 11:17
  • Is it giving you an error in the console? It seems like a[x] is not defined so you're trying to assign a property 'name' to an undefined variable. Commented Nov 27, 2011 at 11:20
  • new Array() is perfectly fine per the ECMAScript Language Specification and its implementations, but [] is shorter and its reduced compatibility is hardly relevant today. Commented Nov 27, 2011 at 11:37

5 Answers 5

9

'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.

Sign up to request clarification or add additional context in comments.

4 Comments

Also, 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.
I totally understand now this is great!!
Correct is: There is no object yet to have a property 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.
Initialization a = [] is pointless here. These languages are loosely typed. If you must, write var a = ….toArray();.
1

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

1

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

0
a[x] = {name: 'f', link: 'UUUUUUUUUUU'};

Comments

0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.