Solved: A value of type 'List<Data>?' can't be assigned to a variable of type 'List<Data>'

Question

Asked by Artur U on January 08, 2022 (source).

I'm trying to fetch data in Flutter from test API using this tutorial - https://flutterforyou.com/how-to-fetch-data-from-api-and-show-in-flutter-listview/

When I copy the code VS Code throws this error, and I do not understand, what I need to do enter image description here

Thank for your responses, and sorry in advance for dummy question, code example

    Future <List<Data>> fetchData() async {
  
  final response =
      await http.get(Uri.parse('https://jsonplaceholder.typicode.com/albums'));
  if (response.statusCode == 200) {
    List jsonResponse = json.decode(response.body);
      return jsonResponse.map((data) => Data.fromJson(data)).toList();
  } else {
    throw Exception('Unexpected error occured!');
  }
}

class Data {
  final int userId;
  final int id;
  final String title;

  Data({required this.userId, required this.id, required this.title});

  factory Data.fromJson(Map<String, dynamic> json) {
    return Data(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
    );
  }
}
class _MyAppState extends State<MyApp> {
  late Future <List<Data>> futureData;

  @override
  void initState() {
    super.initState();
    futureData = fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter API and ListView Example',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter ListView'),
        ),
        body: Center(
          child: FutureBuilder <List<Data>>(
            future: futureData,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                List<Data> data = snapshot.data;
                return 
                ListView.builder(
                itemCount: data.length,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    height: 75,
                    color: Colors.white,
                    child: Center(child: Text(data[index].title),
                  ),);
                }
              );
              } else if (snapshot.hasError) {
                return Text("${snapshot.error}");
              }
              // By default show a loading spinner.
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}

Answer

Question answered by emanuel s (source).

The meaning of List? means that this list can be null.

But List means that this list can not be null, but could be empty as [];

Solutions: Make List be List? This will make your List nullable, and you will have to refactor your code anywhere where it is used to perform null checks. For this, edit your builder method line to this:

List<Data>? data = snapshot.data;

I'd not recommend this though, because you shall have to perform manual nullity checks in your code, which is not that beautiful

Check for nullity of List? I'd recommend using this, you have to change your builder method to this for null checking..

List<Data> data = snapshot.data ?? <Data>[];

What this code means is it will try snapshot.data, if it returns null, it will assign <Data>[] to the data array. Making it an empty array.

This is more easy to deal with(based on my views) than a nullable array!

ASYNC-AWAIT DART FLUTTER
SHARE: