Search code examples
flutternosuchmethoderrordart-null-safety

Flutter - NoSuchMethodError: The getter 'isNotEmpty' was called on a null


It is a world time app that starts with a home screen showing a default location at the beginning then you can change the location and the API gets you the time on that new location. It works fine but when I hit the back button in the "location" bar it gets me an error !!

Here is my Home code:

class _HomeState extends State<Home> {
Map data = {};
@override
Widget build(BuildContext context) {
//the argument method is taking data from another route
//I use this 
data = data.isNotEmpty ? data : ModalRoute.of(context).settings.arguments;

//data = ModalRoute.of(context).settings.arguments;

//isDaytime is a bool
String bgImage = data['isDaytime'] ? 'day.png' : 'night.png';
Color bar = data['isDaytime'] ? Colors.blue[300] : Colors.indigo[900]; 

return Scaffold(
  backgroundColor: bar,
  body: SafeArea(
    child: Container(
      width: 415.0,
      decoration: BoxDecoration(
        image: DecorationImage(
          image: AssetImage('assets/$bgImage'),
          fit: BoxFit.cover,
        ),
      ),
      child: Padding(
        padding: const EdgeInsets.fromLTRB(0, 120.0, 0, 0),
        child: Column(
          children: <Widget>[
            FlatButton.icon(
              onPressed: () async {
                dynamic result =
                    await Navigator.pushNamed(context, '/location');
                setState(() {
                  data = result;
                });
              },
              icon: Icon(
                Icons.edit_location,
                color: Colors.grey[200],
                size: 25.0,
              ),
              label: Text(
                'Edit Location',
                style: TextStyle(
                  color: Colors.grey[200],
                  fontSize: 20.0,
                ),
              ),
            ),
            RichText(
              text: TextSpan(
                text: data['location'],
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 40.0,
                ),
              ),
            ),
            RichText(
              text: TextSpan(
                text: data['time'],
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 70.0,
                ),
              ),
            ),
          ],
        ),
      ),
    ),
  ),
);

} }

and here is my location screen code:

class location extends StatefulWidget {
  @override
 _locationState createState() => _locationState();
}

  class _locationState extends State<location> {
 List<Worldtime> locations = [
   Worldtime(url: 'Africa/Cairo', location: 'Cairo', flag: 'egypt.png'),
   Worldtime(url: 'Europe/London', location: 'London', flag: 'uk.png'),
  Worldtime(url: 'America/New_York', location: 'New york', flag: 'usa.png'),
  Worldtime(url: 'Europe/Berlin', location: 'Berlin', flag: 'germany.png')
  ];

  void updateTime(index) async {
Worldtime instance = locations[index];
await instance.getTime();

Navigator.pop(context, {
  'location' : instance.location,
  'flag' : instance.flag,
  'time' : instance.time,
  'isDaytime' : instance.isDaytime,
});
}

 @override
Widget build(BuildContext context) {
return Scaffold(
  body: ListView.builder(
      itemCount: locations.length,
      itemBuilder: (context, index) {
        return Padding(
          padding:
              const EdgeInsets.symmetric(vertical: 1.0, horizontal: 4.0),
          child: Card(
            child: ListTile(
              title: Text(locations[index].location),
              leading: CircleAvatar(
                backgroundImage:
                    AssetImage('assets/${locations[index].flag}'),
              ),
              onTap: () {
                updateTime(index);
              },
            ),
          ),
        );
      }),
  appBar: AppBar(
    title: Text('Choose Location'),
    backgroundColor: Colors.grey[800],
    elevation: 0,
  ),
);
 }
 }

Solution

  • You are doing

    data = await Navigator.pushNamed(context, '/location')
    

    which when the back button is pressed output of

    await Navigator.pushNamed(context, '/location')
    

    is null so then data will be null.

    Wrap your scaffold in location page with WillPopScope widget and pop the route with desired data.