0

I'm trying to pass an id from one controller to another. I have a select menu that on selection will navigate you to the appropriate tournament. I would like to retrieve the tournament._id value in a different controller and then query that tournament for data. I'm new to angular and any help is appreciated. Thanks!

select menu

<select class="form-control" ng-model="vm.selectedTournamentId" ng-change="vm.showTournament()" >
  <option value="">Select a tournament</option>
  <option ng-repeat="tournament in vm.tournaments" value="{{ tournament._id }}">{{ tournament.name }}</option>
</select>

app.js

.controller('NavigationController', NavigationController);
NavigationController.$inject = ['TournamentService', '$q', '$location', '$scope', '$filter', '$state'];
function NavigationController(TournamentService, $q, $location, $scope,  $filter, $state) {
  var vm = this;
  vm.tournaments = TournamentService.query();
  vm.showTournament = function() {
    var tournament = TournamentService.query({id: vm.selectedTournamentId}, function() {
    vm.selectedTournament = tournament[0]
    $state.go('dashboard.tournament')
    });
  }
}

dashboard.js

angular.module('Dashboard',[]).controller('DashboardController',
DashboardController).factory('TournamentService', TournamentService).factory('UserService', UserService).factory('TeamService', TeamService)

DashboardController.$inject = ['$scope','TournamentService','TeamService','UserService','$q'];

function DashboardController($scope, TournamentService, TeamService, UserService, $q) {
  var vm = this;
  var tournaments = TournamentService.query();
  var users = UserService.query();
  var teams = TeamService.query()

  $q.all([tournaments, users, teams]).then(function(results) {
    vm.users = users;
    vm.availablePlayers = users;
    vm.tournaments = tournaments;
    vm.teams = teams;
  })
}
TournamentService.$inject = ['$resource'];
  function TournamentService($resource) {
   return $resource('/api/tournaments/:id',{cache: true},{tournament: '@tournament'});
  }
UserService.$inject = ['$resource'];
  function UserService($resource) {
  return $resource('/api/users/:id', {cache: true},{user: '@user'})
}
TeamService.$inject = ['$resource'];
  function TeamService($resource) {
  return $resource('/api/teams/:id',{cache: true}, {team: '@team'})
  }






}());
user1576738
  • 113
  • 8
  • Possible duplicate of [pass data between controllers](http://stackoverflow.com/questions/18142008/pass-data-between-controllers) – Anton Poznyakovskiy Feb 17 '16 at 23:00
  • Can you add your `state` config also?? It feels like you should send the `selectedTournamentId ` as a param to the state and then do the query on the next controller instead – GonzoGhanem Feb 17 '16 at 23:17

2 Answers2

1

Since you are using ui-router, I think what would be best for you to do here is to use $stateParams.

Instead of this:

  vm.showTournament = function() {
    var tournament = TournamentService.query({id: vm.selectedTournamentId}, function() {
    vm.selectedTournament = tournament[0]
    $state.go('dashboard.tournament')
    });
  }

Do this:

  vm.showTournament = function() {
    var tournament = TournamentService.query({id: vm.selectedTournamentId}, function() {
        vm.selectedTournament = tournament[0];
        $state.go('dashboard.tournament', {tournamentId: vm.selectedTournamentId});
    });
  }

The difference would be in the $state.go. Notice how I added an object with a property of tournamentId which equals the selected tournament id. This property will be passed to the next state you go to, which is dashboard.tournament.

Now in your second controller, you would also need to inject $stateParams and then access that tournament property by doing $stateParams.tournamentId. So you could set a variable to or like vm.tournament = $stateParams.tournamentId.


In order for this all to work, however, you would need to set some kind of param on the state that you are trying to send the tournament or tournament ID to.

Method 1:

$stateProvider
    .state('dashboard.tournament', {
        url: '/dashboard/tournament/:tournamentId'
        templateUrl: //...,
        controller: //...
    });

The above has an :tournamentId spot in the URI which waits for the stateParams value to be set upon going to the state. So this would show something like /dashboard/tournament/7 if you did $state.go('dashboard.tournament', {id: 7});.

Method 2:

$stateProvider
    .state('dashboard.tournament', {
        url: '/dashboard/tournament'
        templateUrl: //...,
        controller: //...,
        params: {
            tournamentId: null
        }
    });

Noticed how we removed :tournamentId from the url value.

You would set the stateParams the same way using something like $state.go('dashboard.tournament', {tournamentId: 7});, however now nothing will be added to the URI.

In both method 1 and method 2, you can access the tournamentId value in your second controller via $stateParams.tournamentId.

Which method should you use?

The only difference really is that method 2 will hide the param value from the URI. This is especially useful in abstract states, for example, where there should be no URI visible at all. Otherwise, they're basically the same -- just minor differences and a different way of achieving the same thing.

If you want your URL to look like http://domain.com/dashboard/tournament/7, then use method 1.

If you want your URL to look like http://domain.com/dashboard/tournament, then use method 2.

Refer to the routing docs for more info.

Lansana Camara
  • 9,497
  • 11
  • 47
  • 87
  • No problem. Feel free to accept the answer if you feel it correctly answered your question, that way future users with the same issue know it will resolve their problem. – Lansana Camara Feb 18 '16 at 15:31
0

One way of achieving this will be passing the tournament id to the dashboard controller as a state parameter, so in this way when you select the tournament from the menu you will be redirected to the dashboard of that specific tournament.

Add the parameter to your state url on $stateProvider:

.state('app.dashboard', {
     url: '/dashboard/:tournamentId',

On your app.js (Menu Controller):

$state.go('dashboard.tournament',{'tournamentId': vm.selectedTournamentId});

and access it on your DashboardController using $stateParams (don't forget to inject $stateParams to your controller):

var tournamentId = $stateParams.tournamentId;