1

I am using this weather API which requires latitude and longitude to get weather. I am able to get latitude and longitude of my location(tried printing them and they are correct) but when I enter them in my API link, it shows weather of some other latitude and longitude. I have tried putting lats and longs of my location manually in the link, and it works absolutely fine. What is the issue?

import 'package:flutter/material.dart';
import 'package:clima/services/location.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

double key;

class LoadingScreen extends StatefulWidget {
  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}

class _LoadingScreenState extends State<LoadingScreen> {
  var lati;
  var longi;

  @override
  void initState() {
    super.initState();
  }

  void getData() async {
    http.Response r = await http.get('http://api.weatherstack.c'
        'om/current?access_key=41eb36e0c5f82e3ddce66ef01af877a1&query=$lati,$longi');
    String s = r.body;
    var data1 = jsonDecode(s)['location']['lat'];
    var data2 = jsonDecode(s)['location']['lon'];
    print(data1);
    print(data2);
    print(lati);
    print(longi);
  }

  void getlocation() async {
    location a = location();
    await a.getclocation();
    lati = a.lat;
    longi = a.long;
  }

  Widget build(BuildContext context) {
    getlocation();
    getData();
    return Scaffold();
  }
}

Another class named location

import 'package:geolocator/geolocator.dart';
class location{

  double lat;
  double long;


  Future<void> getclocation() async{
// this function is defined in another class
   Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.low);
  lat=position.latitude;
  long=position.longitude;


    }



}

Outputs are

41.250

1.300

28.7041

77.1025

oddgamer1
  • 31
  • 1
  • 5

1 Answers1

0

You need to wait until your operations actually complete.

For a broader explanation on how Future works, see What is a Future and how do I use it?

If you have an async function, make it return a Future<T>, even if it's a Future<void>. Then make sure you await it if you need it's result. In the UI, you cannot just stop and freeze everything, you need a FutureBuilder to play nice and show a little animation while you wait for the result.

class _LoadingScreenState extends State<LoadingScreen> {
  Future<String> getDataFuture;

  @override
  void initState() {
    super.initState();
  
    getDataFuture = getData();
  }

  Future<String> getData() async {
    final position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.low);
    final r = await http.get('http://api.weatherstack.com/current?access_key=41eb36e0c5f82e3ddce66ef01af877a1&query=$position.latitude,$position.longitude');
    return r.body;
  }

  Widget build(BuildContext context) {
    return FutureBuilder(
              future: getDataFuture ,
              builder: (context, snapshot) {
                if(snapshot.hasData) {
                  return Text('Received response: ${snapshot.data}');
                } else if(snapshot.hasError) {
                  return Text('Error: ${snapshot.error.toString()}');
                } else {
                  return CircularProgressIndicator();
                }
  }
}
nvoigt
  • 75,013
  • 26
  • 93
  • 142