Search code examples
angularjsebay-api

using data from a callback from Ebay api in Angularjs


I am trying to use the ebay api in an angular.js app.

The way the api works by itself is to pass data to a callback function and within that function create a template for display. The problem that I am having is in adding the data returned from the callback to the $scope. I was not able to post a working example as I didnt want to expose my api key, I am hoping that the code posted in the fiddle will be enough to identify the issue.

    eBayApp.controller('FindItemCtrl', function ($scope) {

globalFunc = function(root){

 $scope.items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
  console.log($scope.items); //this shows the data
}

  console.log($scope.items); //this is undefined

})

http://jsfiddle.net/L7fnozuo/


Solution

  • The reason the second instance of $scope.items is undefined, is because it is run before the callback function happens.

    The chances are that $scope.items isn't updating in the view either, because Angular doesn't know that it needs to trigger a scope digest.

    When you use the Angular provided async APIs ($http, $timeout etc) they have all been written in such a way that they will let Angular know when it needs to update it's views.

    In this case, you have a couple of options:

    1. Use the inbuilt $http.jsonp method.
    2. Trigger the digest manually.

    Option number 1 is the more sensible approach, but is not always possible if the request is made from someone else's library.

    Here's an update to the fiddle which uses $http.jsonp. It should work (but at the moment it's resulting in an error message about your API key).

    The key change here is that the request is being made from within Angular using an Angular API rather than from a script tag which Angular knows nothing about.

    $http.jsonp(URL)
       .success($scope.success)
       .error($scope.error);
    

    Option 2 requires you to add the following line to your JSONP callback function:

    globalFunc = function(root){
      $scope.items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
      console.log($scope.items); //this shows the data
      $scope.$apply(); // <--
    }
    

    This method tells Angular that it needs to update it's views because data might have changed. There's a decent Sitepoint article on understanding this mechanism, if you are interested.