mailman_73
mailman_73

Reputation: 798

Avoid a repeated scope variable in different controllers in AngularJS

I've got few controllers working with different templates:

curryApp.config(['$routeProvider',
    function($routeProvider) {
        $routeProvider.
        when('/', {
            templateUrl: 'table_index.html',
            controller: 'CurryListCtrl'
        }).
        when('/cities/:cityId/', {
            templateUrl: 'template-total.html',
            controller: 'CurryDetailCtrl'
        }).
        when('/cities/:cityId/mobile/', {
            templateUrl: 'template-mobile.html',
            controller: 'CurryMobileCtrl'
        }).
        when('/cities/:cityId/online/', {
            templateUrl: 'template-online.html',
            controller: 'CurryOnlineCtrl'
        }).

All of theses controllers have $scope variable called cities For example, the first one:

curryControllers.controller('CurryDesktopCtrl', ['$scope', '$routeParams', '$http', '$route',
  function($scope, $routeParams, $http, $route) {
    $scope.cityId = $routeParams.cityId;
    $http.get('json/cities.json').success(function (data) {
      $scope.cities = data;
      ...

The second one:

curryControllers.controller('CurryOnlineCtrl', ['$scope', '$routeParams', '$http', '$route',
  function($scope, $routeParams, $http, $route) {
    $scope.cityId = $routeParams.cityId;
        $http.get('json/cities.json').success(function(data) {
        $scope.cities = data;
        ...

Is it okay to have repeated $scope variables in different controllers? How should I refactor the code in order to escape duplicates?

Upvotes: 1

Views: 88

Answers (4)

Rishi Tiwari
Rishi Tiwari

Reputation: 1051

If cities are not going to change for every controller use services like below

Your service should look like below

 app.service('myService',function($http,$q){
      var cities=null;
      this.getCities=function()
                     {

                         var deferred = $q.defer()
                         if(this.cities==null){
                         $http.get('json/cities.json')
                         .then((response) => {deferred.resolve(response);cities=response;})
                         .catch((error) => deferred.reject(error))
                         }
                         else { deferred.resolve(cities)}
                         return deferred.defer  

                     })
        });

Use the above service in the controller

  app.controller('ctrl',function($scope,myService){
           myService.getCities().then(function(data){ $scope.cities = data;})
  })

Upvotes: 2

Cyril Cherian
Cyril Cherian

Reputation: 32327

If the cities json is common for all the controllers.

One option would be to move the common object used across controllers into rootscope refer.

Other option would be to store the cities json in the service itself read here.

Upvotes: 0

Srijith
Srijith

Reputation: 1444

You should do create a factory like this. Forgive the syntax, but you get the idea.

app.factory('Cities', function ($http) {
return {
    'getData': function() {
         $http.get('json/cities.json').success(function (data) {
           return data;
          }
          .error(function(error){
           return [];
          }
    }
};

}]);

and in your controller inject the factory and get the data

curryControllers.controller('CurryOnlineCtrl', ['$scope', '$routeParams', '$http', '$route', 'Cities'
  function($scope, $routeParams, $http, $route) {
    $scope.cityId = $routeParams.cityId;
    $scope.cities = Cities.getData();
    ...

Upvotes: 1

developer033
developer033

Reputation: 24894

You can create a factory:

.factory('citiesFactory', function($http) {
   function getCities(){
      // return promise from function
      return $http.get("json/cities.json");
   }

   return {
      getCities: getCities
   }
});

then in your controller:

curryControllers.controller('CurryDesktopCtrl', ['$scope', '$routeParams', '$http', '$route', 'citiesFactory'
  function($scope, $routeParams, $http, $route, citiesFactory) {
    $scope.cityId = $routeParams.cityId;
    citiesFactory.getCities().then(function(response){
       $scope.cities = response.data;
    });
      ...

Upvotes: 1

Related Questions