Moshe Shaham
Moshe Shaham

Reputation: 15984

AngularJS: ng-repeat an array with keys

I have an array with unordered keys, and I want to display them. The problem is that angular repeats it for all the keys, even when they are not set.

this is the code:

<div ng-controller="MyCtrl">
  Hello, {{a[10]}}!

    <p ng-repeat="b in a">
        1. {{b}}
    </p>
</div>

<script>
var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    $scope.a = [];
    $scope.a[10] = "aaa";
}
</script>

and this is the output:

Hello, aaa!
1.
1.
1.
1.
1.
1.
1.
1.
1.
1.
1. aaa

i want only the array keys that are set to output. no empty b's please... here is a jsfiddle

Upvotes: 0

Views: 6128

Answers (2)

jvandemo
jvandemo

Reputation: 13296

In essence your problem is not AngularJS related but rather how JavaScript works.

If you have an empty array and you assign an element to position 10, then JavaScript will automatically resize the array to 11 elements (since an array index starts at zero) so the index is large enough to hold your element.

You could write extra code to filter the empty elements, but based on what you write, I think you would be better off with using an object to store your data.

I have created a plnkr for your convenience: http://plnkr.co/edit/apRLuJr4zqS2zbMz322Q?p=preview

// Array
$scope.sampleArray = [];
$scope.sampleArray[10] = 'test';

// Object
$scope.sampleObject = {};
$scope.sampleObject[10] = 'test';

As you can see the syntax is very similar, but the output is completely different.

By using an object, you will automatically eliminate the empty lines.

It will also keep your code simpler since you won't have to deal with the empty array elements.

Hope that helps!

Upvotes: 4

Stewie
Stewie

Reputation: 60406

There's plenty of ways to do a cleanup on your array inside the controller (e.g. using $watchcallback on a that would remove the empty elements from it whenever it changes).

Here's a solution that uses a simple custom filter, defined in a controller:

function MyCtrl($scope) {
    $scope.namea = 'Superhero';
    $scope.a = [];
    $scope.a[10] = "aaa";

    $scope.myFilter = function(item){
        return item;
    }
}

<p ng-repeat="b in a | filter:myFilter">
  1. {{b}}
</p>

As stated in filter docs, the 'filter' filter can take a function:

function: A predicate function can be used to write arbitrary filters. The function is called for each element of array. The final result is an array of those elements that the predicate returned true for.

Upvotes: 1

Related Questions