Nikage
Nikage

Reputation: 598

Angular.forEach does not return the last item in object

       var items = [];

        //angular.forEach(localStorage, function(value, key){
        //    items.push({
        //        'id'    : key,
        //        'text'  : value
        //    });
        //    console.log(value);
        //});
        for(var key in localStorage){
            if(localStorage.hasOwnProperty(key)){
                //console.log(localStorage[row]);
                items.push({
                    'id'    : key,
                    'text'  : localStorage[key]
                });
            }
        }
        return items;

The commented code returns array of two elements, while simple "for in" loop return all the values form the localStorage object (actually there are three items).

I don't get why the hell angular.forEach does not iterate the last item in object?

Everything should be ok according to the docs https://docs.angularjs.org/api/ng/function/angular.forEach

Upvotes: 1

Views: 1668

Answers (1)

shyammakwana.me
shyammakwana.me

Reputation: 5752

Here is what I found from my debugging.

As you have set keys of localStorage as integers (though it will be saved as string) but for libraries like jQuery and Angular, they will consider it as number and will iterate it over object for that particular size of object. (here 3 in your case.)

By printing all values with jQuery (https://jsfiddle.net/9n4btgob/) it's giving me 0 also as output and it's value is undefined. So iteration will be over at 2.

Thus angular is using jQlite so it will output same results. https://jsfiddle.net/hru2k47u/

Here by setting first value of localStorage as 0 will solve problem.

Working With angular : https://jsfiddle.net/hru2k47u/1/
working with jQuery : https://jsfiddle.net/9n4btgob/2/

OR

you can append any alphabet to keys.

Update:

After debugging jQuery more I found that isArrayLike function is causing the issue. Because this function returns true for localStorage where keys are numeric, thus it will start for loop till it's length and iterate over it. so Last property won't execute.

if ( isArrayLike( obj ) ) {
            length = obj.length;
            for ( ; i < length; i++ ) {
                if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                    break;
                }
            }
        } 

Upvotes: 3

Related Questions