Q:

When is $scope.$apply necessary for dealing with objects/arrays with Angular?

I'm working with the Soundcloud JS SDK to bring my Soundcloud favorites into a simple Angular app.
I wasn't able to get the user favorites to import in correctly until I used $scope.$apply.
function TopListCtrl($scope, $http, $modal) {
  $scope.getData = function(sc_user) {
     SC.get('/users/'+ sc_user +'/favorites', {limit: 200}, function(tracks){
     $scope.$apply(function() {
  if (Object.getOwnPropertyNames(tracks).length > 1) {
      $scope.likes = tracks;
      $scope.sortField = 'like.favoritings_count';
      $scope.reverse = true;
      $scope.sc_user = sc_user;
     } 
  else {
      alert("That user has 0 Soundcloud likes. So sad...")
     }
  }).error(function (data, status, headers, config) {          
             alert("Something went awry with that request. Double check that's a real Soundcloud username");         

        })
        }); 
  }

If you don't use $scope.apply, it doesn't work (and says SC.get not defined).
I'd like to understand a bit better why $scope.$apply is necessary.  I ask this because when I was just using the http api, I didn't need it.
function TopListCtrl($scope, $http, $modal) {
  $scope.getData = function(sc_user) {
     var url = 'http://api.soundcloud.com/users/'+ sc_user +'/favorites.json?client_id=0553ef1b721e4783feda4f4fe6611d04&limit=200&linked_partitioning=1&callback=JSON_CALLBACK';
    $http.jsonp(url).success(function(data) {
     if (Object.keys(data.collection).length > 0) {
      $scope.likes = data;
      $scope.sortField = 'like.favoritings_count';
      $scope.reverse = true;
      $scope.sc_user = sc_user;
     } 
    else {
      alert("That user has 0 Soundcloud likes. So sad...")
     }
  }).error(function (data, status, headers, config) {          
             alert("Something went awry with that request. Double check that's a real Soundcloud username");         
        });
  }

A:

Usually angular knows about the code that's executing because you're the one providing the function callbacks but it's angular that's actually calling them. After angular calls a function, it will call $apply sometime later to trigger a $digest cycle.  
If you don't know what a $digest cycle is, the concept is simple. During the $digest phase, angular will do a dirty check on every scope variable that's been set up with a $watch handler and check if it's changed; if it has angular will call its the corresponding $watch handler to update the view.
Getting back to the original question - when angular knows about your code, it will trigger a $digest cycle for you - so there is no need to call $apply explicitly. If you handle a jquery event, that's a different story. Angular has no idea that a $digest might be needed - how can it? So $apply is needed to trigger the $digest manually.

