Trigger.io + Angular.js and updating a view after calling forge.ajax

Having a problem, and so far couldn't get any solutions for seemingly similar SO questions to work. Problem is this:

Using Trigger.io's forge.ajax, my Angular.js view is not updated after the data is returned. I realize this is because forge.ajax is an asychronous function, and the data is returned after the view has already been displayed. I have tried to update the view by using $rootScope.apply(), but it doesn't work for me as shown in the many examples I have seen.

See the Controller code below:

function OfferListCtrl($scope) {

   $scope.offers = [];

   $scope.fetchOffers = function(callback) {

       $scope.offers  = [];

       var successCallback = function(odataResults) {
           var rawJsonData = JSON.parse(odataResults);
           var offers = rawJsonData.d;
           callback(offers);
        };

       var errorCallback = function (error){
            alert("Failure:" + error.message);
       };

       forge.request.ajax({
           type: 'GET',
           url: 'https://www.example.com/ApplicationData.svc/Offers',
           accepts: 'application/json;odata=verbose',
           username: 'username',
           password: 'password',
           success: successCallback,
           error: errorCallback
       });

    };

    $scope.fetchOffers(function(offers) {
        $scope.offers = offers;
        forge.logging.info($scope.offers);
    });
}

All the code there works fine, and $scope.offers gets populated with the Offer data from the database. The logging function shows the data is correct, and in the correct format.

I have tried using $rootScope.apply() in the logical places (and some illogical ones), but cannot get the view to update. If you have any ideas how I can get this to work, I would greatly appreciate it.

Edit: Added HTML

The HTML is below. Note the button with ng-click="refresh()". This is a just a workaround so I can at least see the data. It calls a one-line refresh function that executes $rootScope.apply(), which does update the view.

   <div ng-controller="OfferListCtrl">
        <h1>Offers</h1>
      <ul>
        <li ng-repeat="offer in offers">
            <p>Description: {{offer.Description}}<br />
               Id: {{offer.Id}}<br />
              Created On: {{offer.CreatedOn}}<br />
              Published: {{offer.Published}}<br />
            </p>
        </li>
      </ul>
  <input type="button" ng-click="refresh()" value="Refresh to show data" />
    </div>

You need to change

$scope.fetchOffers(function(offers) {
    $scope.$apply(function(){
        $scope.offers = offers;
    });
    forge.logging.info($scope.offers);
});

It is because all changes to the $scope has to be made within the angular scope, in this case since you are calling ajax request using forge the callback is not executing within the angular framework, that is why it is not working.

You can use $scope.$apply() in this case to execute the code within angular framework.

Look at the $apply() methods doc

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). Because we are calling into the angular framework we need to perform proper scope life-cycle of exception handling, executing watches.

do this

function MyController($scope, myService) 
{
    myService.fetchOffers(data){
        //assign your data here something like below or whateever
        $offers = data 
        $scope.$apply();
    }
});

Thanks Dhiraj

When I do that I have an error like : "$digest already in progress"... I'm Working with $q...

Someone knwo how I can resolve this issue ?

yes, this is caused where ur data comes fast enough and angular has not finished his rendering so the update cant update "outside" angular yet.

so use events: http://bresleveloper.blogspot.co.il/2013/08/angularjs-and-ajax-angular-is-not.html