1

Here am trying to make a RESTful call to an external API. am trying to achieve 2 things in one call. So, I have one function with 2 nested functions within. The first one calls the search API to search for a product. The second one calls recommended API to retrieve recommendations based on the results from the first one.

My AngularJS Code is as follow;

 var walmartAssn= angular.module('myApp', ['ngResource']);

 walmartAssn.controller('walmartAssnController', function($scope,$resource) {
//define the API urls        
var urlSearchProductApi= 'http://api.walmartlabs.com/v1/search';
var urlRecProductApi='http://api.walmartlabs.com/v1/nbp';
//define API key
var keyApi='exampleKey123';

$scope.searchProductMethod= function(){
    //pass the value from the user input text box
    $scope.searchItem = $scope.item ;
               $scope.productId;
              //get the data from the Walmart product search API
              searchRequest = $resource(urlSearchProductApi, { callback: 
              "JSON_CALLBACK" }, { get: { method: "JSONP" }});

              //pass the input text as a parameter through a GET request
              $scope.searchedProducts = searchRequest.get({ apiKey: keyApi, 
              query: $scope.searchItem });

              console.log($scope.searchedProducts.$promise);
              $scope.searchedProducts.$promise.then(function(eventDetail){

                //fetch the ID of the first item
               $scope.productId = eventDetail.items[0].itemId;
              }); 

              recommendRequest = $resource(urlRecProductApi, { callback:    
              "JSON_CALLBACK" }, { get: { method: "JSONP" , isArray:true}});
              console.log(recommendRequest);

              $scope.recommendedProducts = recommendRequest.get({ apiKey: 
              keyApi, itemId: 42608121 });
              console.log($scope.recommendedProducts)
              $scope.recommendedProducts.$promise.then(function(){

                  $scope.recommendedProductsList = eventDetail;
                  console.log("Print recommended list");
                  console.log(eventDetail);
                  console.log($scope.recommendedProductsList);
                  console.log('End');
             });
  }     });   

In the above app, the first function returns result while the second function does not.

In chrome console am getting the following, not the fist function returns an array of JSONs while the second one was blocked.

enter image description here

While on the Network tab in the chrome console, i see the the call was successful, as in shown below;

enter image description here

Moreover, I have tried the URL with hard coded values in the browser and worked successfully.

Any help is appreciated, thanks in advance.

Emad Abdelhamid
  • 305
  • 5
  • 16
  • All of your code that relies on results from the first request has to come in or be called from the then portion of the promise. – Mike Feltman May 17 '16 at 17:30
  • Thanks Mike, not sure if am doing it right; `$scope.searchedProducts.$promise.then(function(eventDetail){ $scope.productId = eventDetail.items[0].itemId; }.then(function(){ $scope.recommendedProducts = recommendRequest.get({ apiKey: keyApi, itemId: 42608121 }); console.log($scope.recommendedProducts); $scope.recommendedProductsList = eventDetail; } )); ` – Emad Abdelhamid May 17 '16 at 18:05

1 Answers1

0

Assuming that the 2nd call does not depend on the first, I see that you are not defining eventDetail as an argument to the second method.

So, instead of:

$scope.recommendedProducts.$promise.then(function(){

It would be:

$scope.recommendedProducts.$promise.then(function(eventDetail){

If you actually mean to use the eventDetail from the first method (the one used with $scope.searchedProducts.$promise), then the whole second request code needs to be called from the first then handler, passing the data needed.

Something like:

var walmartAssn= angular.module('myApp', ['ngResource']);

walmartAssn.controller('walmartAssnController', function($scope,$resource) {
    //define the API urls        
    var urlSearchProductApi= 'http://api.walmartlabs.com/v1/search';
    var urlRecProductApi='http://api.walmartlabs.com/v1/nbp';
    //define API key
    var keyApi='exampleKey123';


    $scope.recommend = function(itemId) {
        var recommendRequest = $resource(urlRecProductApi, { callback:    
        "JSON_CALLBACK" }, { get: { method: "JSONP" , isArray:true}});
        console.log(recommendRequest);

        $scope.recommendedProducts = recommendRequest.get({ apiKey: 
        keyApi, itemId: itemId });
        console.log($scope.recommendedProducts);

        $scope.recommendedProducts.$promise.then(function(eventDetail){
            $scope.recommendedProductsList = eventDetail.items; // or just `eventDetail`?
            console.log("Print recommended list");
            console.log(eventDetail);
            console.log($scope.recommendedProductsList);
            console.log('End');
        });
    };

    $scope.searchProductMethod= function(){
        //pass the value from the user input text box
        $scope.searchItem = $scope.item ;
        $scope.productId;
        //get the data from the Walmart product search API
        var searchRequest = $resource(urlSearchProductApi, { callback: 
        "JSON_CALLBACK" }, { get: { method: "JSONP" }});

        //pass the input text as a parameter through a GET request
        $scope.searchedProducts = searchRequest.get({ apiKey: keyApi, 
        query: $scope.searchItem });

        console.log($scope.searchedProducts.$promise);
        $scope.searchedProducts.$promise.then(function(eventDetail){
            //fetch the ID of the first item
            $scope.productId = eventDetail.items[0].itemId;
            $scope.recommend($scope.productId);
        }); 

    };
});   

One more thing:

Why is isArray:true used only in recommendation but not in search?

Update

It might be worth trying a jQuery JSONP call to see if it works. Maybe the recommendation endpoint does not support JSONP. AngularJS returns 404 in this case according to https://stackoverflow.com/a/24893912/146656

Community
  • 1
  • 1
Meligy
  • 35,654
  • 11
  • 85
  • 109
  • I Have tried that, but by using print statements, it seems that the second function is not being hit at all – Emad Abdelhamid May 18 '16 at 14:56
  • `recommendRequest = $resource(urlRecProductApi, { callback:"JSON_CALLBACK" }, { get: { method: "JSONP" , isArray:true}}); console.log(recommendRequest);` where recommendedRequest doesn't print – Emad Abdelhamid May 18 '16 at 14:57
  • Verify the request in the browser to confirm the product ID is correct. Also, confirm if the `isArray` part is correct as it is. – Meligy May 18 '16 at 15:05
  • I already tried calling the URL manually from the browser, which worked find and returned the expected result. for some reason, in the console it shows status 404, while in the network tab, it shows status 200 OK – Emad Abdelhamid May 18 '16 at 15:22
  • It might be worth trying a jQuery JSONP call to see if it works. Maybe the recommendation endpoint does not support JSONP. AngularJS returns 404 in this case according to http://stackoverflow.com/questions/24072617/jsonp-request-gives-404-in-angular-app – Meligy May 18 '16 at 15:39