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);
})
})
Related
I am a beginner and I have a function to get the link based on your location.
Here is the function:
<p id="demo"></p>
<script>
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition, showError);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "http://api.openweathermap.org/data/2.5/weather?lat=" + position.coords.latitude + "&lon=" +
position.coords.longitude + "&units=metric&APPID=3d1523ca3f27251ddf055b1b26ed347f"
}
</script>
now I am trying to get this link into a get.Json so that the website will automatically get information about the weather in your area. The problem is that I can't get it to work. can someone help me on how to get the link into a get.Json automatically.
To get data from some web api endpoint you need to use some ajax request api. Native ones are XMLHTTPRequest, fetch().
There is also jQuery.ajax and its aliases $.post,$.get,$.getJSON etc
So just use the api that you are comfortable with and add it to your showPosition function. When the respective api's promise, or event callback is triggered used the passed data to display your information:
function showPosition(position) {
let apiUrl = "http://api.openweathermap.org/data/2.5/weather?lat=" +
position.coords.latitude +
"&lon=" + position.coords.longitude +
"&units=metric&APPID=3d1523ca3f27251ddf055b1b26ed347f";
//using fetch() api
fetch(apiUrl).then(response=>response.json()).then(data=>{
//use the returned data however you like
//for instance show temperature
x.innerHTML = data.main.temp;
});
//using XMLHttpRequest
let req = new XMLHttpRequest();
req.open("get",apiUrl);
req.addEventListener('load',function(data){
//use the returned data however you like
});
//using a library like jQuery
jQuery.getJSON(apiUrl).then(function(data){
//use the returned data however you like
});
}
Read up on asynchronous operations and avoid pitfalls like these:
How do I return the response from an asynchronous call?
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
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 was looking to use a weather API (like yahoo's) and make my javascript code able to return the temperature given a city.
My app runs on rivescript (built on javascript and node).
Researching I only found ways to do it locally on json, or by using html and css as well, but I just want a simple javascript code that returns a value with the temperature.
Thanks
You can try something like this, using openweathermap.org APIs:
function getWeather(city, callback) {
var url = 'http://api.openweathermap.org/data/2.5/weather';
$.ajax({
dataType: "jsonp",
url: url,
jsonCallback: 'jsonp',
data: { q: city },
cache: false,
success: function (data) {
callback(data.main.temp);
}
});
}
This example uses a name of a city as input, and returns temperature in K° degrees.
The data.main.temp value is returned, but you could return just data to have the whole weather object for that city.
Otherwise, if you want to use Yahoo Weather API (with your APPID):
function getWeather(position, callback) {
var lat = position.coords.latitude;
var lon = position.coords.longitude;
// Yahoo's PlaceFinder API http://developer.yahoo.com/geo/placefinder/
// We are passing the R gflag for reverse geocoding (coordinates to place name)
var geoAPI = 'http://where.yahooapis.com/geocode?location='+lat+','+lon+'&flags=J&gflags=R&appid='+APPID;
// Forming the query for Yahoo's weather forecasting API with YQL
// http://developer.yahoo.com/weather/
var wsql = 'select * from weather.forecast where woeid=WID and u="'+DEG+'"',
weatherYQL = 'http://query.yahooapis.com/v1/public/yql?q='+encodeURIComponent(wsql)+'&format=json&callback=?', code, city, results, woeid;
// Issue a cross-domain AJAX request (CORS) to the GEO service (not supported in Opera and IE)
$.getJSON(geoAPI, function(r) {
if (r.ResultSet.Found == 1) {
results = r.ResultSet.Results;
city = results[0].city;
code = results[0].statecode || results[0].countrycode;
woeid = results[0].woeid; // the the city identifier for the weather API
// Make a weather API request (it is JSONP, so CORS is not an issue):
$.getJSON(weatherYQL.replace('WID', woeid), function(r) {
if (r.query.count == 1) {
var item = r.query.results.channel.item.condition;
callback(item.temp
} else {
console.error("Error retrieving weather data!");
}
});
}
}).error(function(){
console.error("Sorry, your browser does not support CORS requests!");
});
}
This example uses a position as input (see navigator.geolocation), and returns temperature in C° degrees.
Note:
- both examples imply the use of jQuery.
- the second example implies having obtained a Yahoo APPID
I want to fetch coordinates of 10,000 line of data using Google Maps geocoding API, and print each line to browser.
My approach is to loop each line (contain address) and pass it to Google Maps URL, then I parse those JSON data to get its lat and lng. I use jQuery.
But the problem here is it seems to run asynchronously. I have tried to use recursive but it loop without print anything. I have read to set async=false but I dont know where to place it.
Here is my current code
var x = 1;
setInterval(function(){
geturl = 'parse.php?urut='+x;
$.get(geturl, function(get){
url = get;
});
$.getJSON(url, function(data){
var lat = data.results[0].geometry.location.lat;
var lang = data.results[0].geometry.location.lng;
var nama = data.results[0].address_components[1].long_name;
$('table').append("<tr><td>"+x+"</td><td>"+lat+","+lang+"</td><td>"+nama+"</td></tr>");
});
x++;
}, 500);
Any recommendation?
This snippet of code should show you where you went wrong
function getCoords(x) {
geturl = 'parse.php?urut='+x;
$.get(geturl, function(url){
$.getJSON(url, function(data){
var lat = data.results[0].geometry.location.lat;
var lang = data.results[0].geometry.location.lng;
var nama = data.results[0].address_components[1].long_name;
$('table').append("<tr><td>"+x+"</td><td>"+lat+","+lang+"</td><td>"+nama+"</td></tr>");
});
});
}
the $.getJSON is run as part of the success function of the $.get - therefore it will get run only once the $.get is complete
I've shown this as a function, so that the value of x will be correct in the $('table').append line