I am learning how to perform http requests in Dart / Flutter.
I tried to perform a GET request from a simple api at https://jsonplaceholder.typicode.com/posts
I got the raw json, but need to parse & map it out.
My problem is the documentation I was following seems outdated, and the syntax I used with LIST no longer follows null-safety.
- Is there a better way to perform http requests in Dart / Flutter?
- Is there a better way to initialize my
List<DataModel> model;
that allows for null-safety compliance without factoring a lot of code?
main.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'home_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeScreen(),
);
}
}
home_screen.dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'data_model.dart';
import 'dart:convert' as convert;
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<DataModel> model;
@override
void initState() {
getData();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Http Get Request'),
),
body: ListView.builder(itemBuilder: (BuildContext context, int index){
return const Card(
child: ExpansionTile(
title: Text(model[index].title),
children: [Text(model[index].body)],
),
);
},
itemCount: model.length,
),
);
}
Future<void> getData() async {
Uri url = Uri.https('jsonplaceholder.typicode.com', '/posts');
http.Response response = await http.get(url);
print(response.body);
List<dynamic> body = convert.jsonDecode(response.body);
model = body.map((dynamic item) => DataModel.fromJson(item)).toList();
setState(() {
});
}
}
data_model.dart
class DataModel {
late int userId;
late int id;
late String title;
late String body;
DataModel({required this.userId, required this.id, required this.title, required this.body});
DataModel.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
id = json['id'];
title = json['title'];
body = json['body'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['userId'] = this.userId;
data['id'] = this.id;
data['title'] = this.title;
data['body'] = this.body;
return data;
}
}
CodePudding user response:
You should be able to use the keyword late
and make it a final
variable since initState()
is always called and so model
cannot be null.
You can learn more about late final variables here
class _HomeScreenState extends State<HomeScreen> {
late final List<DataModel> model;
Note: By suggesting you to use
final
, I'm assuming that you don't reassignmodel
anywhere else.