I have been trying to use an external API to get weather data using $resource, I have been able to get $resource all set up for searching by zipcode, city, and coordinates. When I pass in those values directly from the controller to the service, everything works out the way it should. However, when I use geolocation to get the current coordinates I am getting the correct response back from the API, but for some reason it isn't making it to my html from the controller. I have debugged through this using Chrome Developer Tools for hours now, trying to figure out what is different between directly giving the coordinates (which are the same as the geolocation coordinates) and getting the coordinates from geolocation first. Please help me!
Service:
app.factory('WeatherService', function($resource) {
var apiKey = 'defbe4f40449be22d4a2c7ef18af2a32';
return {
Geolocation: $resource('http://api.openweathermap.org/data/2.5/weather?lat=:latitude&lon=:longitude&APPID=:key', {
latitude: "@latitude", longitude: "@longitude", key: apiKey}, {
'get' : { method: 'GET', params: {}, format: 'json', isArray: false }}),
ZipcodeCountry: $resource('http://api.openweathermap.org/data/2.5/weather?zip=:zipCode,:countryCode&APPID=:key', {
zipCode: "@zipCode" , countryCode: "@countryCode", key: apiKey}, {
'get' : { method: 'GET', params: {}, format: 'json', isArray: false }}),
CityCountry: $resource('http://api.openweathermap.org/data/2.5/weather?q=:city,:countryCode&APPID=:key', {
city: "@city", countryCode: "@countryCode", key: apiKey}, {
'get' : { method: 'GET', params: {}, format: 'json', isArray: false }})
};
});
Logic to map the data received from the API
//Logic for getting API data
var mapWeatherData = function(data) {
var weather = { name: null, main: {}, wind: {}, clouds: null};
weather.name = data.name;
if (data.main)
{
weather.main.current = data.main.temp;
weather.main.humidity = data.main.humidity;
weather.main.pressure = data.main.pressure;
weather.main.min = data.main.temp_min;
weather.main.max = data.main.temp_max;
}
if (data.wind)
{
weather.wind.speed = data.wind.speed;
weather.wind.deg = data.wind.deg;
}
weather.clouds = weather.clouds ? data.clouds.all : undefined;
return weather;
};
var getWeatherByGeolocation = function(lat, lon, WeatherService) {
var weather = WeatherService.Geolocation.get({latitude: lat, longitude: lon}, function(data) {
weather = mapWeatherData(data);
});
return weather;
};
Route Config, the weather controller is what is calling the weather service:
app.config(function($routeProvider) {
$routeProvider.
when('/home', {
templateUrl: 'partials/home.html',
name: "Home",
controller: function() {
},
controllerAs: "homeCtrl",
css: 'css/partials/home.css'
}).
when('/weather', {
templateUrl: 'partials/weather.html',
name: "Weather",
controller: function($scope, $timeout, WeatherService) {'-112.0068800', WeatherService);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position){
$timeout(function(){
this.coordinates = {latitude: position.coords.latitude, longitude: position.coords.longitude};
this.weather = getWeatherByGeolocation(this.coordinates.latitude, this.coordinates.longitude, WeatherService);
});
});
}
},
controllerAs: "weatherCtrl",
css: 'css/partials/weather.css'
}).
otherwise({
redirectTo: '/weather'
});
});
Replace
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position){
$timeout(function(){
this.coordinates = {latitude: position.coords.latitude, longitude: position.coords.longitude};
this.weather = getWeatherByGeolocation(this.coordinates.latitude, this.coordinates.longitude, WeatherService);
});
});
}
With
this.weather = getWeatherByGeolocation('40.3141200', '-112.0068800', WeatherService);
To test giving the coordinates directly to the Service.
I'm still pretty new to AngularJS, so please let me know what I can do to fix this. I have already spent hours and hours researching this, and I'm out of resources. Please and thank you!
UPDATE:
Thanks to Sunil D, they pointed out that I need to assign this
to a variable in my controller so that when the service returns with my data, it has something to update because this
can change. Here is what I used in my route controller:
controller: function($scope, $timeout, WeatherService) {
var controller = this;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position){
$timeout(function(){
controller.coordinates = {latitude: position.coords.latitude, longitude: position.coords.longitude};
controller.weather = getWeatherByGeolocation(controller.coordinates.latitude, controller.coordinates.longitude, WeatherService);
});
});
}
this.weather = controller.weather;
},