Mehmet Karanlık
Mehmet Karanlık

Reputation: 277

Flutter null check operator used on null value

This is my first month as coder. I am trying to develop nearby places app. When i used following codes im getting error of "null check operator used on a null value". But based on what i see or when i printed url and checked manually or when i used if condition i see no problem or no error. Just when i rendered screen im getting this error. I would like to ask if someone can point me what is wrong ? Thanks in advance!

The line im getting error is locationName: locationSuggestion!.query.pages[0]!.title. Probibly and following locationSuggestion class.

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_udemy_examples/http_api_data/get_location_data_final.dart';
import 'package:flutter_udemy_examples/http_api_data/get_location_names.dart';
import 'package:flutter_udemy_examples/screens/login_ekrani.dart';
import 'package:flutter_udemy_examples/screens/map_screen.dart';
import 'login_ekrani.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../banner.dart';
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart' as http;

import 'package:flutter_udemy_examples/http_api_data/get_location_images.dart';

// ignore: must_be_immutable
class HomeScreen extends StatefulWidget {
  @override
  State<HomeScreen> createState() => HomeScreenState();
}

class HomeScreenState extends State<HomeScreen> {
  LocationDataFinal? locationSuggestion;

  bool isLoading = true;
  @override
  void initState() {
    super.initState();
    asyncInitState();
  }

  Future<void> asyncInitState() async {
    await fecthlocationData();
  }

  Future fecthlocationData() async {
    var locations = await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.high,
    );

    final double enlem = locations.latitude;
    final double boylam = locations.longitude;
    final url = Uri.parse(
        "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=coordinates%7Cpageimages%7Cdescription%7Cextracts&generator=geosearch&piprop=original&descprefersource=central&exlimit=20&exintro=1&explaintext=1&exsectionformat=plain&ggscoord=${enlem}%7C${boylam}&ggsradius=10000");
    print(url);
    final response = await http.get(url);
    //print(response.body);
    if (response.statusCode == 200) {
      locationSuggestion = await locationDataFinalFromJson(response.body);
      if (locationSuggestion != null) {
        setState(() {
          isLoading = false;
        });
      } else {
        print("null1");
      }
    } else {
      print("null2");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: _buildAppBar(context),
      body: isLoading
          ? Center(
              child: CircularProgressIndicator(),
            )
          : ListView(
              children: [
                MyBanner(
                  // info: locationSuggestion!.query.pages[0]!.description,
                  locationName: locationSuggestion!.query.pages[0]!.title,
                  imagePath:
                      locationSuggestion!.query.pages[0]!.original.source,
                  context: context,
                ),
                MyBanner(
                  //info: locationSuggestion!.query.pages[1]!.description,
                  locationName: locationSuggestion!.query.pages[1]!.title,
                  imagePath:
                      locationSuggestion!.query.pages[1]!.original.source,
                  context: context,
                ),
                MyBanner(
                  //  info: locationSuggestion!.query.pages[2]!.description,
                  locationName: locationSuggestion!.query.pages[2]!.title,
                  imagePath:
                      locationSuggestion!.query.pages[2]!.original.source,
                  context: context,
                ),
                MyBanner(
                  //  info: locationSuggestion!.query.pages[3]!.description,
                  locationName: locationSuggestion!.query.pages[3]!.title,
                  imagePath:
                      locationSuggestion!.query.pages[3]!.original.source,
                  context: context,
                ),
                MyBanner(
                  //  info: locationSuggestion!.query.pages[4]!.description,
                  locationName: locationSuggestion!.query.pages[4]!.title,
                  imagePath:
                      locationSuggestion!.query.pages[4]!.original.source,
                  context: context,
                ),
              ],
            ),
    );
  }

  AppBar _buildAppBar(BuildContext context) {
    return AppBar(
      automaticallyImplyLeading: false,
      leading: RotatedBox(
        quarterTurns: 2,
        child: _buildExitButton(context),
      ),
      actions: [
        _buildOpenMapButton(),
        _buildCallEmergencyNumberButton(),
      ],
      titleSpacing: 25,

      shadowColor: Colors.white,
      elevation: 0.0,
      backgroundColor: Colors.blue[800],
      //titleSpacing: Padding(padding: EdgeInsets.fromLTRB(25.85.0, 0, 25.85.0, 0)),
      title: Text("Traveler Doctor"),
    );
  }

  Widget _buildCallEmergencyNumberButton() {
    return IconButton(
      disabledColor: Colors.red,
      color: Colors.red,
      icon: Icon(Icons.phone_enabled),
      tooltip: "Local emergency number",
      onPressed: null,
    );
  }

  Widget _buildOpenMapButton() {
    return IconButton(
      disabledColor: Colors.orangeAccent,
      color: Colors.limeAccent,
      icon: Icon(Icons.map_rounded),
      tooltip: "Map",
      enableFeedback: false,
      onPressed: () => {
        Navigator.push(context,
            MaterialPageRoute(builder: (BuildContext context) => MapScreen()))
      },
    );
  }
}

Widget _buildExitButton(BuildContext context) {
  return IconButton(
    onPressed: () async {
      final SharedPreferences prefs = await SharedPreferences.getInstance();
      prefs.setString('KullaniciAdi', "");

      Navigator.pushReplacement(context,
          MaterialPageRoute(builder: (BuildContext context) => LoginEkrani()));
    },
    icon: Icon(
      Icons.exit_to_app,
      color: Colors.red,
    ),
    tooltip: "Exit",
  );
}


And this is the model im using for parsing api response

import 'dart:convert';

LocationDataFinal locationDataFinalFromJson(String str) =>
    LocationDataFinal.fromJson(json.decode(str));

class LocationDataFinal {
  LocationDataFinal({
    required this.batchcomplete,
    required this.query,
  });

  String batchcomplete;
  Query query;

  factory LocationDataFinal.fromJson(Map<String, dynamic> json) =>
      LocationDataFinal(
        batchcomplete: json["batchcomplete"],
        query: Query.fromJson(json["query"]),
      );
}

class Query {
  Query({
    required this.pages,
  });

  Map<String, Page> pages;

  factory Query.fromJson(Map<String, dynamic> json) => Query(
        pages: Map.from(json["pages"])
            .map((k, v) => MapEntry<String, Page>(k, Page.fromJson(v))),
      );
}

class Page {
  Page({
    required this.pageid,
    required this.ns,
    required this.title,
    required this.index,
    required this.coordinates,
    required this.original,
    required this.description,
    required this.descriptionsource,
    required this.extract,
  });

  int pageid;
  int ns;
  String title;
  int index;
  List<Coordinate> coordinates;
  Original original;
  String description;
  String descriptionsource;
  String extract;

  factory Page.fromJson(Map<String, dynamic> json) => Page(
        pageid: json["pageid"],
        ns: json["ns"],
        title: json["title"],
        index: json["index"],
        coordinates: List<Coordinate>.from(
            json["coordinates"].map((x) => Coordinate.fromJson(x))),
        original: json["original"] == null
            ? Original(
                source:
                    "https://tigres.com.tr/wp-content/uploads/2016/11/orionthemes-placeholder-image-1.png",
                width: 300,
                height: 200)
            : Original.fromJson(json["original"]),
        description: json["description"] == null ? "asd" : json["description"],
        descriptionsource:
            json["descriptionsource"] == null ? " " : json["descriptionsource"],
        extract: json["extract"],
      );
}

class Coordinate {
  Coordinate({
    required this.lat,
    required this.lon,
    required this.primary,
    required this.globe,
  });

  double lat;
  double lon;
  String primary;
  Globe globe;

  factory Coordinate.fromJson(Map<String, dynamic> json) => Coordinate(
        lat: json["lat"].toDouble(),
        lon: json["lon"].toDouble(),
        primary: json["primary"],
        globe: globeValues.map[json["globe"]]!,
      );
}

enum Globe { EARTH }

final globeValues = EnumValues({"earth": Globe.EARTH});

class Original {
  Original({
    required this.source,
    required this.width,
    required this.height,
  });

  String source;
  int width;
  int height;

  factory Original.fromJson(Map<String, dynamic> json) => Original(
        source: json["source"],
        width: json["width"],
        height: json["height"],
      );
}

class EnumValues<T> {
  late Map<String, T> map;
  late Map<T, String> reverseMap;

  EnumValues(this.map);
}

I will be checking this post frequently. Thanks in advance again. Sincerely ur noob coder.

Upvotes: 0

Views: 1210

Answers (2)

Mehmet Karanlık
Mehmet Karanlık

Reputation: 277

Somewhat i solved issue by replacing locationSuggestion!.query.pages[0]!.titlewith

locationSuggestion!.query.pages.values.elementAt(0).title This way of adressing solved issue for me :)

Upvotes: 0

Pat9RB
Pat9RB

Reputation: 650

Would leave this as a comment but apparently I only have enough reputation to write answers.

In your Query object pages is a Map<String, Page> but you're accessing it with a int key: locationSuggestion!.query.pages[0]!.title

To access the map with an int key, it needs to be Map<int,Page> (or List<Page>)

Upvotes: 1

Related Questions