I get the error after fetching the data with Dio.
Exception has occurred.
NoSuchMethodError (NoSuchMethodError: The method 'forEach' was called on null.
Receiver: null
Tried calling: forEach(Closure: (String, dynamic) => Null))
I get the above error on this line jsonResponse.forEach((key, value) {
this is how I fetch the data from json:
Future<List<AirQualityModel>> _getAirQuality() async {
var dio = Dio();
var cookieJar;
Response dioResponse;
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
try {
cookieJar = PersistCookieJar(dir: appDocPath + "/.cookies/");
dio.interceptors.add(CookieManager(cookieJar));
dioResponse = await dio.get(
"https://www.airvisual.com/api/v2/node/5ded3e13994dfe107f7013a0");
debugPrint('dioResponse: ' + dioResponse.data.toString());
debugPrint("response: " + dioResponse.statusMessage.toString());
jsonResponse = json.decode(dioResponse.data);
airqualityList = List<AirQualityModel>();
jsonResponse?.forEach((key, value) {
airqualityList = (jsonResponse['current'] as List)
.map<AirQualityModel>((j) => AirQualityModel.fromJson(j))
.toList();
});
debugPrint('List: $airqualityList');
return airqualityList;
} catch (e) {
print('catch error: $e');
}
}
and this is my airquality_model.dart
class AirQualityModel {
final int pm25;
final int co2;
final int humidity;
final int temperature;
AirQualityModel(this.pm25, this.co2, this.humidity, this.temperature);
AirQualityModel.fromJson(Map<String, dynamic> json)
: pm25 = json['p2'],
co2 = json['co'],
humidity = json['hm'],
temperature=json['tp'];
}
This is my debug console:
I've updated my code and I put a set state where I decode the json and now my debug console looks like this:
The following RangeError was thrown building:
RangeError (index): Invalid value: Valid value range is empty: 0
How can I resolve this error?
You can copy paste run full code below
Step 1: dioResponse.data
is Map
, you do not need to do json.decode
again
Step 2: dioResponse.data["current"]
is not a List
, you can directly use Future<AirQualityModel>
code snippet
Future<AirQualityModel> _getAirQuality() async {
var dio = Dio();
var cookieJar;
Response dioResponse;
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
try {
cookieJar = PersistCookieJar(dir: appDocPath + "/.cookies/");
dio.interceptors.add(CookieManager(cookieJar));
dioResponse = await dio.get(
"https://www.airvisual.com/api/v2/node/5ded3e13994dfe107f7013a0");
return AirQualityModel.fromJson(dioResponse.data["current"]);
} catch (e) {
print('catch error: $e');
}
}
working demo
full code
import 'dart:convert';
import 'dart:io';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
class AirQualityModel {
final double pm25;
final double co2;
final double humidity;
final double temperature;
AirQualityModel(this.pm25, this.co2, this.humidity, this.temperature);
AirQualityModel.fromJson(Map<String, dynamic> json)
: pm25 = json['p2'].toDouble(),
co2 = json['co'].toDouble(),
humidity = json['hm'].toDouble(),
temperature = json['tp'].toDouble();
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<AirQualityModel> _future;
Future<AirQualityModel> _getAirQuality() async {
var dio = Dio();
var cookieJar;
Response dioResponse;
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
try {
cookieJar = PersistCookieJar(dir: appDocPath + "/.cookies/");
dio.interceptors.add(CookieManager(cookieJar));
dioResponse = await dio.get(
"https://www.airvisual.com/api/v2/node/5ded3e13994dfe107f7013a0");
return AirQualityModel.fromJson(dioResponse.data["current"]);
} catch (e) {
print('catch error: $e');
}
}
@override
void initState() {
_future = _getAirQuality();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<AirQualityModel> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0, bottom: 6.0, left: 8.0, right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("co2 ${snapshot.data.co2.toString()}"),
Spacer(),
Text(
"pm25 ${snapshot.data.pm25.toString()}",
),
],
),
));
;
}
}
}),
);
}
}