Reputation: 27
Dear all I am having trouble with the scope of my $scope or how should I put it.
I am retrieving the data from my Service successfully but I´m having trouble with accessing $scope.players and $scope.tournament and I think it has something to do with being inside the service call. If I console.out() inside the service call everything is just fine. How can I be able access the data which is inside of the service call.
Version 1: Here console log simply states undefined.
.controller('SelectCtrl', ['$scope','$stateParams', '$location', '$window','playerService','tournamentService', function ($scope, $stateParams, $location, $window, playerService, tournamentService) {
init();
function init() {
playerService.getPlayers().then(function (data) {
$scope.players = [];
angular.forEach(data, function (player, index) {
$scope.players.push(player.info);
});
});
tournamentService.getTournaments().then(function (data) {
var result = data.filter(function (element) {
if (element.ID == $stateParams.id) {
return true;
} else {
return false;
}
});
$scope.tournament = result;
});
};
console.log($scope.tournament);//undefined
console.log($scope.players); //undefined
}
Version 2:, Here console log simply states the Object {then: function, catch: function, finally: function} Which is not what I wan´t I want the data to be able to display it in my view.
.controller('SelectCtrl', ['$scope','$stateParams', '$location', '$window','playerService','tournamentService', function ($scope, $stateParams, $location, $window, playerService, tournamentService) {
init();
function init() {
$scope.players = playerService.getPlayers().then(function (data) {
$scope.players = [];
angular.forEach(data, function (player, index) {
$scope.players.push(player.info);
});
});
$scope.tournament = tournamentService.getTournaments().then(function (data) {
var result = data.filter(function (element) {
if (element.ID == $stateParams.id) {
return true;
} else {
return false;
}
});
$scope.tournament = result;
});
};
console.log($scope.tournament);//Object {then: function, catch: function, finally: function}
console.log($scope.players);//Object {then: function, catch: function, finally: function}
}
Your help is really appreciated!
The Services:
.factory('playerService', function ($http,$q) {
return {
getPlayers: function () {
//return the promise directly.
var deferred = $q.defer();
$http.get(webServiceUrl + 'api/Player/GetAllPlayers')
.success(function (data) {
//resolve the promise as the data
deferred.resolve(data);
}).error(function () {
deferred.reject();
});
return deferred.promise;
}
}
})
.factory('tournamentService', function ($http,$q) {
return {
getTournaments: function () {
//return the promise directly.
var deferred = $q.defer();
$http.get(webServiceUrl + 'api/Tournament/GetAllTournaments')
.success(function (data) {
//resolve the promise as the data
deferred.resolve(data);
}).error(function () {
deferred.reject();
});
return deferred.promise;
}
}
})
Part of the view:
<h1 style="display: inline-block; margin-left:15px;">Enter <i>{{tournament.Name}}</i></h1>
<div class="row">
<div class="selectinforow">
<div class="col-xs-2 selectinfo">
<span>{{tournament.EntryFee}}$</span></br>
<span>Entry Fee</span>
</div>
<div class="col-xs-2 selectinfo">
<span>{{tournament.Entries}}</span></br>
<span>Entries</span>
</div>
<div class="col-xs-2 selectinfo">
<span>{{tournament.Size}}</span></br>
<span>Max Size</span>
</div>
<div class="col-xs-2 selectinfo">
<span>{{tournament.StartTime}}</span></br>
<span>Start Date</span>
</div>
<div class="col-xs-2 selectinfo">
<span>{{tournament.Entryfee*tournament.Entries}}$</span></br>
<span>Winnings</span>
</div>
</div>
</div>
Upvotes: 0
Views: 653
Reputation: 4882
Your code is executed before the promise
response.
If you need to code "procedurally", you should $watch
the scope variable as below to detect any changes.
For example:
$scope.$watch('tournament', function() {
console.log($scope.tournament);
}, true);
Upvotes: 0
Reputation: 10430
So if you read your code carefully you will notice you are using a promise on the following line:
tournamentService.getTournaments().then(function (data) {
// [your data is set here - AFTER the service call runs]
}
// [your print is here - run BEFORE service call runs]
The key to the "then" statement is it isn't executed right away, but is instead run when data is returned from the service call. In other words, you have your print in the wrong spot - I would expect the values to be undefined there. If you move the console.log statements into the promise (then) - I would expect to see the valid values. You can also put a break point in the browser debugger to see the values in the "then" function if you want to validate that things are working. Hope this puts you on the right track!
EDIT
Once the promise completes, angular automatically updates the view. Lets say you have the following in your view (just an example):
<h1 ng-bind="tournament.Title">Default Text</h1>
When the view/page loads you will see "Default Text". After the promise completes, if a tournament has been loaded, angular will automatically update the "h1" to now have the Title for that tournament. This happens because angular automatically runs an "$apply()" after a promise completes.
Upvotes: 2