Home > front end >  Why am I getting an error, "ReferenceError: categories is not defined" in AngularJS?
Why am I getting an error, "ReferenceError: categories is not defined" in AngularJS?

Time:10-27

In my understanding, $scope.categories is already defined. Then why am I getting this error and not able to access data from the Json file?

Here is my controller:

(function(){

    app.controller('productsCtrl', ['$scope','$cookies', '$http', function($scope,$cookies,$http){

        $http.get("controllers/data.json").then(function (response) {
            $scope.categories = response.data;
        }); 

        $scope.specials = [categories[0].laptops[1], categories[1].accessories[0]];

    }]);

})(); 

Here is my Json file:

[
  {
    "laptops": [     
      {
        "name": "Asus Laptop",
        "price": 300
      },
      {
        "name": "HP Notebook",
        "price": 200
      }
    ]
  },
  {
    "accessories": [
      {
        "name": "WD Hard Drive",
        "price": 100
      },
      {
        "name": "WD Blue SSD",
        "price": 700
      }
    ]
  }
] 

CodePudding user response:

You have assigned response data into $scope.categories, you need to use $scope.categories instead of categories and also you should add into $scope.specials once http call completed like

(function(){

    app.controller('productsCtrl', ['$scope','$cookies', '$http', function($scope,$cookies,$http){

        $scope.specials = [];
        $http.get("controllers/data.json").then(function (response) {
            $scope.categories = response.data;
            $scope.specials.push($scope.categories[0].laptops[1]);
            $scope.specials.push($scope.categories[1]. accessories[0]);
        }); 

        

    }]);

})(); 

CodePudding user response:

There's actually a few issues here. First is you never define a variable named categories, you have a property of the $scope object named that, so you need to access $scope.categories or the response.data setting it directly.

Second, you have a race condition issue. You are trying to access the values of categories outside the promise, meaning potentially before the get request has returned any data. When you use get().then() like you are, the code after the request doesn't wait for the request to finish before it runs, so whatever is faster runs first. Because one of the two operations running is accessing an external endpoint and the other is local javascript code, the flow is almost guaranteed to be this:

  1. send get request to "controllers/data.json"
  2. set $scope.specials - causing your undefined error
  3. set $scope.categories when get request promise resolves

You need to access the categories inside the promise to guarantee that it actually has been defined at the point you are trying to access it:

$http.get("controllers/data.json").then(function (response) {
    $scope.categories = response.data;
    $scope.specials = [$scope.categories[0].laptops[1], $scope.categories[1].accessories[0]];
}); 

It's also generally a bad idea to hard code indexes like this, if the data changes you run into a possible index out of bounds error.

  • Related