1

I have JSONP request that callbacks function outside Angular Controller. How can I return data from that function back to Controller? Or maybe there's a way to callback function inside Controller?

Adding '?callback=JSON_CALLBACK' don't fire success promise. I think it's because JSONP response wraped in function call: CBR_XML_Daily_Ru({"Date":"2016-10-06T00:00:00+00:00" ... });

<div ng-controller='myCtrl' ng-app='myApp'>
    <input type=text ng-model='divForCharCode'></input>
    <div id='div1'></div>
</div>

<script>CBR_XML_Daily_Ru = function(data) {
  document.getElementById("div1").innerHTML = data.Valute.EUR.CharCode;

};

var myApp = angular.module('myApp', [])
  .controller('myCtrl', myCtrl);

  function myCtrl($scope,$http) {
      $scope.divForCharCode = ' need to place EUR here!';
    $http.jsonp('https://www.cbr-xml-daily.ru/daily_jsonp.js');
  };</script>

https://plnkr.co/edit/hKdXf7MxAhnU8aMFqPUV

Anton
  • 1,898
  • 3
  • 18
  • 27
  • i think you should take look here, [similar case question](http://stackoverflow.com/questions/12066002/parsing-jsonp-http-jsonp-response-in-angular-js) – Ahmad Abu Saa Oct 06 '16 at 08:03

2 Answers2

3

i came up this solution after searching and trying ,in your case this solution is better than other solutions that use angular.element(....).scope() because here we use angular service $window while in (angular.element().scope) we use something may be disabled in some angular mode, check this.

CBR_XML_Daily_Ru = function(data) {
  window.angularJsonpCallBackDefindInController(data);

};

var myApp = angular.module('myApp', []).controller('myCtrl', myCtrl);

function myCtrl($scope, $http,$window) {
  var self = this;

  $http.jsonp('https://www.cbr-xml-daily.ru/daily_jsonp.js?callback=JSON_CALLBACK');
  $window.angularJsonpCallBackDefindInController = function (data) {
      //u can do anything here, you are in the controller, and in the same time this function in the window object and get called from anywhere even in jquery 
     self.divForCharCode = data.Valute.EUR.CharCode;
  };
}

you can also use this way to execute function in controller from jquery "scope":

CBR_XML_Daily_Ru = function(data) {
  angular.element("#controllerDivId").controller().angularJsonpCallBackDefindInController(data);

};

var myApp = angular.module('myApp', []).controller('myCtrl', myCtrl);

function myCtrl($scope, $http,$window) {
  var self = this;

  $http.jsonp('https://www.cbr-xml-daily.ru/daily_jsonp.js?callback=JSON_CALLBACK');
  self.angularJsonpCallBackDefindInController = function (data) {
     self.divForCharCode = data.Valute.EUR.CharCode;
  };
}

this is the html (you need to include jquery to use the second solution)

<html>

<head>
  <script src="jquery-3.1.1.min.js"></script>
  <script src="angular.min.js"></script>
  <!--<link rel="stylesheet" href="style.css" />-->
  <script src="jsnopstuff.js"></script>
</head>

<body>
    <div id="controllerDivId" ng-controller='myCtrl as ctrl' ng-app='myApp'>
        <input type=text ng-model='ctrl.divForCharCode'>
        <div id='div1'></div>
    </div>

</body>
</html>
Ahmad Abu Saa
  • 718
  • 6
  • 12
  • Thanks, it works! Though I still doubt that server responded JSONP data format is supposed to work with Angular... – Anton Oct 06 '16 at 14:05
  • 1
    welcome, you check this line about issue of many JSONP servers that dosnt accept angular callback name https://github.com/angular/angular.js/issues/1551 – Ahmad Abu Saa Oct 09 '16 at 06:21
-1

I would have done like this: this code has a full functioning promise using $q. Hope this helps

     <div ng-controller='myCtrl' ng-app='myApp'>
        <input type=text ng-model='divForCharCode'></input>
        <div>{{data.Valute.EUR.CharCode}}</div>
    </div>

    <script>

        var myApp = angular.module('myApp', [])
          .controller('myCtrl', myCtrl);

          function myCtrl($scope,$http, $q) {
              var self = this;
              self.divForCharCode = ' need to place EUR here!';

              var getDataFromServer = function(){
              var deferred = $q.defer(); // creating a promise
              var url = "https://www.cbr-xml-daily.ru/daily_jsonp.js?callback=JSON_CALLBACK";
              $http.get(url).success(function (data, status, headers,config) {
                deferred.resolve(data);
            }).error(function (data, status, headers, config) {
                //this always gets called
                console.log(status);
                deferred.reject(status);
            });
            return deferred.promise;
          }
           var promise = getDataFromServer();
           promise.then(function(data){
           $scope.data = data;
           });

          };
</script>
  • getting error: XMLHttpRequest cannot load https://www.cbr-xml-daily.ru/daily_jsonp.js?callback=JSON_CALLBACK. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. – Anton Oct 06 '16 at 08:56
  • @Anton That is happening because you are trying to access a resource (here a jsonp.js file) from your locally hosted server. The server you are trying to access is not permitting CORS. This usually happens when the webapp is running from a local instance. – Alan Joseph Oct 07 '16 at 07:11
  • So it's remote server that is misconfigured or my request is wrong? I don't have any control over cbr-xml-daily.ru and it's not in my local network. – Anton Oct 07 '16 at 07:16
  • 1
    @Anton, I get it. it is just the server which is not configured to accept CORS. As i mentioned earlier, after the development stage is done, and the app is hosted on a server or as a hybrid mobile app, this problem should not persist. – Alan Joseph Oct 07 '16 at 09:03
  • @Anton or, as a work around, you could use a plugin for chrome for enabling CORS support. Search for **CORS toggle** in the chrome plugin store. Enable it before making any requests. – Alan Joseph Oct 07 '16 at 09:05