AngularJS: How to pass values from Controller to Service Method?

31,549

Solution 1

Defining params in the resource constructor are only necessary when the call needs to have a default when none is supplied. Any param passed in to the method is appended as a query param, regardless of whether it has a default value defined. The '@' means that the params value is replaced by what gets returned in the JSON response, so your @uuid makes sense, but not your @month.

Personally, I would just create the resource like so:

$resource('/users/:userId/transactions/:transactionId',
    // todo: default user for now, change it
    {userId: 'bd675d42-aa9b-11e2-9d27-b88d1205c810', transactionId: '@uuid'},
    {
        getRecent: {method: 'GET', params: {recent: true}, isArray: true},
        getForMonthAndYear: {method: 'GET', isArray: true}
    });

Then add the query variables as needed by passing them in. (Creating special method names is fine but not necessary so showing both ways below.)

var t = new Transaction();
$scope.recentTransactions = t.$get({recent:true}) //results in /users/bd675d42-aa9b-11e2-9d27-b88d1205c810/transactions/?recent=true
$scope.recentTransactions = t.$getRecent(); //same thing as above
$scope.transactions = t.$get({month: $scope.month, year: $scope.year}); //results in /users/bd675d42-aa9b-11e2-9d27-b88d1205c810/transactions/?month=5&year=2013
$scope.transactions = t.$getForMonthAndYear({month: $scope.month, year: $scope.year}); //same as above... since no defaults in constructor, always pass in the params needed

Solution 2

I had the same problem, I ended up returning parametrized functions from my service, so the service looks like that

factory('MyService', function($resource) {
    return {
        id: function(param) { return $resource('/api/'+param+'/:id', {id: '@id'}); },
        list: function(param) { return $resource('/api/'+param); },
        meta: function(param) { return $resource('/api/meta/'+param); }
    }
})

and calling the service from the controller with:

$scope.meta = MyService.meta('url_param').query();

not sure this is the cleanest angular.js solution, but it works!

Solution 3

One way of doing it is to inject the service into your controller:

angular.controller('controllerName', 
 ['$scope', 'Transaction',
   function($scope, transactionService) {
      ...
   }
]);

Then you can access an instance of your service through the transactionService parameter.

EDIT

check out this fiddle Tell me if this is close enough to what you are trying to do

Share:
31,549
daydreamer
Author by

daydreamer

Hello Viewer, Some of the places to see my work are BonsaiiLabs My Website

Updated on August 17, 2020

Comments

  • daydreamer
    daydreamer almost 4 years

    I have a controller which is dependent on a TransactionService. One of the method is

    $scope.thisMonthTransactions = function () {
        $scope.resetTransactions();
        var today = new Date();
        $scope.month = (today.getMonth() + 1).toString();
        $scope.year = today.getFullYear().toString();
        $scope.transactions = Transaction.getForMonthAndYear();
    };
    

    The TransactionService looks like

    angular.module('transactionServices', ['ngResource']).factory('Transaction', function ($resource, $rootScope) {
        return $resource('/users/:userId/transactions/:transactionId',
            // todo: default user for now, change it
            {userId: 'bd675d42-aa9b-11e2-9d27-b88d1205c810', transactionId: '@uuid'},
            {
                getRecent: {method: 'GET', params: {recent: true}, isArray: true},
                getForMonthAndYear: {method: 'GET', params: {month: 5, year: 2013}, isArray: true}
            });
    });
    

    As you can see the method getForMonthAndYear depends on two parameters month and year, which are hardcoded right now as params: {month: 5, year: 2013}. How can I pass this data from my controller?

    I tried injecting rootScope in TransactionService, but that did not help(meaning I do not know how to use it probably).

    Also Angular ngResource documentation doesn't recommend any way to perform this.

    Can someone please guide here?

    UPDATE
    My Controller looks like

    function TransactionsManagerController($scope, Transaction) {
    
        $scope.thisMonthTransactions = function () {
            $scope.resetTransactions();
            var today = new Date();
            $scope.month = (today.getMonth() + 1).toString();
            $scope.year = today.getFullYear().toString();
    
            var t = new Transaction();
            $scope.transactions = t.getForMonthAndYear({month: $scope.month});
        };
    }
    

    and I change service method to

    getForMonthAndYear: {method: 'GET', params: {month: @month, year: 2013}, isArray: true}
    

    I look at the console.log and it says

    Uncaught SyntaxError: Unexpected token ILLEGAL transaction.js:11
    Uncaught Error: No module: transactionServices