Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 
like image 389
daydreamer Avatar asked Jun 05 '13 03:06

daydreamer


3 Answers

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
like image 196
Lukus Avatar answered Oct 05 '22 11:10

Lukus


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!

like image 35
gru Avatar answered Oct 05 '22 11:10

gru


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

like image 33
mfeingold Avatar answered Oct 05 '22 13:10

mfeingold