0

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?

Ethan
  • 118
  • 1
  • 13

0 Answers0