0

I am loading JSON file from S3. File is loading successfully but problem is, I cannot access AnglarJS modules($scope, services and etc) in my callback function because it is written outside angularJS. Is there a way to access $scope in my callback?

AngularJS code

var url = "http://my_s3_url/abc/v1/klm/my.json"

$http.jsonp(url);

my.json

jsonp_callback({name:"xyz",age:2})

callback

<script>
   function jsonp_callback(data) {
      console.log(data.name);
      // cannot access $scope here :(
   }
</script>
waqas
  • 4,357
  • 3
  • 34
  • 42

5 Answers5

3

Hmm you are using $http so I guess angular is generally available.

Is there a way to access $scope in my callback?
If the script block is within the same document, then any scope is accessible by doing i.e. angular.element('body').scope().

<script>
  function jsonp_callback(data) {
    console.log(data.name);
    
    // access $scope here :)
    var scope = angular.element('body').scope();
    scope.$apply(function() {
      scope.lastResult = data;
    });
  }
</script>

Element body is used only as an example. It might be adapted for any DOM element related to the target scope.

Andre Pastore
  • 2,841
  • 4
  • 33
  • 44
angabriel
  • 4,979
  • 2
  • 35
  • 37
0

You shouldn't have to write the callback function yourself. It should be enough to use the special "success" method from the resulting promise from the $http.jsonp call. If the following code is in the controller, you should still have access to the $scope variable.

$http.jsonp(url).
success(function(data, status, headers, config) {
    // The data is here
}).

Edit I've realised this answer depends on there being a string JSON_CALLBACK in the url passed to $http.jsonp, which I suspect Angular replaces with some unique callback function it's defined. The server must then interpret this, and output JSON wrapped in a call to this function. This might not work on S3, which just serves static files.

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165
  • Thnx Michal, yes you are right that this solution won't in case of S3. Any idea how we can make it work? – waqas Dec 16 '13 at 07:17
  • 1
    How about CORS? http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html . Then you can just store standard JSON. IE support isn't great though http://caniuse.com/cors – Michal Charemza Dec 16 '13 at 08:15
  • yes I know CORS is an option. But this is our last option. If we become unable to find any solution then we have to enable CORS at the end to make things work. – waqas Dec 16 '13 at 10:06
0

Use the $q promise library to pass the data back to the scope

In the director.js

function eventReturn($http, $q){   
   return {
      getEvent: function(){
          var deferred = $q.defer();
          $http({method:'GET', url'http://my_s3_url/abc/v1/klm/my.json'}).
              success(function(data, status, headers, config){
                  deferred.resolve(data);
          });
          return deferred.promise;
      }
   }
};

and in the controller.js

$scope.event = eventReturn.getEvent();
  • we cannot send $http({method:'GET' ... }) request to S3. We have to stick with $http({method:'JSONP' ...}). If we want to send 'GET' request to S3, we have to enable Cross(CORS) Domain request on Amazon S3 otherwise it won't work. – waqas Dec 20 '13 at 18:07
0

I have created the plunker for your scenario, its like when page loads it will read the json file from $http and then call the external js file function,to that function it will pass the $scope and result data, that external function take the result and display by using scope.

url : http://plnkr.co/edit/k66KevvcIyxiKA5QSBAc?p=preview

hope this is what ur looking.

Uttesh Kumar
  • 290
  • 2
  • 10
  • we cannot send $http({method:'GET' ... }) request to S3. We have to stick with $http({method:'JSONP' ...}). If we want to send 'GET' request to S3, we have to enable Cross(CORS) Domain request on Amazon S3 otherwise it won't work – waqas Dec 20 '13 at 18:11
  • modified the plucker to 'JSONP' instead of GET http://plnkr.co/edit/k66KevvcIyxiKA5QSBAc?p=preview. could you please elaborate your issue. – Uttesh Kumar Dec 21 '13 at 03:41
0

I use the AWS javascript lib and had to use apply:

AWS.config.update({accessKeyId: '?', secretAccessKey: '?'});
var s3 = new AWS.S3({ maxRetries: 5});
console.log("S3 correctly configured");
s3.listObjects( {Bucket : 'bucketName', Prefix : 'foo/bar/' }, function (err, data) {
    if (err) {
        console.log(err); // an error occurred
    } else {
        console.log(data); // successful response
        sc.$apply(function() {
            sc.prefix = data.Prefix;
            sc.data = data;
        });
    }
});
user987339
  • 10,519
  • 8
  • 40
  • 45
davilj
  • 101
  • 2
  • 6