Jonas
Jonas

Reputation: 784

AngularJS: How to pass the id through a service method in the controller

I am developping an AngularJS webapp. I have following routeconfig:

  $routeProvider.
    when("/drivers", {templateUrl: "partials/drivers.html", controller: "driversController"}).
    when("/drivers/:id",{templateUrl: "partials/driver.html", controller: "driverController"}).
    otherwise({redirectTo: '/drivers'});
}]);

So to pass the ID of JSON, I use following method in my service.js file

F1API.getDriverDetails = function(id) {
        return  $http({
            method: 'JSONP', 
            url: 'http://localhost:8000/app/data/' + id + '/driverStandings.json?callback=JSON_CALLBACK'
        });
    }

    F1API.getDriverRaces = function(id) {
        return  $http({
            method: 'JSONP', 
            url: 'http://localhost:8000/app/data/' + id + '/results.json?callback=JSON_CALLBACK'
        });
    }

    return F1API;
  });

But now there is the part where I'm stuck. I need this method to assign a driver and his races in an object. But I need the id for this, so I tried in my controller.js

/* Driver controller */
controller('driverController', function($scope, $routeParams, F1APIservice) {


    $scope.id = $routeParams.id;
    $scope.races = [];
    $scope.driver = null;

    F1APIservice.getDriverDetails(id).success(function(response){
      $scope.driver = response.MRData.StandingsTable[0].DriverStandings[0];
    });

    F1APIservice.getDriverRaces(id).success(function(response){
      $scope.races = response.MRData.RaceTable.Races;
    });
});

Id is unknown while I build my webapp. What do I do wrong?

Upvotes: 3

Views: 2110

Answers (2)

Beyers
Beyers

Reputation: 9108

The better approach is to decouple your controller from $routeParams. To achieve that use $routeProvider's resolve functionality:

$routeProvider.
    when("/drivers/:id", {
        templateUrl: "partials/driver.html",
        controller: "driverController",
        resolve: {
            'id': function($route) {
                return $route.current.params.id);
            }
        }
    })

Using the above, Angular will make id available to your controller:

controller('driverController', function($scope, id, F1APIservice)

Since resolve is promise aware, an alternative approach could even be to do your service call inside resolve:

$routeProvider.
    when("/drivers/:id", {
        templateUrl: "partials/driver.html",
        controller: "driverController",
        resolve: {
            'driver': function($route, F1APIservice) {
                return F1APIservice.getDriverDetails($route.current.params.id);
            }
            'races': function($route, F1APIservice) {
                return F1APIservice.getDriverRaces($route.current.params.id);
            }
        }
    })

The driver and races get injected into your controller:

controller('driverController', function($scope, driver, races, F1APIservice)

Upvotes: 1

Sean Walsh
Sean Walsh

Reputation: 8344

In your controller, you assign $routeParams.id to $scope.id, but then you call getDriverDetails and getDriverRaces with just id, which is undefined. You need to call them like this: getDriverDetails( $scope.id ).

Upvotes: 3

Related Questions