I'm using the geolocation
web API to return the latitude and longitude of the user in decimal degrees. I use the following code to accomplish this:
const lat = position.coords.latitude + 0.001
const lon = position.coords.longitude - 0.001
const location = { lat, lon }
Constants lat
and lon
return the latitude and longitude of the user. Then the object location
bundles both constants into an object. Once this data is received it's sent to weatherapi.com's API; then, the user's city and it's weather are returned in the form of an object. Here's what the object returned by weatherapi looks like:
{
location: {
name: 'Jingli',
region: 'Anhui',
country: 'China',
lat: 33.57,
lon: 117.73,
tz_id: 'Asia/Shanghai',
localtime_epoch: 1677113400,
localtime: '2023-02-23 8:50'
},
current: {
last_updated_epoch: 1677113100,
last_updated: '2023-02-23 08:45',
temp_c: 2.1,
temp_f: 35.8,
is_day: 1,
condition: {
text: 'Partly cloudy',
icon: '//cdn.weatherapi.com/weather/64x64/day/116.png',
code: 1003
},
wind_mph: 5.1,
wind_kph: 8.3,
wind_degree: 88,
wind_dir: 'E',
pressure_mb: 1026,
pressure_in: 30.31,
precip_mm: 0,
precip_in: 0,
humidity: 87,
cloud: 29,
feelslike_c: -0.4,
feelslike_f: 31.3,
vis_km: 10,
vis_miles: 6,
uv: 2,
gust_mph: 7.6,
gust_kph: 12.2
}
}
{ lat: 33.5675392, lon: -117.7255936, timestamp: 1677113563590 }
[ '33.5675392', '117.7255936' ]
{
location: {
name: 'Jingli',
region: 'Anhui',
country: 'China',
lat: 33.57,
lon: 117.73,
tz_id: 'Asia/Shanghai',
localtime_epoch: 1677113400,
localtime: '2023-02-23 8:50'
},
current: {
last_updated_epoch: 1677113100,
last_updated: '2023-02-23 08:45',
temp_c: 2.1,
temp_f: 35.8,
is_day: 1,
condition: {
text: 'Partly cloudy',
icon: '//cdn.weatherapi.com/weather/64x64/day/116.png',
code: 1003
},
wind_mph: 5.1,
wind_kph: 8.3,
wind_degree: 88,
wind_dir: 'E',
pressure_mb: 1026,
pressure_in: 30.31,
precip_mm: 0,
precip_in: 0,
humidity: 87,
cloud: 29,
feelslike_c: -0.4,
feelslike_f: 31.3,
vis_km: 10,
vis_miles: 6,
uv: 2,
gust_mph: 7.6,
gust_kph: 12.2
}
}
{ lat: 33.5675392, lon: -117.7255936, timestamp: 1677113823146 }
[ '33.5675392', '117.7255936' ]
{
location: {
name: 'Jingli',
region: 'Anhui',
country: 'China',
lat: 33.57,
lon: 117.73,
tz_id: 'Asia/Shanghai',
localtime_epoch: 1677113823,
localtime: '2023-02-23 8:57'
},
current: {
last_updated_epoch: 1677113100,
last_updated: '2023-02-23 08:45',
temp_c: 1.7,
temp_f: 35.1,
is_day: 0,
condition: {
text: 'Clear',
icon: '//cdn.weatherapi.com/weather/64x64/night/113.png',
code: 1000
},
wind_mph: 4.5,
wind_kph: 7.2,
wind_degree: 123,
wind_dir: 'ESE',
pressure_mb: 1027,
pressure_in: 30.32,
precip_mm: 0,
precip_in: 0,
humidity: 90,
cloud: 15,
feelslike_c: -0.5,
feelslike_f: 31.1,
vis_km: 10,
vis_miles: 6,
uv: 1,
gust_mph: 7.8,
gust_kph: 12.6
}
}
However, this clearly does not work. I'm in California and weatherapi thinks I'm somewhere in China. I think this is because the geolocation
API returns North, East coordinates and weatherapi expects North, West coordinates. So however I could do that would likely fix the problem. Here's my code:
Frontend code on the index.html
page
HTML
and Vanilla JS
Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather Here</title>
</head>
<body>
<h1>How's the weather?</h1>
<button id="check-in">Check-in!</button>
<script>
if ("geolocation" in navigator) {
console.log("Geolaction is supported")
const checkInBtn = document.getElementById("check-in")
navigator.geolocation.getCurrentPosition(async (position) => {
const lat = position.coords.latitude + 0.001
const lon = position.coords.longitude - 0.001
const location = { lat, lon }
console.log(position.coords)
const storeLocation = JSON.stringify(location)
localStorage.setItem("my-coords", storeLocation)
console.log(location)
const getData = async () => {
const postOptions = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(location)
}
console.log(location)
const responseStream = await fetch("/api", postOptions)
const response = await responseStream.text()
if (response == "Success 200 @ /api POST") {
window.location.href = "/results.html"
console.info(response)
}
else {
alert("Error " + response)
console.error(response)
}
}
checkInBtn.addEventListener("click", getData)
})
}
else {
alert("This app is not supported")
}
</script>
</body>
</html>
Vanilla JS
only code
if ("geolocation" in navigator) {
console.log("Geolaction is supported")
const checkInBtn = document.getElementById("check-in")
navigator.geolocation.getCurrentPosition(async (position) => {
const lat = position.coords.latitude + 0.001
const lon = position.coords.longitude - 0.001
const location = { lat, lon }
console.log(position.coords)
const storeLocation = JSON.stringify(location)
localStorage.setItem("my-coords", storeLocation)
console.log(location)
const getData = async () => {
const postOptions = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(location)
}
console.log(location)
const responseStream = await fetch("/api", postOptions)
const response = await responseStream.text()
if (response == "Success 200 @ /api POST") {
window.location.href = "/results.html"
console.info(response)
}
else {
alert("Error " + response)
console.error(response)
}
}
checkInBtn.addEventListener("click", getData)
})
}
else {
alert("This app is not supported")
}
Backend code with Node.js
on the index.js
file
const { request, response } = require("express")
const express = require("express")
const nedb = require("nedb")
const app = express()
const port = 2000
app.listen(port, () => {
console.log("Listening at port " + port)
})
const database = new nedb("allweather.db")
database.loadDatabase()
app.use(express.static("public"))
app.use(express.json({limit: "1mb"}))
app.get("/api", (request, response) => {
database.find ({}, (err, data) => {
if (err) {
response.send("Error not found 404 @ /api GET")
}
response.send(data)
})
})
app.get("/weather/:coords", async (request, response) => {
const coords = request.params.coords.split(",")
const lat = coords[0]
const lon = coords[0]
console.log(coords)
const weatherUrl = `http://api.weatherapi.com/v1/current.json?key=MY_API_KEY&q=${coords}&aqi=no`
const getWeather = await fetch(weatherUrl)
const weather = await getWeather.json()
console.log(weather)
response.json(weather)
})
app.post ("/api", (request, response) => {
request.body.timestamp = Date.now()
console.log(request.body)
database.insert(request.body)
response.send("Success 200 @ /api POST")
})
Database with nedb
{"lat":33.5675392,"lon":-117.7255936,"timestamp":1677113823146,"_id":"09OnSqBhgw9fgRWh"}
{"lat":33.5675392,"lon":-117.7288704,"timestamp":1676766051971,"_id":"6M6P1VPTkPVgIp04"}
{"lat":33.5675392,"lon":-117.7288704,"timestamp":1676773089698,"_id":"8LJmf3gcHU3bmpqt"}
{"lat":33.5675392,"lon":-117.7255936,"timestamp":1677113563590,"_id":"BEEikUu2LObRccEr"}
{"lat":33.5675392,"lon":-117.7255936,"timestamp":1677113245401,"_id":"JcHKwVBwrzhPChNQ"}
{"lat":33.5675392,"lon":-117.7255936,"timestamp":1677113399718,"_id":"yYuUpGBfqc6GK7cy"}
Result.html
frotend page
HTML
and Vanilla JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Results</title>
</head>
<body>
<div id="checkins"></div>
<script>
const getData = async () => {
const response = await fetch("/api")
const results = await response.text()
const splitData = results.split("}")
let checkins = document.getElementById("checkins")
for (let i = 0; i < splitData.length; i++) {
const finalData = splitData[i].replace(/[^a-zA-Z0-9.,]/g, ' ');
let checkInList = document.createElement("div")
checkInList.className = "check-in-list"
checkins.appendChild(checkInList)
checkInList.textContent = finalData
console.log(finalData)
}
const recivedCoords = localStorage.getItem("my-coords")
const myCoords = recivedCoords.replace(/[^a-zA-Z0-9.,]/g, '');
const coordsPre1 = myCoords.replace("lat", "")
const coords = coordsPre1.replace("lon", "")
console.log(coords)
const returnWeather = await fetch(`/weather/${coords}`)
const returnedWeather = await returnWeather.json()
console.log(returnedWeather)
}
getData()
</script>
</body>
</html>
Vanilla JS
only code
const getData = async () => {
const response = await fetch("/api")
const results = await response.text()
const splitData = results.split("}")
let checkins = document.getElementById("checkins")
for (let i = 0; i < splitData.length; i++) {
const finalData = splitData[i].replace(/[^a-zA-Z0-9.,]/g, ' ');
let checkInList = document.createElement("div")
checkInList.className = "check-in-list"
checkins.appendChild(checkInList)
checkInList.textContent = finalData
console.log(finalData)
}
const recivedCoords = localStorage.getItem("my-coords")
const myCoords = recivedCoords.replace(/[^a-zA-Z0-9.,]/g, '');
const coordsPre1 = myCoords.replace("lat", "")
const coords = coordsPre1.replace("lon", "")
console.log(coords)
const returnWeather = await fetch(`/weather/${coords}`)
const returnedWeather = await returnWeather.json()
console.log(returnedWeather)
}
getData()
Edit:
I just tried changing my geolocation in the sensors
tab on chrome. Every place in the US shows up as somewhere in China. However, other countries reported their correct weather and location. Maybe a problem with Weather API?