2

config

(function() {

  angular.module('plunker', ['ngRoute']);

  angular.module('plunker').config(['$routeProvider', moduleConfig]);

  function moduleConfig($routeProvider) {
    $routeProvider
      .when('/home', {
        templateUrl: 'home.html', //url of the template
        controller: 'HomeCtrl', //name of the controller
        controllerAs: 'hCtrl' //how it should be referred in the template
      })
      .when('/profile', {
        templateUrl: 'profile.html', //url of the template
        controller: 'ProfileCtrl', //name of the controller
        controllerAs: 'pCtrl' //how it should be referred in the template
      })
      .otherwise({
        redirectTo: '/home'
      });
  }


  //controllers should be in their own .js files
  angular.module('plunker').controller('HomeCtrl', HomeCtrl);
  angular.module('plunker').controller('ProfileCtrl',['myservice', ProfileCtrl]);

  function HomeCtrl() {
    var hCtrl = this;
    alert('HomeCtrl');
  }

  function ProfileCtrl(myservice) {

    var pCtrl = this;
    myservice.retrive(function(data){
      alert('profile');
    });
  }

})();

myservice

(function(){

    angular.module('plunker')
        .factory('myservice',myservice);

    myservice.$inject=['$http'];

    function myservice($http) {

        var factory={
            retrive:retrive
        };

        return factory;

        function retrive(callback){

            var url = 'test.json';
            var params = {
                    callback: 'angular.callbacks._0'
                };

            $http.jsonp(url, {params: params}).then(callback);
        }
    }


})();

I wrote this controller and service for a particular page, let say "/profile". profile controller uses a service which has JSONP request. when I go to that page("/profile") everything works and JSONP callback executes. But when I go to "/index" after "/profile" and come back again to "/profile" JSONP call fires but callback in controller is not executed. can some one spot the error

plnkr with code http://plnkr.co/edit/fswywkpsH6xl5XU0YplK?p=preview

In this plnkr the callback in profile controller executes only once

3 Answers 3

1

The problem is angular will internally increment the jsonp callback value as a tracking mechanism

You must use the documented query string ?callback=JSON_CALLBACK.

The value JSON_CALLBACK is just a placeholder that $http will replace internally with values like:

angular.callbacks._0
angular.callbacks._1
angular.callbacks._2

The problem with your implementation is you always return angular.callbacks._0() so the next call that expects angular.callbacks._1() isn't receiving that value and will thus reject the request

Change your service method to:

  function retrive(callback){

        var url = 'test.json';
        var params = {
                callback: 'JSON_CALLBACK'
            };

        $http.jsonp(url, {params: params}).then(callback ).catch(function(err){
          console.log(err)
        });
    }

And in your demo you will see that err.status is 404 on the second request

DEMO

Sign up to request clarification or add additional context in comments.

4 Comments

can you tell me why it fails? Is there a way to get the callback working?
sure, your api should just wrap the json in the dynamic callback param that is sent. For example in php .. echo $_GET['callback'] .'(' . $json . ')';
I am trying to hit yelp api. it seems yelp doen't support this
does it support jsonp? Not all API's do support it
1

It's executing twice but failing the second time with a 404. You can see the failure if you add the error handler function:

$http.jsonp(url, {params: params}).then(callback, function() { console.log('I\'ve failed you:', arguments); })

Comments

0

Take a look at this modification: http://plnkr.co/edit/5HnXfpjZEzVhtCUjonGa?p=preview

You can add a flag dataLoaded in myservice that is changed from false to true when data is retrieved first time, and the check it in the controller:

//in controller code    
if(!myservice.dataLoaded) {
   myservice.retrive(function(data){
     myservice.dataLoaded = true;
     alert('profile');
   });
 }

//in service code
var factory={
  retrive:retrive,
  dataLoaded: false
};

3 Comments

There is nothing change in plnkr behavior. profile alert did not come for the second time
so you need 'myservice.retrive(function(data){' to fire EVERY time you get to /profile ?
exactly. i need callback which sets the retrieved data to model

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.