8

I'm attempting to use Angularjs to gather data from the USGS Earthquake feed. Typically you would need to tack ?callback=JSON_CALLBACK on to the end of the URL for Angular to use it, however the USGS feed does not recognize this option.

The URL I'm using is http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojsonp and adding ?callback=JSON_CALLBACK (eg. http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojsonp?callback=JSON_CALLBACK) returns a dataset wrapped in a function called eqfeed_callback.

Is there any way to use this data? I've got an eqfeed_callback function but it's not in scope which makes using Angular pointless.

Here's the code that I've got as it stands:

function QuakeCtrl($scope, $http) {

    $scope.get_quakes = function() {
        var url = 'http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojsonp';
        $http.jsonp(url)
    }

}

function eqfeed_callback(data) {
    return data;
}

Is there any way to either get the data back into the scope, or get angular to use the eqfeed_callback function internally?

3
  • Are you adverse to just using JSON? I hazarded a guess that removing the p from the url would make it just pure JSON, and it does. Commented Oct 15, 2013 at 7:05
  • That would work, however the USGS does not have CORS enabled so I get cross origin errors. Is there a way to use JSON if CORS isn't enabled? My understanding is that is a server side setting and not something I can modify. Commented Oct 15, 2013 at 7:10
  • Oh :/ guess you can't do that then; yes, it is a server side setting. Commented Oct 15, 2013 at 7:16

3 Answers 3

18

Another option would be defining the eqfeed_callback within the scope like this:

function QuakeCtrl($scope, $http) {
    $scope.data = null;
    $scope.get_quakes = function() {
      var url = 'http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojsonp';
      $http.jsonp(url)
    }

    window.eqfeed_callback = function(data) {
      $scope.data = data
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Awesome! That does it. Thanks!
Or even: $window.eqfeed_callback ...
That's just another way of using a global.
@T.J.Crowder so true, but I think it keeps the logic more in place :)
0

The only idea that comes to mind is (blech) to use a global, and then to manually trigger an Angular update, e.g.:

var callback$scope;
function QuakeCtrl($scope, $http) {

    $scope.get_quakes = function() {
        var url = 'http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojsonp';
        callback$scope = $scope;
        $http.jsonp(url)
    }

}

function eqfeed_callback(data) {
    if (callback$scope) {
        // 1. Use callback$scope here
        // 2. Set callback$scope to undefined or null
        // 3. Trigger an Angular update (since it won't be automatic)
    }
}

Not pretty, but...

2 Comments

He could just use a JSON instead of JSONP request, which would be a little less sketchy than this. Also, wouldn't it need to be $scope = callback$scope? Or even $http.jsonp.call(callback$scope, [url])?
@Fred: He can't use JSON because to do that, he'd have to use ajax, and that would be a cross-origin request. The SOP won't allow that (unless, of course, the earthquake.usgs.gov supports CORS and the user is using a browser that supports it, and he handles the whole IE9 and earlier problem).
0

Expanding on @MichaelVanRijn's answer:

In order to keep the "global peace", define the global function when you need it and nullify it right after.

.controller('QuakeCtrl', function($window, $scope, $http) {
  $scope.get_quakes = function() {
    $window.eqfeed_callback = function(data){
      console.log("quake data", data)
    };

    // load your jsonp data
    $http.jsonp('http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojsonp')
    .then(function(success) {
      console.log(success);
      $window.eqfeed_callback = null;
    }, function(fail) {
      console.log(fail);
      $window.eqfeed_callback = null;
    })
  }
})

Comments

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.