leticia
leticia

Reputation: 2388

Ajax call to an external API to get a JSON - using JSONP

I need to perform an Ajax call to an external API to get a JSON formatted data, but I'm not getting any result.

I have this controller:

angular.module('myApp').controller('myCtrl', function($scope, MyService) {

        $scope.list = MyService.fetchAll();
});

And this Service, to make an Ajax request to another domain:

var MyService = function($http) {
    this.fetchAll = function() {
        console.log('here1');

        $http.jsonp('http://other.domain.com/list/?allback=JSON_CALLBACK').success(function(data) 
            console.log('here2');
            return angular.fromJson(data);
        }).error(function(data, status, headers, config) {
            console.log('here3');
            console.log(status);
        });
    };
};

angular.module('myApp').service('MyService', MyService);

My Json returned is just:

[1,2,3,4,5]

When execute the code/request I didn't get the result excepted, the code in .success() never is executed. I get in console:

here1
here3
404 

Any suggestion about how is the best approach to implement this will be appreciated. I'm newbie on this.

Upvotes: 1

Views: 240

Answers (3)

leticia
leticia

Reputation: 2388

For archive purpose, I finally did it as follow (personally I think is the simplest approach):

In my service I have this:

this.fetchAll = function() {

        return $http.jsonp("<here API Endpoint>").then(function(response){
                return response.data;
        });
};

And in my controller:

MyService.fetchAll().then(function(data) {
    requestResult = data;
});

Just a note: The main problem was that the requested API doesn't returns the callback reference, just return the JSON [1,2,3,4,5]. Instead is needed to return something like "JSON_CALLBACK([1,2,3,4,5])"

Upvotes: 1

Fedaykin
Fedaykin

Reputation: 4552

Please keep in mind that the external json request is an asynchronous operation, and that´s the root of your problem, when you call ´fetchAll()´ it will not wait for the request to complete and to return the values. To correct that you must return a promise from your service and assign your data on it´s ´then´ function.

var MyService = function($http, $q) {
    this.fetchAll = function() {
        var deferred = $q.defer();


        $http.jsonp('http://other.domain.com/list/?allback=JSON_CALLBACK').success(function(data){ 
            console.log('here2');
            deferred.resolve(angular.fromJson(data));
        }).error(function(data, status, headers, config) {
            console.log('here3');
            deferred.reject(status);
        });

        return deferred.promise;
    };
return this;
};

And at your controller, do this:

angular.module('myApp').controller('myCtrl', function($scope, MyService) {
    MyService.fetchAll.then(function(data){
        $scope.list = data;
    })
}, function(error){
    console.log(error);
    // Decide what to do with your $scope.list in case of an error
    $scope.list = null;
});

Upvotes: 1

sylwester
sylwester

Reputation: 16498

Your console.log(status) printing 404 which means:

The 404 or Not Found error message is a HTTP standard response code indicating that the client was able to communicate with a given server, but the server could not find what was requested.

double check url address.

you can make ajax call using factory that way: (sample here http://jsfiddle.net/ty69u6tL/4/)

FACTORY:

app.factory('MyService', function ($http, $q) {

    /////////////////////////////////////////////////////////////
    // put your url here:////////////////////////////////////////
    /////////////////////////////////////////////////////////////
    var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";


    this.fetchAll = function () {
        var deferred = $q.defer();
        console.log('here1');
        $http.jsonp(url).success(function (data) {
            console.log('here2');
            deferred.resolve(angular.fromJson(data));
        }).error(function (data, status, headers, config) {
            console.log('here3');
            console.log(status);
            deferred.reject(data, status, headers, config);
        });
        return deferred.promise;
    };
    return this;
});

CONTROLLER:

app.controller('jsonp_example', function ($scope, MyService) {
    $scope.data = {};

    $scope.doRequest = function () {
        MyService.fetchAll().then(onSucess, onError);

        function onSucess(response) {
            $scope.data = response;
        }

        function onError() {
            alert("Cant get data ");
        }        
    };
 });

HTML*

<div ng-app="app">
    <div ng-controller="jsonp_example">
        <button ng-click="doRequest()">Make JSONP request</button> <pre> {{data | json}}</pre>

    </div>
</div>

Upvotes: 1

Related Questions