Barlow96
Barlow96

Reputation: 57

How to update $scope variable with 'http get'?

Struggling to understand the concept of http requests and promises. I know the http request is asynchronous but have no idea how to implement a promise and return the data to update the $scope variable so that is accessible anywhere.

At the minute the $scope variable only prints out inside '.then'

Basically i'm trying to return the 'season_number' into an array so its displayed as:

Array[

{season_number: 1},
{season_number: 2},
{season_number: 3},
{season_number: 4},
{season_number: 5}

];

Code:

$scope.seasonDetails = [];

var getSeasons = function() {
var data = "";
 $http({
    method: 'GET',
    url: url

  })

  .then(function(response) {
    var tvSeasonDetails = [];
    for (var i = 0; i < response.data.seasons.length; i++) {
      tvSeasonDetails.push(response.data.seasons[i].season_number)
    }

    $scope.seasonDetails = tvSeasonDetails;
    console.log($scope.seasonDetails); //<----Variable displayed here

  })
}

  getSeasons();
  console.log($scope.seasonDetails); //<---- Empty Array displayed here

Upvotes: 1

Views: 1292

Answers (2)

jcaron
jcaron

Reputation: 17710

As you pointed out, $http.get() is asynchronous. So when you call getSeasons, it will not set the value of $scope.seasonDetails right away, but only after it receives a response.

So, yes, it won't be available in your call to console.log right after your call to getSeasons, but it will eventually get there once it's available.

If you just need the data to get in scope at some point (so it can be displayed in your page via ng-repeat or the like), then you don't need to do anything more. Angular will apply the changes when they arrive.

If you do need to manipulate the results, then you can either do it directly in the existing then, or have getSeasons return the $http promise, and add a new then after your call to getSeasons. Which is more relevant depends on your actual needs (e.g. getSeasons is called from several places but you have different post-processing depending on where it's called from or not).

Option 1:

var getSeasons = function() {
var data = "";
 $http({
    method: 'GET',
    url: url

  })

  .then(function(response) {
    var tvSeasonDetails = [];
    for (var i = 0; i < response.data.seasons.length; i++) {
      tvSeasonDetails.push(response.data.seasons[i].season_number)
    }

    $scope.seasonDetails = tvSeasonDetails;
    console.log($scope.seasonDetails); //<----Variable displayed here

    ... add your call to any function that needs access to $scope.seasonDetails here...
  })
}

Option 2:

var getSeasons = function() {
var data = "";
 // the only change is right here
 return $http({
    method: 'GET',
    url: url
  })

  .then(function(response) {
    var tvSeasonDetails = [];
    for (var i = 0; i < response.data.seasons.length; i++) {
      tvSeasonDetails.push(response.data.seasons[i].season_number)
    }

    $scope.seasonDetails = tvSeasonDetails;
    console.log($scope.seasonDetails); //<----Variable displayed here

  })
}

getSeasons().then(function()
{
   ... your call to whatever function needs $scope.seasonDetails here ...
});

Upvotes: 4

Andrew Shepherd
Andrew Shepherd

Reputation: 45232

In the case where you need to manipulate some results after seasonDetails has changed, you can use the function $scope.$watch(...)

 $scope.$watch('seasonDetails', function(newValue, oldValue) {
      console.log($scope.seasonDetails);
 });

Upvotes: 1

Related Questions