Error: "angular was used before it was defined" but online editors able to output the result

RAOUL picture RAOUL · Jul 13, 2015 · Viewed 9.9k times · Source

I couldn't get an output from this code when I ran it my local machine but the weird part is online editors able to give me an output: http://codepen.io/anon/pen/waXGom

*Im using Adobe Brackets editor

Here is my HTML code:

    <!DOCTYPE html >
  <html>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
    <script src= "app.js"></script>    
    <body ng-app="MyApp">

<div ng-controller="Controller2">
    <button ng-click="add()">Add Object</button>
    <button ng-click="reset()">Reset</button>
    <div remove="remove($index)" ng-repeat="name in names">
        {{name}}
    </div>
</div>

</body>
</html>

Here is my JS code:

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

    myApp.controller('Controller2', function ($scope) {
        $scope.names = [];
    var data = ['Dean', 'Andy', 'Dan', 'Wizek', 'Pete', 'Pawel', 'Chris', 'Misko'];
    $scope.add = function() {
        if (data.length)
            $scope.names.push(data.pop());
    };

        $scope.reset = function(index) {
        data.push($scope.names.splice(index, 1)[0]);
    };
    });

Please help me to figure it out...

Answer

ruffin picture ruffin · Jul 13, 2015

Do you mean you see the angular used before it was defined error from JSLint? That'd be because you're using angular, a global, in your JavaScript code without letting JSLint know it's in scope first.

JSLint operates on a page-by-page level, and can't tell what's in the global context from outside includes. You've loaded Angular into the global context in another include, but JSLint can't tell that when it looks at this single JavaScript file by itself.

To be clear, then, just this line should already cause JSLint to report the error:

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

You have to add a global directive to let JSLint know what's in the global context.

/*global angular */
var myApp = angular.module('myApp', []);

Now you're golden.


Just for fun, here's a fully JSLinted version of your JavaScript file snippet. Didn't take much. Note that I had to add squiggly brackets around your if block and the jslint directive white:true for what it considers non-standard whitespace. More on all that here.

/*jslint white:true */
/*global angular */
var myApp = angular.module('myApp', []);
myApp.controller('Controller2', function ($scope) {
    "use strict";

    $scope.names = [];
    var data = ['Dean', 'Andy', 'Dan', 'Wizek', 'Pete', 'Pawel', 'Chris', 'Misko'];
    $scope.add = function() {
        if (data.length)
        {
            $scope.names.push(data.pop());
        }
    };

    $scope.reset = function(index) {
        data.push($scope.names.splice(index, 1)[0]);
    };
});