Reputation: 33
Im doing the freecampcode curriculum right now i'm at the local weatherapp.
My problem here is everytime i try to use, i get apiLink is not defined. I understand that the .getJSON part can't connect with the var defined inside the definedCordinates function.
Also i tried to use the direct api link on the .getJSON function, but even with that i get 0 input from json, im using console.log(data) and $("#temp").text to check the input from json.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Local Weather App</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="custom.css">.
<script type="text/javascript">
$(document).ready(function(){
getCordinates();
$.getJSON(apiLink, function(data){
console.log(data);
})
})
function getCordinates(){
navigator.geolocation.getCurrentPosition(definedCordinates);
}
function definedCordinates(position){
var latitude = Math.floor(position.coords.latitude);
var longitude = Math.floor(position.coords.longitude);
var apiLink = "api.openweathermap.org/data/2.5/weather?lat=" + latitude +"&lon="+ longitude +"&APPID=##########";
return apilink;
}
</script>
<body>
<div class="container-fluid">
<div class="row" id="titleRow">
<div class="col-md-4 col-md-offset-4">
<h1>My Local Weather App</h1>
</div>
</div>
<div class="row" id="locationRow">
<div class="col-md-4 col-md-offset-4">
<div class=row">
<div class="col-md-6" style="background-color: grey">
<p style="text-align:center">icon</p>
</div>
<div class="col-md-6" style="background-color: yellow">
<p style="text-align:center" id="temp">temp</p>
</div>
</div>
</div>
</div>
<div class="row" id="dataRow">
<div class="col-md-6 col-md-offset-3">
<div class="row">
<div class="col-md-4" style="background-color: grey">
<p id="name"> city name</p>
</div>
<div class="col-md-4" style="background-color: yellow">
<p> sky</p>
</div>
<div class="col-md-4" style="background-color: grey">
<p> wind</p>
</div>
</div>
</div>
</div>
<div class="row" id="poweredBy">
<div class="col-md-6 col-md-offset-3">
<div class="row">
<div class="col-md-6" id="powered">
<p> Powered by openweathermap.org API </p>
</div>
<div class="col-md-6"style="background-color: yellow">
<p> button celsius or farh </p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Upvotes: 1
Views: 234
Reputation: 350781
The function getCordinates
does not return anything, and even if it did, it cannot return the URL synchronously, because the callback definedCordinates
will only be called later, asynchronously. Secondly, the return value from that callback (which is the URL) is currently not used, but disappears in oblivion.
There are several ways to solve this, but in this case adding a promise (to the promise that $.getJSON
already is) seems like a nice solution:
$(document).ready(function(){
getCordinates().then(function(apiLink) {
// this executes when the promise returned by getCordinates is resolved:
return $.getJSON(apiLink);
}).then(function (data) {
// this executes when the promise returned by getJSON is resolved:
console.log(data);
});
})
function getCordinates() {
// return a promise that resolves when you get the current position:
return new Promise(function (resolve) {
navigator.geolocation.getCurrentPosition(function (position) {
resolve(definedCordinates(position));
});
});
}
The function definedCordinates
can stay like it is, but correct the wrong spelling of apiLink
in the return statement.
Upvotes: 1
Reputation: 2975
getCordinates needs to return a value (your url) and you need to pass that value to getJSON rather than an object (which doesn't exist in the same scope as your document ready!)
a more likely fix would be something like:
$(document).ready(function(){
var url = getCordinates();
$.getJSON(url, function(data){
console.log(data);
})
})
function getCordinates(){
navigator.geolocation.getCurrentPosition(definedCordinates);
}
function definedCordinates(position){
var latitude = Math.floor(position.coords.latitude);
var longitude = Math.floor(position.coords.longitude);
var apiLink = "api.openweathermap.org/data/2.5/weather?lat=" + latitude +"&lon="+ longitude +"&APPID=##########";
return apilink;
}
You will also run into an issue as you are not passing anything into definedCoordinates.
This could be solved by making apiLink a global variable but this is not a good way to solve the problem
Upvotes: 0
Reputation: 337637
The issue is because your apiLink
variable is defined in the definedCordinates()
function, which is well out of scope of the document.ready
handler.
To fix this you need to restructure your logic so that the apiLink
is available to the AJAX request by using the appropriate callbacks on async methods. Try this:
$(document).ready(function(){
getCordinates(function(apiLink) {
$.getJSON(apiLink, function(data) {
console.log(data);
})
});
})
function getCordinates(callback) {
navigator.geolocation.getCurrentPosition(function(position) {
var latitude = Math.floor(position.coords.latitude);
var longitude = Math.floor(position.coords.longitude);
var apiLink = "https://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&APPID=##########"
callback && callback(apiLink)
});
}
Also note that the apiLink
should be an absolute URL, ie. it needs a http://
or https://
prefix.
Upvotes: 1