1

I have been trying to get data from a json file through service in AngularJS(1.5.3). I am unable to retrieve the data from json and display it in the view. I get blank values instead. Below is the code:

//Service

angularStoreApp.factory('dataService', ['$http', function ($http, $q) {

    return {
        getProducts: function () {
            var promise = $http.get('/api/json/products.json')        
        .then(function successCallback(response) {
            if (typeof response.data === 'object') {
                return response.data;
            } else {
                // invalid response
                return "Invalid data";
            }
        }, function errorCallback(response) {
            return "Invalid data";
        })
            return promise;
        }
    };
}]);

//Controller

/// <reference path="SearchController.js" />
angularStoreApp.controller('SearchCtrl', ['$scope', 'dataService', function ($scope, dataService) {
      
    $scope.ProductItems = [];
   
    dataService.getProducts()
        .then(function (data) {
            $scope.ProductItems = data;
        });
}]);
<blockquote>
    <h4 style="color: salmon">Welcome to the New Store
    <br />
        Please select the products you want and add them to your shopping cart.
    <br />
        When you are done, click the shopping cart icon to review your order and checkout.
    <br />
    </h4>


  
<div class="row">
    <div class="col-sm-12" ng-repeat="ProductItem in ProductItems track by $index">
        {{ProductItem.Name}}, {{ProductItem.Price}}
    </div>
</div>

Update:

Below is the json data that I have. [{ "itemName": "Notepad", "itemPrice": 12, "itemQuantity": 0 }, { "itemName": "Pen", "itemPrice": 8, "itemQuantity": 0 }, { "itemName": "Pencil", "itemPrice": 5, "itemQuantity": 0 }];

Could anyone help me out.

Sreehari
  • 49
  • 8

6 Answers6

1

I think the problem is in your first line!

you should pass all the services as string:

angularStoreApp.factory('dataService', ['$http', '$q' function ($http, $q) {
Ahmad Mobaraki
  • 7,426
  • 5
  • 48
  • 69
1

In order to get the code snippet working, you need to

  • initialize the module in the js: var angularStoreApp = angular.module('storeapp', []);
  • add ng-app in the view
  • add ng-controller in the view (or use routing)

Forgetting to add $q to the dependencies is indeed a mistake, but it doesn't prevent your app from working, as long as you don't use $q.

Below is an adjusted, working code snippet. I simulated the http call by returning json wrapped in a promise. If it still doesn't work, the problem is the HTTP call, i.e. the part I commented out. Execute the call in the browser and verify that the correct JSON is returned.

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

//Service

angularStoreApp.factory('dataService', ['$http', '$q',
  function($http, $q) {

    return {
      getProducts: function() {
        //simulate promise with json:
        return $q.when([{
          'Name': 'name 1',
          'Price': 1.23
        }, {
          'Name': 'name 2',
          'Price': 4.56
        }]);
        //var promise = $http.get('/api/json/products.json')
        // .then(function successCallback(response) {
        //  if (typeof response.data === 'object') {
        //   return response.data;
        // } else {
        // invalid response
        //   return "Invalid data";
        // }
        // }, function errorCallback(response) {
        //   return "Invalid data";
        // })
        // return promise;
      }
    };
  }
]);

//Controller

/// <reference path="SearchController.js" />
angularStoreApp.controller('SearchCtrl', ['$scope', 'dataService',
  function($scope, dataService) {

    $scope.ProductItems = [];

    dataService.getProducts()
      .then(function(data) {
        $scope.ProductItems = data;
      });
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="storeapp" ng-controller="SearchCtrl">
  <blockquote>
    <h4 style="color: salmon">Welcome to the New Store
    <br />
        Please select the products you want and add them to your shopping cart.
    <br />
        When you are done, click the shopping cart icon to review your order and checkout.
    <br />
    </h4>



    <div class="row">
      <div class="col-sm-12" ng-repeat="ProductItem in ProductItems track by $index">
        {{ProductItem.Name}}, {{ProductItem.Price}}
      </div>
    </div>
</div>
fikkatra
  • 5,605
  • 4
  • 40
  • 66
0

I've replicated your code in jsbin and it is working fine through I've changed the code for brevity.

The issue might be with below code as it looks for products.json in root folder not in your project folder.

$http.get('/api/json/products.json')

Try with removing '/' in the URL.

$http.get('api/json/products.json')

Gangadhar Jannu
  • 4,136
  • 6
  • 29
  • 49
0

I found the answer after reading the following links

http://www.dwmkerr.com/promises-in-angularjs-the-definitive-guide/

http://bguiz.github.io/js-standards/angularjs/resolving-promises-for-a-controller/

The following is how I modified my code to get it working:

In the config routing section I used the resolve property for that route

var angularStoreApp = angular.module('AngularStore', ['ngRoute']);
angularStoreApp.config(['$routeProvider', function ($routeProvider) {
    $routeProvider.when('/products', {
        templateUrl: '/Views/Store.html',
        controller: 'SearchCtrl',
        resolve: {
            resolvedJSON: function (dataService) {
                return dataService.getProducts();
            }
        }
    })
    .when('/product/:productName', {
        templateUrl: '/Views/product.html',
        controller: 'ProductCtrl'
    })
    .otherwise({
        redirectTo: '/products'
    });
}]);

Now I injected the resolvedJSON in my controller as follows

/// <reference path="SearchController.js" />
angularStoreApp.controller('SearchCtrl', ['$scope', 'resolvedJSON',           function ($scope, resolvedJSON) {
$scope.ProductItems = [];
$scope.ProductItems = resolvedJSON;
}]);

And my service code as follows:

angularStoreApp.factory('dataService', ['$http', function ($http, $q) {
  return {
    getProducts: function () {
        return $http.get('/api/json/products.json')
           .then(function successCallback(response) {
               return response.data;
           }, function errorCallback(response) {
               return "Invalid data";
           })
    }
};

following is my json data

[{
   "itemName": "Notepad",
   "itemPrice": 12,
   "itemQuantity": 0
},
{
   "itemName": "Pen",
   "itemPrice": 8,
   "itemQuantity": 0
},
{
    "itemName": "Pencil",
    "itemPrice": 5,
    "itemQuantity": 0
}]

My view(Store.html) is something like this:

<div class="row">
    <div class="col-sm-12" ng-repeat="ProductItem in ProductItems track by $index">
        {{ProductItem.itemName}}, {{ProductItem.itemPrice}}
    </div>
</div>

Hope this helps anyone facing a similar issue as mine. Thank you everyone who steered me to a better and simple answer.

Sreehari
  • 49
  • 8
-1
  1. u forgot the '$q' for minification
  2. u should use the var deferred = $q.defer();// (I will add a full code)
  3. example jsfiddle

    angular.module('app', [])
    .controller('ctrl', function(dataService, $scope) {
    var vm = this;
    $scope.ProductItems = [];
    
    dataService.getProducts()
      .then(function(data) {
        $scope.ProductItems = data;
      });
    })  
    .factory('dataService', ['$http', '$q', function($http, $q) {
    
    function getProducts() {
      var deferred = $q.defer();
    
      $http.get('https://httpbin.org/get')
        .then(function successCallback(response) {
    
          if (typeof response.data === 'object') {
            // let say we get list of Products
            deferred.resolve([{
              id: 1,
              name: 'Product1'
            }, {
              id: 2,
              name: 'Product2'
            }, {
              id: 3,
              name: 'Product3'
            }]);
          } else {
            // invalid response
            return "Invalid data";
          }
        }, function errorCallback(response) {
          return deferred.reject("Invalid data");
        })
    
      return deferred.promise;
    }
    
    return {
      getProducts: getProducts
    };
     }]);
    
ofir fridman
  • 2,691
  • 2
  • 17
  • 27
  • Please try to avoid the explicit promise construction anti pattern! It is really not necessary to construct a deferred object in this case. See here: http://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it – fikkatra Apr 15 '16 at 14:40
  • Ok Thanks :) I didn't know it anti pattern – ofir fridman Apr 15 '16 at 14:42
-1

I think one of the problems you have is already mentioned @Ahmad Mobaraki ,and another one is in your dataService, the promise object returned by $http.get('/api/json/products.json') is already consumed by then() function, so what you need to do is to create a new promise and return it.

Code example:

//service
angularStoreApp.factory('dataService', ['$http', '$q', function ($http, $q) {

    return {
        getProducts: function () {
            var defered = $q.defer();

            $http.get('/api/json/products.json')        
                .then(function successCallback(response) {
                    if (typeof response.data === 'object') {
                        defered.resolve(response.data);

                    } else {
                        // invalid response
                        defered.reject("Invalid data");
                    }
                }, function errorCallback(response) {
                defered.reject("Invalid data");
            });
            return defered.promise;
        }
    };
}]);

//Controller
angularStoreApp.controller('SearchCtrl', ['$scope', 'dataService', function ($scope, dataService) {

    $scope.ProductItems = [];

    dataService.getProducts()
        .then(function (data) {
            $scope.ProductItems = data;
        });
}]);

hope this can help you :)

David Tao
  • 513
  • 5
  • 12
  • even if you add 'then' to a promise, it will still return a new promise because promises are chained. Furthermore, try to avoid the explicit promise construction anti patter, see here: http://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it – fikkatra Apr 15 '16 at 14:38
  • Thank you, just looking into that :) – David Tao Apr 15 '16 at 14:51