1

I am trying to get the length of span element using angular.element However, I realize that it takes time to load angular to execute ng-repeat. And because of that, I didn't get the right number of length to return.

What I want to accomplish is: first, display number of zero based on the length of the letter. And then randomly generate a number to 0 to 9. Eventually, replace the number with the correct position of the letters.

HTML file

    <span class="nbr" ng-repeat="(key, value) in letters track by $index">0</span>

JS File

app.controller('MainCtrl', function($scope) {
   $scope.letters = ["H", "E","L", "L","O"];
   $scope.randomnbr = angular.element(document.querySelectorAll('.nbr'));
        alert($scope.randomnbr.length);
});

I made a Plunker Plunker Link

Will be helpful if someone can explain how and when angular is loaded and why this is happened. Thank you advanced!

Shaohao
  • 3,471
  • 7
  • 26
  • 45
  • what is the point of this? you are taking an array which has a known length and then trying to find it's length by finding out how many elements were written out? This doesn't feel angular at all, and even if there are answers that work, it just plain doesn't make sense. – Claies Jul 28 '15 at 16:25
  • This is just piece of code that I need to find out how to work with my other project. Suppose you have a string, and you want to display the letter individually and you want to manipulate individually as well in certain way. @Claies – Shaohao Jul 28 '15 at 17:17
  • you already have an answer as to how to do it the non-angular way, but I still think this not the most efficient way to work in angular at all. I think if you posted the specifics of your particular code, 99 times out of 100 there is a way to do whatever you need to accomplish in angular without resorting to JQuery or `angular.element`, and you haven't really made the case that this is that one time it is necessary. – Claies Jul 28 '15 at 17:38
  • @Claies I edit what I want to accomplish, any suggestion ? – Shaohao Jul 28 '15 at 17:51
  • I updated the plunker as well. @Claies – Shaohao Jul 28 '15 at 18:02

2 Answers2

2

First - Don't do DOM manipulation in controllers.

This is happening because your controller is getting initialized first which triggers the ng-repeat model scoped variable.

To test it wrap the code in a $timeout - this will make sure you call the angular.element called in next digest cycle.

app.controller('MainCtrl', function($scope, $timeout) {
  $scope.letters = ["H", "E", "L", "L", "O"];
  $timeout(function() {
    $scope.randomnbr = angular.element(document.querySelectorAll('.nbr'));
    alert($scope.randomnbr.length);
  });
});

Better way to handle is Calling a function when ng-repeat has finished

Community
  • 1
  • 1
Liam
  • 2,837
  • 23
  • 36
1

Check working demo: Plunker.

Add $timeout to wait for the $digest to finish:

var app = angular.module('plunker', []);

app.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout) {
  $scope.letters = ["H", "E","L", "L","O"];

  $timeout(function () {
    $scope.randomnbr = angular.element(document.querySelectorAll('.nbr'));
    alert($scope.randomnbr.length);
  });

}]);
Joy
  • 9,430
  • 11
  • 44
  • 95