2

I am trying to call a web service using ajax and then pass the results to an angular controller. I cannot get the values out of the callback function to pass into a scope variable. I think it's just my bad understanding of how the callback function works.

here is the code:

function ajaxKimono(callback) {

    $.ajax({
          url:"https://www.kimonolabs.com/api/cveeggn4?apikey=NWYzkeJpFDtb4aOYd6yD96L5PdLuZHjo",
          crossDomain: true,
          dataType: "jsonp",
          success: callback,
          error: function (xhr, status) {
            //handle errors
            console.log(xhr);
            console.log(status);
          }
        });

};

angular.module('app').controller('gifCtrl', function(){
    var self = this;
    var gifs = [];

    ajaxKimono(function(result){
        var collection = result.results.collection1;

        $.each(collection, function(i, item){
            gifs.push({ gif: item.property5.href});
        });

        //this outputs the correct data
        //so i know the ajax call is working correctly
        console.log(gifs);

        self.gifCollection = gifs;

    });

    //something about the scope is messing me up
    //this outputs nothing...
    console.log(self.gifCollection);

});
Bipin Butala
  • 165
  • 1
  • 9
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Gavriel Jan 21 '16 at 17:36
  • 1
    Your callback function works perfectly. You don't understand, that ajax request is async. Your console.log, which outputs nothing is performed firstly, before ajax request performed and was handled. Then, ajax request performed and your callback was called. And only now console.log in callback will be performed. It is normal situation. So you will have step of initialization in your controller, when you perform some ajax requests. – Sharikov Vladislav Jan 21 '16 at 17:36
  • 1
    In AngularJS you are supposed to use the `$http` service for ajax calls https://docs.angularjs.org/api/ng/service/$http – Brakebein Jan 21 '16 at 17:58

1 Answers1

2

As mentioned in the comments, I guess the problem is that your console.log is called before your request has finished.

Place your http request in a separate factory or service. This makes testing and re-use easier. Note the use of angular's $http shortcut methods which returns a promise:

app.factory('DataService', function($http) {
  var getValues= function() {
    return $http.jsonp("/api/...") // returns a promise
  };

  return {
    getValues: getValues
  }
});

And then in your controller:

myApp.controller('MyController', function ($scope, DataService) {     
    DataService.getValues().then(
    function(){
      // successcallback
    },
    function(){
      // errorcallback
    })   
});

Note that I have not implemented the above code, but should provide you with an outline

sjokkogutten
  • 2,005
  • 2
  • 21
  • 24
  • 1
    i've added a factory and controller. and there are some interesting results. i don't get anything from with inside the "// successcallback" area. but it seems to resolve the completely separate ajax call. check this out on my codepen (give it about 5 seconds to load) http://codepen.io/bipinbipin/pen/mVpvyB – Bipin Butala Jan 21 '16 at 20:33
  • still trying to get this work with the method sjokkogutten suggested. currently it is unhappy with the .then() TypeError: Cannot read property 'then' of undefined – Bipin Butala Jan 21 '16 at 23:14
  • Sorry, forgot a return statement. Updated your codepen – sjokkogutten Jan 22 '16 at 08:14
  • that did it. i am still having trouble with my kimono service. need to research about jsonp, everything i read says that the kimono service is jsonp and not raw json. (even the .ajax request has dataType: "jsonp") however when i use Angular $http.jsonp i get: kimono-service.html:1 Refused to execute script from 'https://www.kimonolabs.com/api/cveeggn4?apikey=NWYzk...' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled. kimono-service-app.js:55 Object {data: undefined, status: 404, config: Object, statusText: "error"} – Bipin Butala Jan 22 '16 at 16:14
  • I tried to replace `$http.jsonp` with `$http.get` and it returned `Object { data: null, status: 0, headers: Yc/<(), config: Object, statusText: "" }`. It also returned:Cross-Origin Request Blocked:The Same Origin Policy disallows reading the remote resource at https://www.kimonolabs.com/api/etc... (Reason: CORS header 'Access-Control-Allow-Origin' missing). – sjokkogutten Jan 22 '16 at 18:15
  • same here. and when i add a CORS header, it rejects as it's not jsonp. although the ajax call seems to not have this issue. consuming Kimono service via Angular is my intention but it seems there is a trick i cannot figure out. hence the flip-flop from .ajax to $http. – Bipin Butala Jan 22 '16 at 22:02
  • When I'm running the code in Chrome, I get the following error: "_Refused to execute script from + because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled_". I think the problem is on your server. http://stackoverflow.com/questions/25140050/refused-to-execute-script-from-because-its-mime-type-application-json-is – sjokkogutten Jan 23 '16 at 12:31
  • I tried using a different url, https://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero and then using `$http.jsonp` worked as expected – sjokkogutten Jan 23 '16 at 12:33
  • Ah, your url do not return a valid URL. http://stackoverflow.com/questions/2067472/what-is-jsonp-all-about. Should have checked that in the first place. – sjokkogutten Jan 23 '16 at 12:46