I am using a openweather api to display the weather of the user's city. I begin by using the geolocation function to find the latitude and longitude of the user. That data is then passed in the variable api. The console keeps displaying a value of undefined. I'm not sure where I went wrong.
Here is the JavaScript:
$(document).ready(function(){
var lat;
var long;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
lat = position.coords.latitude;
long = position.coords.longitude;
var api='http://api.openweathermap.org/data/2.5/weather?lat='+lat+'&lon='+long+'&appid=myapi';
$.getJSON(api,function(data){
var city= data.name;
console.log(api);
console.log(city);
});
});
}
});
So change the code for getJSON to this :
$.getJSON(api,{})
.done(function(data){
console.log(data.name);
})
.fail(function(err){
console.log(err.responseText);
});
and check the console for the actual error
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 4 years ago.
I'm building a weather App using reactjs and the geolocation(navigator) api with the darksky weather api. I got the longitude and latitude displaying correctly, but when I try to retrieve the data I get a {code: 400, error: "The given location (or time) is invalid."}. However, if i manually put the address into the browser I get the proper JSON returned.
Example URL request: https://api.darksky.net/forecast/{api_secret_key}/37.4498,-77.3047
Looking at the headers in the console it doesn't even appear that the requested URL contains the longitude and latitude I'm passing in. Might it be that the weather API call is being executed before I get the latitude and longitude?
Request URL per console: https://api.darksky.net/forecast/{api_secret_key}/,
getWeather = async (e) => { //Get weather data
let latitude = '';
let longitude = '';
e.preventDefault(); //prevent page reload behaviour
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition((position) => {
latitude = position.coords.latitude.toFixed(4); //save lat and lon from above API call
longitude = position.coords.longitude.toFixed(4);
console.log("Latitude: " + latitude + ", Longitude: " + longitude);
});
} else {
console.log("Geolocation not available");
}
//Pass the lattitude and longitude values from the location API call to the weather API
const weather_api_call = await fetch(`https://api.darksky.net/forecast/${api_secret_key}/${latitude},${longitude}`);
const weather_data = await weather_api_call.json(); //retrieve weather API data
console.log(weather_data); //print weather API data to console
}
Answer: Ended up moving the fetch and logging of the weather API data into the getCurrentPosition function
getWeather = (e) => {
e.preventDefault(); //prevent page reload behaviour
if ("geolocation" in navigator) { //if the users allows geolocation to be active
navigator.geolocation.getCurrentPosition(async (position) => { //access naviagotr API & get the users current lat and lon
let latitude = position.coords.latitude.toFixed(4); //save lat and lon from above API call
let longitude = position.coords.longitude.toFixed(4);
console.log("Latitude: " + latitude + " Longitude: " + longitude); //check lat and lon
//Pass the lattitude and longitude values from the location API call to the weather API
const weather_api_call = await fetch(`https://api.darksky.net/forecast/${api_secret_key}/`+latitude+`,`+longitude); //run API call after when lat and lon data is gotten
const weather_data = await weather_api_call.json(); //retrieve weather API data after the call is executed with the lat and lon
console.log(weather_data); //print weather API data to console
});
} else {
console.log("Geolocation not available"); //Log if user blocks location in browser
}
}
navigator.geolocation.getCurrentPosition is an async call where you're setting the values of latitude and longitude in the supplied callback. However the getWeather function just keeps executing along and calls the fetch with the original latitude and longitude values which are defined as empty strings.
If you move your fetch calls into the callback of navigator.geolocation.getCurrentPosition where you are sure that latitude and longitude are defined it should be fine.
I'm trying to get data from the open weather API but all I get is an object that I cannot use (the JSON is inside but I cannot access it)
I've read a lot about asynchronous JS and callbacks. I'm really not sure whether I need a callback for EACH API i'm using, I already used one to get latitude and longitude but now, for the open weather API, i need to pass these lat and lon as parameters for the API call, and I have no idea on how to do that if I use callbacks (as it seems that arguments in callbacks functions are not the ones used in the function but the ones that actually get returned, which I find extremely confusing).
Can anyone tell me what I'm doing wrong here?
$(document).ready(function() {
$('#getWeather').on('click', function(){
myLatAndLon(function(result) {
var lat = result[0];
var lon = result[1];
console.log(myWeather(lat, lon));
// Here, although the params work in browser, the message that gets returned in console is : "NS_ERROR_DOM_BAD_URI: Access to restricted URI denied"
});
})
})
function myLatAndLon(callback) {
$.getJSON('http://ip-api.com/json/').done( function(location) {
var arr = [];
arr.push(location.lat);
arr.push(location.lon);
callback(arr);
});
}
function myWeather(lat, lon) {
return $.getJSON('http://api.openweathermap.org/data/2.5/weather', {
lat: lat,
lon: lon,
APPID: 'a9c241803382387694efa243346ec4d7'
})
// The params are good, and when I type them on my browser, everything works fine
}
Change your code to it and test again :
$(document).ready(function() {
$('#get').on('click', function() {
myLatAndLon(function(result) {
var lat = result[0];
var lon = result[1];
alert(JSON.stringify(result));
$req = myWeather(lat, lon);
$req.done(function(R) {
alert(JSON.stringify(R))
});
});
})
})
function myLatAndLon(callback) {
$.getJSON('//ip-api.com/json/').done(function(location) {
var arr = [];
arr.push(location.lat);
arr.push(location.lon);
callback(arr);
});
}
function myWeather(lat, lon) {
return $.getJSON('//api.openweathermap.org/data/2.5/weather', {
lat: lat,
lon: lon,
APPID: 'a9c241803382387694efa243346ec4d7'
})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="get">get</button>
And also you should check your server for CORS limitations read more here:
http://enable-cors.org/server.html
I am going to make a web app that show local weather using openweathermap api.
When I click the button, an IP API was called to get the co-ordinate of my location(longitude and latitude). These information then was used with API key (I registered in the website openweathermap.org) to create URL to call weather info according to the APIdocs, then change the HTML element with the data got from the server. I doing this on codepen. I tried to do the simplest one but it doesn't work.
<h1>weather forcast</h1>
<button id="btn">view</button>
<p id ="test">change me</p>
<p id ="place">place</p>
<p id ="temp">temperature</p>
<p id ="description">description</p>
var getLocation = function(data) {
var lat = data.lat;
var lon = data.lon;
var apiKey = "[APIKEY]";
};
var url = 'http://api.openweathermap.org/data/2.5/weather?' + 'lat=' + lat + '&lon=' + lon + '&appid=' + apiKey;
//call back function to extract weather info.
var getWeather = function(data) {
var temp = data.main.temp;
var description = data.weather[0].description;
var place = data.name;
};
$(document).ready(function() {
$("#btn").click(function() {
$.getJSON('http://ip-api.com/json', getLocation, 'jsonp')
$.getJSON(url, getWeather, 'jsonp');
$("#test").text("I AM CHANGED. THANKS!")
$("#temp").text(temp)
$("#description").text(description)
$("#place").text(place)
})
})
You have several issues. The first is that the $.getJSON calls are asynchronous, so the text() of the elements will be changed before any request completes. You need to place all code dependant on the values returned from the request in the callback functions.
Secondly you have issues with variable scope where you're defining your variables inside the function and then attempting to use them outside where they will be undefined.
With that said, you need to re-arrange your logic to something like this:
var getWeather = function(data) {
$.getJSON('http://api.openweathermap.org/data/2.5/weather', {
lat: data.lat,
lon: data.lon,
appid: "[APIKEY HERE]"
}, showWeather, 'jsonp');
};
var showWeather = function(data) {
$("#test").text("I AM CHANGED. THANKS!")
$("#temp").text(data.main.temp)
$("#description").text(data.weather[0].description)
$("#place").text(data.name)
};
$(document).ready(function() {
$("#btn").click(function() {
$.getJSON('http://ip-api.com/json', getWeather)
})
})
Note that the function calls are chained from the event (ie the click makes the location AJAX request, which calls getWeather which then calls showWeather. Also note how the variables are now local and used within their own function scope.
Finally, check that you're using the correct data formats for the AJAX requests. ip-api.com/json is returning JSON, not JSONP.
You can get data about the location with use third-party API. for example:http://ip-api.com/.
You get your location weather data from OpenWeatherMap service using the ip-api. its help you to get visitor location weather.
var getIP = 'http://ip-api.com/json/';
var openWeatherMap = 'http://api.openweathermap.org/data/2.5/weather'
$.getJSON(getIP).done(function(location) {
$.getJSON(openWeatherMap, {
lat: location.lat,
lon: location.lon,
units: 'metric',
APPID: 'Your-Openweather-Apikey'
}).done(function(weather) {
$('#weather').append(weather.main.temp);
console.log(weather);
})
})
I know what i can get JSON LatLon (and other) data indicate my address in the URL
app.factory('myCoordinates', function myCoordinates($q, $http) {
var deferred = $q.defer();
$http.get('http://maps.google.com/maps/api/geocode/json?address=$address&sensor=false®ion=$region')
.success(function(coordinates) {
var myCoordinates = {};
myCoordinates.lat = coordinates.results[0].geometry.location.lat;
myCoordinates.lng = coordinates.results[0].geometry.location.lng;
myCoordinates.zoom = 14;
deferred.resolve(myCoordinates);
})
return deferred.promise;
});
http://maps.google.com/maps/api/geocode/json?address=$address&sensor=false®ion=$region
But how can i get latitude and longitude coordinates of my current location without input my address in URL (automatically) ?
How about using html5 navigator.geolocation.getCurrentPosition to get the latitude and longitude?
Example:
navigator.geolocation.getCurrentPosition(function(pos){
console.log(pos)
});
I'm attempting to assign a global variable to HTML5 geolocation coordinates in JavaScript and passing these via jQuery to a form field.
The problem I'm having is assigning the lat and long to a global variable. I know the geolocation api is exposed via "navigator.geolocation" but I must be missing something in assigning these values to the global variable.
Here's my attempt:
var latitude = null;
function lat()
{
if (navigator.geolocation)
{
latitude = position.coords.latitude;
}
}
var longitude = null;
function lon()
{
if (navigator.geolocation)
{
longitude = position.coords.latitude;
}
}
Any help in ironing out the mistake would be greatly appreciated.
Edit: Tried this. Doesn't work in obtaining the value but also doesn't result in a Firebug error:
var latitude = navigator.geolocation.getCurrentPosition(function(position){
lat = position.coords.latitude
return lat
});
var longitude = navigator.geolocation.getCurrentPosition(function(position){
lon = position.coords.longitude
return lon});
..edit2: updating with more useful example for callbacks..
function requestCurrentPosition(){
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(useGeoData);
}
}
function useGeoData(position){
var longitude = position.coords.longitude;
var latitude = position.coords.latitude;
/*do stuff with long and lat here.*/
}
..edit: updating example...
var latitude = null;
function lat()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(
function(position){
latitude = position.coords.latitude;
});
}
}
var longitude = null;
function lon()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(
function(position){
longitude = position.coords.latitude;
});
}
}
}
You might want to check out this HTML5 Demo
How about something more like this:
// Does this browser support geolocation?
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(locationSuccess, locationError);
}
else{
showError("Your browser doesn't support geolocation!");
}
// Now get user's location
function locationSuccess(position) {
var lat = position.coords.latitude;
var lon = position.coords.longitude;
}