AngularJS - using angular.forEach and console.log to loop through arrays is unpredictable

This is a zip-code guessing app, built with FireBase and Angular. For each digit that the user inputs, a query is made to a FireBase database that returns an array with zip codes that have the corresponding digit in the corresponding place(lines 3-48). Then the newGuess() function is called. For each of the inputs that have a number entered, the array that was returned is placed in an array called compareArray(lines 50 - 66). The length of compareArray (line 76) determines what happens next, which is where I was trying to iterate through each of the nested arrays. This is the brick wall that I cannot seem to get past. The arrays do not print out. Am I using $scope wrong? It seems to iterate through the arrays SOME of the time, but not all. Does this mean that the arrays may not be populating in time?

It should be noted that both the compareArray and the resultsArray have been placed in and out of the $scope object, with the same results. I have also used a regular for loop to try and iterate through the arrays, but the angular.forEach loop seemed to worked more often than it.

The end goal is that once we know how many arrays there are nested in the compareArray, we will be able to pull them out, iterate through them, and compare them for similar zip codes. These zip codes, that are present in all returned arrays, are then places into a resultsArray, and a random one is chosen. The computer uses this random zip-code to “guess” where the user lives.

I also realize that there are parts of the code that are not as DRY as they could be. I was planning on getting the code working first, and then spending time re-factoring. Any advice on that is also appreciated.

I'll also link to the github. The only other files that are relevant are the app.js and the index.html file.

https://github.com/nhwilcox/zip-code_angular

zipCodeApp.controller('ZipCodesCtrl', function ZipCodesCtrl($scope, $firebaseArray) {

    var ref = new Firebase('https://zip-it.firebaseio.com/zips');

    $scope.detectChangeDigit1 = function() {
        var query = ref.orderByChild("digit1").equalTo($scope.zipCode.firstDigit.toString());
        $scope.digit1Array = $firebaseArray(query);
        $scope.digit1Array.$loaded().then(function() {
            $scope.digit1Array.sort();
        });
        newGuess();
    };

    $scope.detectChangeDigit2 = function() {
        var query = ref.orderByChild("digit2").equalTo($scope.zipCode.secondDigit.toString());
        $scope.digit2Array = $firebaseArray(query);
        $scope.digit2Array.$loaded().then(function() {
            $scope.digit2Array.sort();
        });
        newGuess();
    };

    $scope.detectChangeDigit3 = function() {
        var query = ref.orderByChild("digit3").equalTo($scope.zipCode.thirdDigit.toString());
        $scope.digit3Array = $firebaseArray(query);
        $scope.digit3Array.$loaded().then(function() {
            $scope.digit3Array.sort();
        });
        newGuess();
    };

    $scope.detectChangeDigit4 = function() {
        var query = ref.orderByChild("digit4").equalTo($scope.zipCode.fourthDigit.toString());
        $scope.digit4Array = $firebaseArray(query);
        $scope.digit4Array.$loaded().then(function() {
            $scope.digit4Array.sort();
        });
        newGuess();
    };

    $scope.detectChangeDigit5 = function() {
        var query = ref.orderByChild("digit5").equalTo($scope.zipCode.fifthDigit.toString());
        $scope.digit5Array = $firebaseArray(query);
        $scope.digit5Array.$loaded().then(function() {
            $scope.digit5Array.sort();
        });
        newGuess();
    };

    var newGuess = function() {
        var compareArray = []
        if (typeof $scope.zipCode.firstDigit !== "undefined") {
            compareArray.push($scope.digit1Array);
        }
        if (typeof $scope.zipCode.secondDigit !== "undefined") {
            compareArray.push($scope.digit2Array);
        }
        if (typeof $scope.zipCode.thirdDigit !== "undefined") {
            compareArray.push($scope.digit3Array);
        }
        if (typeof $scope.zipCode.fourthDigit !== "undefined") {
            compareArray.push($scope.digit4Array);
        }
        if (typeof $scope.zipCode.fifthDigit !== "undefined") {
            compareArray.push($scope.digit5Array);
        }

        var resultsArray = [];

        // if there is only one number, only one query is needed, and it can be
        // assigned to the results array.
        // if there are two numbers, we need two queries, and the resulting arrays
        // need to be checked against each other to find zipcodes that are only
        // present in both arrays.

        if (compareArray.length === 1) {
            console.log("1!");
            resultsArray = compareArray[0];
            angular.forEach(compareArray[0], function(value, key) {
                console.log(value);
            });
        } else if (compareArray.length === 2) {
            console.log("2!");
            angular.forEach(compareArray[0], function(value, key) {
                console.log(value);
            });
            angular.forEach(compareArray[1], function(value, key) {
                console.log(value);
            });
        } else if (compareArray.length === 3) {
            console.log("3!");
            angular.forEach(compareArray[0], function(value, key) {
                console.log(value);
            });
            angular.forEach(compareArray[1], function(value, key) {
                console.log(value);
            });
            angular.forEach(compareArray[2], function(value, key) {
                console.log(value);
            });

        } else if (compareArray.length === 4) {
            console.log("4!");
        } else if (compareArray.length === 5) {
            console.log("5!");
        }
        $scope.resultsArray = resultsArray;
    }
});

Answers


I would guess this is a timing issue. Put the newGuess() call inside the .then() and that should fix it.


Need Your Help

Plone plone.app.jquery 1.9.1 breaks TinyMCE etc?

jquery tinymce plone

If i install a fresh Plone 4.3.2 and then upgrade the default plone.app.jquery from 1.7.2 to 1.9.1, editing the default homepage shows the following:

Parsing huge (~100mb) kml (xml) file taking *hours* without any sign of actual parsing

ruby xml timeout kml large-data

I'm currently trying to parse a very large kml (xml) file with ruby (Nokogiri) and am having a little bit of trouble.