I am trying to connect an API to my application and have come across the error: _TypeError (type 'Null' is not a subtype of type 'String')
The error occurs on the line: title: Text(snapshot.data?[i].hourly),
I thought that I had implemented null safety to avoid this error but it doesn't seem to have worked. I would appreciate any help!
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MaterialApp(
home: HomePage(),
debugShowCheckedModeBanner: false,
));
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future getUserData() async {
var response = await http.get(Uri.parse(
'https://api.open-meteo.com/v1/forecast? latitude=52.52&longitude=13.41&hourly=temperature_2m'));
var jsonData = jsonDecode(response.body);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Rangers Tool'),
),
body: Center(
child: Card(
child: FutureBuilder(
future: getUserData(),
builder: (context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data?.length,
itemBuilder: (context, i) {
return ListTile(
title: Text(snapshot.data?[i].hourly),
subtitle: Text(snapshot.data[i]?.latitude),
);
});
} else {
return const Center(child: CircularProgressIndicator());
}
},
))),
);
}
}
getUserData() {}
class User {
final String? hourly,
time,
temperature_2m,
longitude,
generationtime_m,
hourly_units,
latitude;
User(this.longitude, this.latitude, this.hourly, this.time,
this.temperature_2m, this.generationtime_m, this.hourly_units);
}
CodePudding user response:
According to the api response
(response data link), your response data
is not an array of json
but you are try to render the json object as array
and you are trying to parse the json field as invalid way thats why the error occurred.
You can follow the bellow code spinet and can see that how I can parse the json then can modify based on your requirement.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(
MaterialApp(
home: HomePage(),
debugShowCheckedModeBanner: false,
),
);
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future<dynamic> getUserData() async {
var response = await http.get(Uri.parse(
'https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&hourly=temperature_2m'));
var jsonData = jsonDecode(response.body);
return jsonData;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Rangers Tool'),
),
body: Center(
child: Card(
child: FutureBuilder(
future: getUserData(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
var hourly = snapshot.data['hourly'];
return ListTile(
title: Text(
"time: ${hourly['time'][0]} - temperature_2m: ${hourly['temperature_2m'][0]}",
),
subtitle: Text(
"latitude: ${snapshot.data['latitude']}",
),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
),
),
);
}
}
getUserData() {}
class User {
final String? hourly,
time,
temperature_2m,
longitude,
generationtime_m,
hourly_units,
latitude;
User(this.longitude, this.latitude, this.hourly, this.time,
this.temperature_2m, this.generationtime_m, this.hourly_units);
}
CodePudding user response:
Change two things
Before
Future getUserData() async {
var response = await http.get(Uri.parse(
'https://api.open-meteo.com/v1/forecast? latitude=52.52&longitude=13.41&hourly=temperature_2m'));
var jsonData = jsonDecode(response.body);
}
Next
Future getUserData() async {
var response = await http.get(Uri.parse(
'https://api.open-meteo.com/v1/forecast? latitude=52.52&longitude=13.41&hourly=temperature_2m'));
return jsonDecode(response.body);
}
before
if (!snapshot.hasData)
next
if (snapshot.hasData)