jrodr
jrodr

Reputation: 45

Why this if statement creates an undefined value inside a for loop?

I have created this for loop to collect all the images inside an <ul>. I want to collect on one hand the portrait images and on the other the ones that are in landscape, and apparently it works...

for ( var i = 0; i < imgArray.length; i += 1 ) {
    var images = [ imgArray ]; // Creates an array with all the images.

//Figure out which images are in landscape and in portrait.

    if ( imgArray[i].height < imgArray[i].width ) {
        var landscapeImg = [ imgArray[i] ]; // Stores landscape images.
    } else if ( imgArray[i].height > imgArray[i].width ) {
        var portraitImg = [ imgArray[i] ]; // Stores portrait images.
    };

... but when I log in the console var landscapeImg and portraitImg this happens.

[Log] [ (app.js, line 24)
<img src=​"img/​1.jpg" alt=​"Imagen 1">​
]
[Log] undefined (app.js, line 25)
[Log] [ (app.js, line 24)
<img src=​"img/​1.jpg" alt=​"Imagen 1">​
]
[Log] [ (app.js, line 25)
<img src=​"img/​2.jpg" alt=​"Imagen 2">​
]
[Log] [ (app.js, line 24)
<img src=​"img/​3.jpg" alt=​"Imagen 3">​
]
[Log] [ (app.js, line 25)
<img src=​"img/​2.jpg" alt=​"Imagen 2">​
]
[Log] [ (app.js, line 24)
<img src=​"img/​4.jpg" alt=​"Imagen 4">​
]
[Log] [ (app.js, line 25)
<img src=​"img/​2.jpg" alt=​"Imagen 2">​
]
[Log] [ (app.js, line 24)
<img src=​"img/​5.jpg" alt=​"Imagen 5">​
]
[Log] [ (app.js, line 25)
<img src=​"img/​2.jpg" alt=​"Imagen 2">​
]

Why I am getting an undefined value? And why the loop goes over the image 1 again?

Thanks in advance :)

Upvotes: 0

Views: 69

Answers (2)

Michael Geary
Michael Geary

Reputation: 28860

First, a naming tip. It helps to use consistent and meaningful names. I like using plural and singular names for arrays and single items respectively: images is a good name for an array of images, and image is a good name for a single image. landscapeImg is not a good name for an array of landscape images, because it sounds like a name for a single image. imgArray is a fine name for an array of images, but if you have a lot of arrays it gets tedious to repeat the Array part over and over again. My suggestion there is to use plural names like images for brevity and clarity.

So I'm going to tweak the names a bit in the example below and assume the input array is called images. And if it's already an array, we don't need to create another array with the same thing. Also, we need to take care of square images, unless you want to lump them into either the portraits or landscapes.

One other tip: instead of repeating imgArray[i] several times in the code (or it would be images[i] in the code below), it helps to assign that to a simple variable to make the code shorter and more clear.

Finally, what you want to do is create each array before the loop and then push items into the appropriate array inside the loop. So it might look like this:

var squares = [], landscapes = [], portraits = [];

for( var i = 0;  i < images.length;  i++ ) {
    var image = images[i];
    if( image.height < image.width ) {
        landscapes.push( image );
    } else if( image.height > image.width ) {
        portraits.push( image );
    } else {
        squares.push( image );
    }
}

Upvotes: 1

Spencer Wieczorek
Spencer Wieczorek

Reputation: 21575

Because on the first run only the code in the if or else-if will run, both sections cannot be ran one on a single iteration. This leaves one of the variables yet to be defined. For example:

if ( true ) {
    var landscapeImg = [ imgArray[i] ]; // Stores landscape images.
} else if ( false ) {
    var portraitImg = [ imgArray[i] ]; // Stores portrait images.
};

console.log(portraitImg) // logs undefined
console.log(landscapeImg) // logs some defined value

Upvotes: 1

Related Questions