1

I am working on a SPA website to display softball stats for the softball teams I manage. This specific questions is related to using angularjs to display the results of an api call, where the api call is based on what is selected in a selector.

The two models I am working with:

public class Team
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string WeekNight { get; set; }
    public int? Year { get; set; }

    public int ManagerId { get; set; }
    public int LeagueId { get; set; }

    public virtual Manager Manager { get; set; }
    public virtual League League { get; set; }
    public virtual ICollection<Game> Games { get; set; }
    public virtual ICollection<Player> Players { get; set; }
    public virtual ICollection<Award> Awards { get; set; }
}

public class Award
{
    public int Id { get; set; }
    public int AwardTypeId { get; set; }
    public int PlayerId { get; set; }
    public int TeamId { get; set; }

    public virtual AwardType AwardType { get; set; }
    public virtual Player Player { get; set; }
    public virtual Team Team { get; set; }

}

In part of my view I have the following which creates a selector and populates it with all of my teams:

var teamService = angular.module('teamService', ['ngResource']);

teamService.factory('Team', ['$resource',

  function($resource) {
    return $resource('api/v1/teams/:teamId', {}, {
      query: {
        method: 'GET',
        params: {
          teamId: '@teamId'
        },
        isArray: true
      },
      post: {
        method: 'POST'
      },
      update: {
        method: 'PUT',
        params: {
          teamId: '@teamId'
        }
      },
      remove: {
        method: 'DELETE'
      }
    });
  }
]);;


var teamController = angular.module('teamController', []);

teamController.controller('teamListController', ['$scope', 'Team',
  function($scope, Team) {
    $scope.teams = Team.query();
  }
]);
<div class="col-md-12">
  <div class="award-team-select col-md-offset-4 col-md-4">
    <select class="form-control" ng-controller="teamListController">
      <option ng-repeat="t in teams">{{t.year}} - {{t.name}} ({{t.weekNight}}'s)</option>
    </select>
  </div>
</div>

Connected to my webAPI this works correctly and will return something like:

2015 - SomeTeamName (Monday's)

Cool. Now underneath that I want to display the awards for that selected team. I have a working url created as such:

config.Routes.MapHttpRoute(
            name: "TeamAwards",
            routeTemplate: "api/v1/teams/{id}/awards/{awardId}",
            defaults: new { controller = "award", awardId = RouteParameter.Optional }
        );

Using Googles Advanced Rest Cient I can get the awards for a specific team... and here is where I am struggling. Underneath the selector I have some pretty formatted divs to display the awards. I want to show the awards for the team in the selector.

I tried adding another function to my factory that calls the "api/v1/teams/{id}/awards/{awardId}" url but I am not sure how to get the teamId from the selector linked into the new factory function. I was then going to make a 'teamAwardController' that gets the data from the factory to be displayed in the divs below the selector.

In short I want to be able to display awards, where awards.teamId == the Id of the team in the selector.

Any advice would be awesome. Thanks!

Adding an edit:

So based on current feed back I am also taking a stab at accessing the child awards in the TeamController. So if I have:

 <div ng-controller="teamController">
   <div class="col-md-12">
     <div class="award-team-select col-md-offset-4 col-md-4">
       <select class="form-control">
         <option ng-repeat="t in teams">{{t.year}} - {{t.name}} ({{t.weekNight}}'s) </option>
       </select>
     </div>
   </div>

  <div class="col-md-4 col-sm-6 col-xs-12">
      // awards to go here
  </div>

</div>  // end teamController div

... I tried using ng-model="teams" up in the teamController and then ng-bind="teams" in the awards section as well as trying {{teams.awards}} but no dice. Am I way off here?

5
  • Have you considered simply returning the awards as part of the teams list? It looks like your Team model already has the awards as children. Commented Mar 16, 2016 at 20:47
  • I was looking at doing this but It would have to be in a nested ng-repeat. my issue is that the ng-repeat for teams is in a select tag which is closed and so is its parent div. Then further down another div is where I am trying to display the awards. Commented Mar 17, 2016 at 13:20
  • So basically you need a way to get the selected team ID, pass that into your teamAwardController within which you will call your API to get the team's awards. Is that right? Commented Mar 17, 2016 at 14:05
  • Yup! so the drop down uses teamController which calls api/v1/teams/{id}. Then I would have a teamAwardsController which calls api/v1/teams/{teamId}/awards/{id}. But I don't know how to populate teamID. Also, I have been trying to just use the TeamController and get awards via the child attributes but I am unsure how to get them. I am still in under the div containing the TeamController, I tried using ng-model="teams" and then using ng-bind down in the awards div, but no luck. Commented Mar 17, 2016 at 19:33
  • Check out the answer I provided below - you can maintain your separate controller modules. I'm not sure where or how you were trying to use ng-model and ng-bind in your updated question. Commented Mar 17, 2016 at 20:59

2 Answers 2

0

You need to bind the <select> to a variable in your controller, then use that variable to display the correct awards. Something like this:

 <div ng-controller="teamController">
   <div>
       <select ng-model="selectedTeamId">
         <option ng-repeat="t in teams" value="{{t.id}}">{{...}}</option>
       </select>
   </div>

  <div>
      // awards to go here
      {{awardInfo}}
  </div>
</div>

Javascript:

teamController.controller('teamListController', ['$scope', 'Team', 'Award',
    function($scope, Team, Award) {

        $scope.teams = Team.query();
        $scope.selectedTeamId = null;
        $scope.awardInfo = null;

        $scope.$watch('selectedTeamId', function(idValue) {
            if (idValue !== null) {
                $scope.awardInfo = Award.query({ teamId: idValue });
            }
        });
    }
]);
Sign up to request clarification or add additional context in comments.

Comments

0

Since you need to share the selected team ID between controllers, you have to use something to accomplish this. Angular has several options for this, but in this case I think a value would suffice. Also, I would switch your select to use ng-options to make this whole process easier.

There are many ways to implement this, but here is one sample that should help get you started. I faked up some data and also everything is just using one large angular.module() chain, both of which you probably should not do in a production app.

I'm using a value to share the team ID between the controllers. A value is nothing more than a persistent object that you can inject in any of your Angular modules. In the teamAwardsController I am watching for a change in the SelectedTeam.id property - you'll have to handle when no team is selected, but that should be easy. In teamListController I assign the SelectedTeam value to a $scope level variable so that it can be read and set directly in the view.

First the JS:

angular.module('app', [])
    .value('SelectedTeam', {
        id: -1
    })
    .service('FakeDataService', function() {
        this.GetTeams = function() {
            return [{
                id: 1,
                name: 'Portland Timbers',
                weekNight: 'Monday',
                year: '2016'
            }, {
                id: 2,
                name: 'Seattle Sounders',
                weekNight: 'Tuesday',
                year: '2016'
            }, {
                id: 3,
                name: 'LA Galaxy',
                weekNight: 'Thursday',
                year: '2016'
            }, {
                id: 4,
                name: 'San Jose Quakes',
                weekNight: 'Wednesday',
                year: '2016'
            }, ];
        };
    })
    .controller('teamListController', function($scope, FakeDataService, SelectedTeam) {
        $scope.selectedTeam = SelectedTeam;
        $scope.teams = FakeDataService.GetTeams();
    })
    .controller('teamAwardsController', function($scope, $log, SelectedTeam) {
        $scope.selectedTeam = SelectedTeam;
        $scope.$watch('selectedTeam.id', function() {
            $log.info('Team changed to ' + $scope.selectedTeam.id);
        });
    });

And now some sample markup:

<div ng-app='app'>
    <div ng-controller='teamListController'>
        <select ng-model='selectedTeam.id' ng-options='t.id as (t.year + " - " + t.name + " (" + t.weekNight + "s)") for t in teams'></select>
    </div>
    <div ng-controller='teamAwardsController'>
        Here is where would list the selected team's awards.
    </div>
</div>

1 Comment

OK. I got it! The answer you have here is what I originally had in mind for how I would get the data, but your very first comment to my OP really does make the most sense and that's what Mikes solution does. I implemented this solution first, but since both controllers have the selectedTeam param I simply expand the div containing the controller reference to contain the awards dive and then used Mikes solution below. Thanks for all the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.