Solving API call issue in React JS (400 Error) [duplicate] - javascript

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.

Related

how to automate a geolocation based Json

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

Geolocation won't be displayed in console

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

Why did the latitude results object change from the google maps api?

I am hitting the google maps api while passing in a city like so:
this.geoCode = function(city) {
var dfd = $q.defer();
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': city},
function (results, status) {
console.log('map response: ', results);
cityObj.address = results[0].formatted_address;
getWeather(results[0].geometry.bounds.R.R, results[0].geometry.bounds.j.j)
.then(function(response) {
cityObj = response;
dfd.resolve(cityObj);
});
});
return dfd.promise;
};
Just 2 weeks ago I was accessing the latitude/longitude from the results object by:
getWeather(results[0].geometry.bounds.R.R, results[0].geometry.bounds.j.j)
Now the results object looks like this:
getWeather(results[0].geometry.bounds.H.H, results[0].geometry.bounds.j.j)
as you can see, the latitude went from being accessed on the R.R object to being accessed on the H.H object. I don't know if this is something googlemaps frequently does. If it is, how could use the code to continually parse through the data to get the latitude/longitude without continually changing the object letters? Any feedback would be greatly appreciated. Thanks
That is due to it being minified, the property names aren't always named the same and aren't meant to be accessed directly.
geometry.bounds is a LatLngBounds instance. As such you use the methods like getCenter() to get a LatLng object which you can then get the latitude and longitude values
var center = results[0].geometry.bounds.getCenter();
var lat = center.lat();
var lng = center.lng();
Or you can also use geometry.location as it is already a usable LatLng instance, it all depends on which coordinates you are needing to retrieve.

show local weather using openweathermap api

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);
})
})

How can i get latitude and longitude coordinates from JSON Google Maps

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&region=$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&region=$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)
});

Categories