0

I have been working with wrapping my head around the "angularjs" way of thinking (Angular 1) and I have a relatively ok grasp as I work my way through a small personal project. I am at a bit of a roadblock, not because I cannot get it to work, but I would like to know what the proper way to set up the data in my application.

The basic situation is this:

I have 3 json files:

categories.json
products.json
vendors.json

These hold the data (which I will fetch from a database later but am simplifying for now).

I basically need to load the data from all three of these files so that I can form a variable holding all "Products" (which is a JS class I declared separately).

I started off by storing the data inside one controller (relevant code below):

myApp.controller('productListController', ['$scope', '$http', '$q', function ($scope, $http, $q) {

var promises = [];
promises.push(getCategories($http));
promises.push(getVendors($http));
promises.push(getProducts($http));

$q.all(promises).then(function (response) {
  //categories = response[0];
  //vendors = response[1];
  //products = response[2];
  $scope.products = createProductList(response);
  $scope.vendors = response[1].data;
  $scope.vendorChecked = getCheckedVendors($scope.vendors);
})

This worked fine but I realized that I need this data in other views, which led me to try to move this code into a service.

The problem I had when doing this is that I do not know of a way for the controller to know that the service is done fetching the data so that I can then save it in the ProductListController $scope.

I would need to have a way to for example:

myApp.service('ProductService', ['$http', '$q', function ($http, $q) {

self = this;
var promises = [];
promises.push(getCategories($http));
promises.push(getVendors($http));
promises.push(getProducts($http));

$q.all(promises).then(function (response) {
//These three I would like to update in ProductListController
//when it is done.
  self.products = createProductList(response);
  self.vendors = response[1].data;
  self.vendorChecked = getCheckedVendors(self.vendors);
})

Is this the correct approach to take? If so, how can I let the controller know that the service is done fetching the data and save for example:

$scope.products = ProductService.products;
$scope.vendors = ProductService.vendors;
$scope.categories = ProductService.categories;

Is this even the correct approach? Another approach I thought of was to use a factory instead of a service. Then I had another problem because I had for example:

return {
    getProducts: function() {
         //http get request code in here
         return promise
    },
    getVendors: function() {
         //http get request code in here
        return promise
    },
    getCategories: function() {
         //http get request code in here
        return promise
    },
    getAllData: function () {
    //in here I want to use the three promises in the 3 functions above
    //but I am not able to call them from here. If I was able to do that
    //then I could call this method from ProductListController and get the
    //data that way.
    }

I am sorry if this is long but I wanted to describe the different things I tried. I know I can make it work but I want to learn the right way, or a couple of right ways.

1 Answer 1

1

It is better to always return promise:

var promises = [];
promises.push(getCategories($http));
promises.push(getVendors($http));
promises.push(getProducts($http));

return $q.all(promises)

If you also not satisfied that in each controller you should call createProductList,getCheckedVendors - consider putting this tranforms to $http transformResponce https://docs.angularjs.org/api/ng/service/$http. Or you can create your own promise. (Using $q.defer https://docs.angularjs.org/api/ng/service/$q).

Using servie or factory actually doesnt matter. This is factory:

var factory = {};
factory.getProducts: function() {
         return promise
}
factory.getCategories: function() {
         return promise
}
factory.getVendors: function() {
         return promise
}
factory.getAllData: function () {
    var promises = [];
    promises.push(factory.getProducts());
    promises.push(factory.getCategories());
    promises.push(factory.getVendors());

    return $q.all(promises)
}
return factory;

And in controler you just have: MyFactory.getAllData().then(...)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you this was helpful. I was able to get it working and also I split up my services into 2. One for the helper methods and one to hold the model.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.