1

Hello i am trying to create an angular app. So here is one function which i am using very often in most of my controllers. Can i make one function or one method so can i can use this function everywhere just like we do in PHP.

Here is the function i have:

var responsePromise = $http.get("http://www.somewebsite.com/api/get_category_index/");
                responsePromise.success(function(data, status, headers, config) {
                    //console.log(data);
                    $scope.PostCategories = data.categories;
                    $scope.spinner = false;
                });
                responsePromise.error(function(data, status, headers, config) {
                    alert("ajax didnt work");
                });

I have multiple controller for example i am attaching 2 controllers here:

var module = angular.module('app', ['onsen', 'ngSanitize']);

module.controller('directoryControl', function($scope, $http, $rootScope) {
ons.ready(function() {
                $scope.spinner = true;
                var responsePromise = $http.get("http://www.somewebsite.com/api/get_category_index/");
                responsePromise.success(function(data, status, headers, config) {
                    //console.log(data.categories);
                    $scope.PostCategories = data.categories;
                    $scope.spinner = false;
                });
                responsePromise.error(function(data, status, headers, config) {
                    alert("ajax didnt work");
                });

                $scope.setCurrentCategory = function(categoryName){    
                       $scope.CurrentCategory = categoryName;
                     $rootScope.CurrentCategory=$scope.CurrentCategory;       
                }
    });
});

module.controller('directoryCategoryListing', function($scope, $http, $rootScope) {
ons.ready(function() {

                $scope.CurrentCategory = $rootScope.CurrentCategory;
                $scope.spinner = true;
                var CategoryWiseListingPromise = $http.get("http://www.somewebsite.com/api/get_category_posts/?slug="+$rootScope.CurrentCategory+"&count=50");
                CategoryWiseListingPromise.success(function(data, status, headers, config) {
                    //console.log(data.posts);
                    $scope.PostDetails = data.posts;
                    $scope.spinner = false;
                });
                CategoryWiseListingPromise.error(function(data, status, headers, config) {

                    alert("ajax didnt work");
                });
                $scope.setCurrentListing = function(listingName){
                       $scope.CurrentListing = listingName;
                       $rootScope.CurrentListing=$scope.CurrentListing;
                }
    });
});

So i just want to make that as a common function which i can call from controller.

And same i had an issue with the URL. I want to define a URL variable which i can access from everywhere in all the controllers. Like:

var WebsiteURL = "http://www.somewebsite.com/api/"

Any one know about i can attain this!

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
user3201500
  • 1,538
  • 3
  • 22
  • 43
  • 2
    What you are looking for is Angular Services https://docs.angularjs.org/guide/services. You put your function in an object and return it. Then you can include your service inside a controller the same way you put `$scope, or $http` as a parameter. – azium Apr 26 '15 at 19:28
  • are you using all that code to ask how to create an angular service? https://docs.angularjs.org/guide/services – Claies Apr 26 '15 at 19:28
  • Yes i think its service. Can you help me here with my example? So i can have a better understanding of this? – user3201500 Apr 26 '15 at 19:31
  • Yes using angular service is the way to go. Create a module.service(...) and move all your $http calls into methods in the service – shivas Apr 26 '15 at 19:32
  • I guess yes thats the way it is. I am trying to figure out of doing so. Lets try. – user3201500 Apr 26 '15 at 19:33

2 Answers2

2

You could achieve this by creating factrory and place this method inside there, and access this method by injecting factory dependency

app.factory('DataService', fucntion($http){
  var baseUrl = "http://www.somewebsite.com/api";
  var getData = function(extendedUrl, successCallback, errorCallback){
     return $http.get(baseUrl + extendedUrl).success(successCallback).error(errorCallback);
  }
  return { 
    getData: getData
  }
});

Controller

module.controller('directoryCategoryListing', function($scope, $http, $rootScope, DataService) {
    ons.ready(function() {

        $scope.CurrentCategory = $rootScope.CurrentCategory;
        var successCallback = function(data, status, headers, config) {
            //console.log(data.posts);
            $scope.PostDetails = data.posts;
            $scope.spinner = false;
        };

        var errorCallback = function(data, status, headers, config) {
             alert("ajax didnt work");
        }
        DataService.getData("/get_category_posts/?slug=" + $rootScope.CurrentCategory + "&count=50", successCallback, errorCallback);
        $scope.setCurrentListing = function(listingName) {
            $scope.CurrentListing = listingName;
            $rootScope.CurrentListing = $scope.CurrentListing;
        }
    });
});

In controller you could do access by injecting service/factory name, then access the method which is available in it.

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • return { getData: getData } Can you please help me with this? Why you use getData: getData? here – user3201500 Apr 26 '15 at 19:35
  • because I'm exposing getData method from the service, and further we can add more functions inside the service, you must need to look at this how to write service/factory http://stackoverflow.com/questions/15666048/service-vs-provider-vs-factory/28262966#28262966 – Pankaj Parkar Apr 26 '15 at 19:37
  • @user3201500 look at my edit which now you only need to pass `successCallback` & `errorCallback` function which will get call on `success` & `error` of ajax..let me know if you want anything else – Pankaj Parkar Apr 26 '15 at 19:48
  • Awesome! I got the concept clearly and it really helped me a lot. Thank you so much! – user3201500 Apr 26 '15 at 19:57
1

Here is how you can refactor your code:

var module = angular.module('app', ['onsen', 'ngSanitize']);

module.service('DirectoryService',function(){
    var self = this;

    self.GetCategoryIndex = function(scope){
    $http.get("http://www.somewebsite.com/api/get_category_index/").success(function(data, status, headers, config) {
                //console.log(data.categories);
                scope.PostCategories = data.categories;
                scope.spinner = false;
            }).error(function(data, status, headers, config) {
                alert("ajax didnt work");
            });

}
});
module.controller('directoryControl', function($scope, $http,     $rootScope,DirectoryService) {
ons.ready(function() {
            $scope.spinner = true;

            DirectoryService.GetCategoryIndex($scope);

            $scope.setCurrentCategory = function(categoryName){    
                   $scope.CurrentCategory = categoryName;
                 $rootScope.CurrentCategory=$scope.CurrentCategory;       
            }
});
});
shivas
  • 913
  • 10
  • 15
  • OK its good. But if i want to take the .success and .error both the method to the function in the module.service can i do that? – user3201500 Apr 26 '15 at 19:37
  • You can but then you wont be able to do stuff to your $scope variables form the service. Not directly atleast – shivas Apr 26 '15 at 19:38
  • Can i use $scope here instead of var self.GetCategoryIndex? Like $scope.GetCategoryIndex – user3201500 Apr 26 '15 at 19:39
  • I don't think you can use $scope in a service. Let me verify – shivas Apr 26 '15 at 19:40
  • Awesome got it. And what about the $scope thing? How can i make it wrokable if i use the whole .success and .error function together. Do i have to set some kind of KEY and VALUE pair? Will that be a good option? – user3201500 Apr 26 '15 at 19:42
  • Are you trying to move all the logic up to the service? – shivas Apr 26 '15 at 19:44
  • Yes i want to move everything to the service. So i dont have to specify lots of code all the time. like success and error methods. And is there any difference in service/factory? – user3201500 Apr 26 '15 at 19:46
  • A service and factory are the same things - They are all services in angular. Usually i like keep the promises in the controller so i can handle the .success and .error in the controller. But if you want to move it to the service, I will update the above code – shivas Apr 26 '15 at 19:52
  • var self.GetCategoryIndex = function(scope){ can i pass one more value to this function? Like URL i will pass from DirectoryService.GetCategoryIndex($scope, URL); is that possible? so i can use the URL directly – user3201500 Apr 26 '15 at 20:02
  • I guess there is some error in var self.GetCatIndex its showing this error. Uncaught SyntaxError: Unexpected token . angular.js:80 Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to: Error: [$injector:nomod] Module 'app' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument. – user3201500 Apr 26 '15 at 20:14
  • And yes when i remove self. then it removes the error too. But when i load the controller. I get this error TypeError: ajaxCall.GetCatIndex is not a function – user3201500 Apr 26 '15 at 20:17
  • I change the names here. – user3201500 Apr 26 '15 at 20:17
  • Sorry i had a typo it should have been var self = this; and then self.GetCategoryIndex = function(scope)..... and yes you can add more parameters to the service function – shivas Apr 26 '15 at 20:22
  • var self = this; self.GetCategoryIndex still the same error. :( – user3201500 Apr 26 '15 at 20:23
  • TypeError: ajaxCall.GetCatIndex is not a function – user3201500 Apr 26 '15 at 20:24
  • Ok got it resolved. It was asking for $http. Now i got it. :) Thank you so much for continues help. – user3201500 Apr 26 '15 at 20:28