Reputation: 277
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
Reputation: 277
Somewhat i solved issue by replacing
locationSuggestion!.query.pages[0]!.title
with
locationSuggestion!.query.pages.values.elementAt(0).title
This way of adressing solved issue for me :)
Upvotes: 0
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