1

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
1

2 Answers 2

4

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 ...
});
Sign up to request clarification or add additional context in comments.

3 Comments

I need to use '$scope.seasonDetails' in a function directly after this, but is always giving an empty array
Then either move the call to that function inside your existing then, or have getSeasons return a Promise (i.e. return $http.get(...)), and either call that function inside a then of this (i.e. getSeasons().then(function() { youcallhere }) or pass the promise to this function so it can then do the then itself.
Edited answer with two options.
1

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);
 });

2 Comments

Wouldn't a $watch add way more overhead than just a then on a Promise?
@jcaron I agree with you on this, there's no need to pollute your code with $scope.$watch unless it's a last resort when Promises can't achieve what you need.

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.