Reputation: 2200
I am trying to use the Forecast.io weather API to build a weather application with Ionic. I am having a hell of a time getting the AJAX response data delivered to my controller for use in my view.
My Factory Service:
.factory('WeatherService', function($cordovaGeolocation) {
var posOptions = { timeout: 10000, enableHighAccuracy: false };
return {
// Get current Geolocation position with the configured /posOptions/
getPosition : $cordovaGeolocation.getCurrentPosition(posOptions),
// Query the result of /getPosition/ for /lat/, /long/, and /accuracy/
getCoords : function(pos) {
var loc = {
lat : pos.coords.latitude,
long : pos.coords.longitude,
accuracy : pos.coords.accuracy
};
return loc;
},
// Build the API request URI
getApi : function(lat, long) {
var url = 'https://api.forecast.io/forecast/';
var apiKey = 'foo';
var forecastApi = url + apiKey + '/' + lat + ',' + long + '?callback=?';
return forecastApi;
},
// Execute a request against the API URI to recieve forecast data
getForecast : function(api) {
var forecast;
$.ajax({
url : api,
dataType : 'json',
async : false,
success : function(res) {
forecast = res;
}
});
return forecast;
}
};
})
My Controller Method:
.controller('DashCtrl', function($scope, WeatherService) {
WeatherService.getPosition.then(function(pos) {
var pos = pos;
return pos;
}).then(function(pos) {
var coords = WeatherService.getCoords(pos);
return coords;
}).then(function(coords) {
var api = WeatherService.getApi(coords.lat, coords.long);
return api;
}).then(function(api) {
$scope.forecast = WeatherService.getForecast(api);
console.log($scope.forecast);
});
})
There's probably a lot of things inherently wrong with the above code. From my reading I have been made aware that then()
methods really shouldn't be used in the controller method, and all of that logic should be isolated to the Service Method. I will be refactoring to that pattern when I get this working.
I am using the jQuery $.ajax()
instead of $http
because of CORS issues with Forecast.io when developing locally. $jsonp
was throwing syntax errors on the response, so I had to resort to jQuery for the call to get this working locally.
I know I am getting a successful response because if I console.log(forecast)
inside the $.ajax
call I can explore the weather data. For whatever reason, I am unable to save the response value to the forecast
var saved in the parent scope of the ajax call and then return that to the controller for use in my view with the $scope.forecast
variable. It is always returning undefined
.
I have looked at plenty of SO questions while trying to get this working on my own, and have yet to have any success..
How do I return the response from an asynchronous call?
Get Data from a callback and save it to a variable in AngularJS
Upvotes: 0
Views: 102
Reputation: 48865
Well, if you really really feel the need to use ajax (probably better to track down and fix the jsonp issue) then you should probably wrap the forcast in your very own promise.
.factory('WeatherService', function($q,$cordovaGeolocation) {
...
getForecast : function(api)
{
var deferred = $q.defer();
$.ajax({url : api, dataType : 'json', async : false,
success : function(res) {
defereed.resolve(res);
}
});
return defereed.promise;
}
You already know how to handle promises in your controller code so I won't post those changes.
Upvotes: 1