2

I'm awaiting a GEOLOCATOR function to fetch location from the user. But during the initial build I always get an error(latitude was called on null) for a few seconds before the location is actually retrieved from the GEOLOCATOR. How do I make it so that the LOCATION is actually fetched before the page is built?

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';

class DistancingPage extends StatefulWidget {
  DistancingPage(this.uid);
  @override
  _DistancingPageState createState() => _DistancingPageState();
}

class _DistancingPageState extends State<DistancingPage> {
Position position;

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

  Future<void> getPos() async {
    Position p = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);

    setState(() {
      position = p;
    });
  }
@override
  Widget build(BuildContext context) {
return Scaffold(
        appBar: AppBar(
          title: Text('Distancing Alerts'),
          backgroundColor: Colors.red[800],
),
body: Padding(
            padding: const EdgeInsets.all(36.0),
            child: Column(
              children: [
                Text(
                  'YOUR CURRENT POSITION',
                  style: TextStyle(
                    color: Colors.red[800],
                  ),
                ), //THE ERROR OCCURS HERE
                Text(position.latitude.toString() +
                    '° N , ' +
                    position.longitude.toString() +
                    '° E'),
],
            )));
  }
}


  • you cannot do that, you cant wait for future while building a UI, but you can update the UI once the data is available, use a FutureBuilder for that – Yadu Dec 09 '20 at 05:52

2 Answers2

1

You should use the FutureBuilder widget where the future is your async function and builder is whatever you want to return (the scaffold in your case). Check if the future has returned anything with snapshot.hasData and return a progress indicator (or anything you want) if it hasn't returned anything.

    FutureBuilder(
      future: getPos(),
      builder: (context, snapshot) {
    snapshot.hasData ? 
      Scaffold(
                appBar: AppBar(
                  title: Text('Distancing Alerts'),
                  backgroundColor: Colors.red[800],
        ),
        body: Padding(
                    padding: const EdgeInsets.all(36.0),
                    child: Column(
                      children: [
                        Text(
                          'YOUR CURRENT POSITION',
                          style: TextStyle(
                            color: Colors.red[800],
                          ),
                        ), //THE ERROR OCCURS HERE
                        Text(position.latitude.toString() +
                            '° N , ' +
                            position.longitude.toString() +
                            '° E'),
        ],
                    ))) : CircularProgressIndicator();};
0

You can add a temporary page with some animation from flutter_spinkit. On that page you awaiting a GEOLOCATOR function, and when it will return a value you will navigate to your main screen

Ox. S
  • 107
  • 1
  • 6
  • Or you can fetch the location the background if the app is in foreground, there is article how to do it https://medium.com/@pierre.sabot/how-to-fetch-user-location-in-background-with-flutter-e3494021bdf5 – Ox. S Dec 08 '20 at 21:56