0

I am sure this question has been already asked before, but I could not see or find a best explanation of it, therefore I would like to re-ask the same question and open the thread for more clear answers with some examples.

My goal is to display teams and its ranking, note: for displaying ranking I have a separate function that gets the ranking of team depending on their score field in db.

I have two functions within a TeamController as below:

        tm.showAllByClass = function (classId) {
            TeamService.showAllByClass(classId).then(function (response) {
                tm.teamsInClass = response.data;
            }).catch(function (error) {
                $scope.result = error;
            });
        };

        tm.ranking = function (classId, teamId) {
            TeamService.ranking(classId, teamId).then(function (response) {
                return response.data;
            }).catch(function (error) {
                $scope.result = error;
            });
        };

        <tr ng-repeat="tm in team.teamsInClass.data">
                <td>{{tm.group_number}}</td>
                <td>{{tm.role.name}}</td>
                <td>{{tm.ranking(tm.class_id, tm.id)}}</td>
                <td>{{tm.amount | currency}}</td>
        </tr>

And this is the function in backend part that gets all teams:

public function findAllTeamsInClass($classId)
{
    return Team::where('class_id', '=', $classId)->with('role', 'business')->get();
}

// return rank of team
public function teamRanking($classId, $teamId){
    return 3; // for sake of simplicity I just return a static value
}

Is there any way I can attach teamRanking function directly to the team entitiy as relationship or something?

For some reason tm.ranking() is not returning anything, how can I call a function that returns a value within the ng-repeat.

artan
  • 45
  • 9
  • For sure, make a `$http` *request* inside `ngRepeat`, is really a bad practice. Also I doubt that you don't receive an error like `infinite digest` or something like this.. – developer033 Aug 14 '16 at 23:04
  • @developer033, I totally agree with you, and I had no choice of doing it, could you tell me what is the other way or the best way how to handle such cases? – artan Aug 14 '16 at 23:14
  • I would greatly appreciate your help on this as it is very important for me to understand how one would handle this.. would be even greater if you could explain it with some examples. – artan Aug 14 '16 at 23:15
  • You have to change the response in your `back-end`, joining tables and so on.. all should come from back-end. – developer033 Aug 14 '16 at 23:18
  • @developer033, I dont have a seperate table for storing the ranking of teams, all I have is a field called 'score' in teams table, but I have a function that finds the rank for each team like this: rankingTeam($teamId) which returns the rank number. I am not quite sure how do I attach this into this: public function findAllTeamsInClass($classId) { return Team::where('class_id', '=', $classId)->with('role', 'business')->get(); } – artan Aug 15 '16 at 01:19

2 Answers2

0

You might have the same answer here: https://stackoverflow.com/a/26400951/6715875

you can simply call a function inside ng-repeat same as normal one.

Community
  • 1
  • 1
Ramin Esfahani
  • 190
  • 1
  • 6
0

Since the fetch of individual rankings is asynchronous, those operations need to be chained from the fetch of the list of teams.

team.showAllByClass = function (classId) {
    TeamService.showAllByClass(classId).then(function (response) {
        team.teamsInClass = response.data;
        //return for chaining
        return team.teamsInClass;
    }).then(function(teamsInClass) {
        promiseArray = [];
        for (var iTeam=0; iTeam<teamsInClass.length; iTeam++) {
            //IIFE
            (function (iTeam) {
                var iPromise = TeamService.ranking(classId, iTeam.id);
                iPromise = iPromise.then(function(response) {
                     var ranking = response.data;
                     team.teamsInClass[iTeam].ranking = ranking;
                     return ranking;
                });
                promiseArray.push(iPromise);
            })(iTeam);
            //end IIFE
        };
        //return for chaining
        return $q.all(promiseArray);
    }).then(function(rankingArray) {
        console.log("All rankings fetched");        
    }).catch(function (error) {
        $scope.result = error;
    });
};

The above example fetches the list of teams and then creates a list of promises that attach each ranking to each team. It uses $q.all to chain the list of promises.

The HTML

    <tr ng-repeat="tm in team.teamsInClass">
            <td>{{tm.group_number}}</td>
            <td>{{tm.role.name}}</td>
            <td>{{tm.ranking || 'PENDING' }}</td>
            <td>{{tm.amount | currency}}</td>
    </tr>

The ranking will display as PENDING until the data is retrieved from the API.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • I did the same thing, just that have done it from the backend-side... I will accept this as correct asnwer :) – artan Aug 16 '16 at 23:59