0

So I am trying to make a weather app, using openWeatherAPI, and I need the lattitude and longitude of a location

First off, the desired location (city) is put into the geocode class, so that it can be converted into an object with the city name, lon, and lat.

The thing is, when I use the lon and lat values, they appear as undefined, but when you call the whole object itself, it shows all the values as they should be.

This is my index.js:

import Search from "./models/search";
import GeoCode from "./models/geocode";

const geocode = new GeoCode("toronto");
const weather = new Search(geocode.lat, geocode.lon);

console.log(geocode);
console.log(weather);

This is my geocode converter API module (geocode.js):

import axios from "axios";

export default class Geocode{
    constructor(city){
        this.city = city;
        
        this.getLatLong();
    }

    async getLatLong(){
        try{
            const res = await axios(`https://us1.locationiq.com/v1/search.php?key=${key}&q=${this.city}&format=json`);

            this.lat = JSON.parse(res.data[0].lat);
            this.lon = JSON.parse(res.data[0].lon);
        }catch(err){
            console.log(err)
        }
    }
    
}

and this is my search module, where it contacts the api to search using lon and lat (search.js):

import axios from "axios";

export default class Search{
    constructor(lat, lon){
        this.lat = lat;
        this.lon = lon;

        this.getResults();
    }

    async getResults() {
        try {
            const res = await axios(`https://api.openweathermap.org/data/2.5/onecall?lat=${this.lat}&lon=${this.lon}&%20exclude=daily&appid=${key}&units=metric`);
            this.result = res;
        }catch(error){
            alert(error);
        }
    }
}

This is also what I get in the console:

Geocode {city: "toronto"}

Search {lat: undefined, lon: undefined}
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
Tidris
  • 114
  • 2
  • 8
  • You forgot to wait for the API call to return the results. You are accessing the properties `lat` and `lon` before they are set. – CherryDT Jul 19 '20 at 01:49
  • I'm kind of a beginner, but how do I wait for the values? – Tidris Jul 19 '20 at 01:50
  • 1
    Take a look at [this question](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call). You'll probably need to learn about how to write asynchronous code correctly, because if you don't apply the "asynchronous mindset" from start to finish, your code won't work. – CherryDT Jul 19 '20 at 01:51
  • basically, your `console.log`s for geocode and weather occur before axios has fetched your data and you've updated your objects state with that fetched data. – Nick Parsons Jul 19 '20 at 01:59

1 Answers1

1

Change this:

import Search from "./models/search";
import GeoCode from "./models/geocode";

const geocode = new GeoCode("toronto");
const weather = new Search(geocode.lat, geocode.lon);

console.log(geocode);
console.log(weather);

To this:

import Search from "./models/search";
import GeoCode from "./models/geocode";

(async () => {
  const geocode = new GeoCode("toronto");
  await geocode.getLatLong();

  const weather = new Search(geocode.lat, geocode.lon);
  await weather.getResults();

  console.log(geocode);
  console.log(weather);
})();

Also remove this.getLatLong(); from geocode.js, and remove this.getResults(); from search.js.

GirkovArpa
  • 4,427
  • 4
  • 14
  • 43
  • 1
    May I suggest adding a `.catch` at the end of the IIFE call. Otherwise you may get an unhandled rejection (which may result in a swallowed error) in case the code fails, which is never a good thing. – CherryDT Jul 19 '20 at 02:02
  • I made the mistake of assuming `getLatLong()` returned anything. My answer is updated and probably answers your question. – GirkovArpa Jul 19 '20 at 02:11
  • 1
    thanks for the answer, but why can I not just do ` await this.getLatLong` inside the Geocode constructor class? – Tidris Jul 19 '20 at 02:14
  • 1
    Because JavaScript simply does not support `async` constructors (yet). – GirkovArpa Jul 19 '20 at 02:15
  • You can get close to what you want if you study the solution described here: https://gist.github.com/goloroden/c976971e5f42c859f64be3ad7fc6f4ed#gistcomment-3197319 – GirkovArpa Jul 19 '20 at 02:21