简体   繁体   中英

Flutter - A value of type 'List<Map<String, Object>>' can't be assigned to a variable of type 'List<Classes>'

I'm new to flutter, i need to show my sample array of objects in a list view. but when i try to set my array to my list objects its show an error like

A value of type 'List<Map<String, Object>>' can't be assigned to a variable of type 'List'.

i don't know what I'm doing in wrong? actually i don't know. is this the right way to do? can anyone help me to find where am i wrong?

here is my dart file:

class Classes {

        late String title;
        late List<CoursesOptions> classes;

        Classes({required this.title, required this.classes});

        factory Classes.fromJson(Map<String, dynamic> parsedJson){

            var list = parsedJson['data'] as List;
            print(list.runtimeType);
            List<CoursesOptions> dataList = list.map((i) => CoursesOptions.fromJson(i)).toList();


            return Classes(
                title: parsedJson['title'],
                classes: dataList
            );
        }
}
  class CoursesOptions {
        late int id;
        late String value;

        CoursesOptions({required this.id, required this.value});

        factory CoursesOptions.fromJson(Map<String, dynamic> parsedJson){
            return CoursesOptions(
                id : parsedJson['id'],
                value : parsedJson['value']
            );
        }
        }
class ClassSelectionPage extends StatefulWidget {
  @override
  _ClassSelectionPageState createState() => _ClassSelectionPageState();
}

class _ClassSelectionPageState extends State<ClassSelectionPage> {

  late List<Classes> futureData;
  @override
  void initState() {
    super.initState();
      var courses = [
      {
        "title": 'Choose your class',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'Grade - 10',
          },
          {
            "id": 2,
            "value": 'O/L',
          },
        ],
      },
     
{
        "title": 'Choose your A/L stream',
        "coursesOptions": [
         {
            "id": 1,
            "value": 'SO',
          },
          {
            "id": 2,
            "value": 'dart',
          },
          {
            "id": 3,
            'value': 'Java',
          },
          {
            "id": 4,
            "value": 'android',
          },
        ],
      },     {
        "title": 'Choose your A/L stream',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'SO',
          },
          {
            "id": 2,
            "value": 'dart',
          },
          {
            "id": 3,
            'value': 'Java',
          },
          {
            "id": 4,
            "value": 'android',
          },
        ],
      },
  
        ];
        
    futureData = courses;// this is the point that I'm getting that error and i tried to set this value with  Classes.fromJson(futureData) its says that The argument type 'List<Map<String, Object>>' can't be assigned to the parameter type 'Map<String, dynamic> 
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Container(
              child: Text('ok'),
            ),
            Expanded(
              child: FutureBuilder<List<Classes>>(
                future: futureData,
             builder: (context, snapshot) {
              if (snapshot.hasData) {
                List<Classes>? 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();
            },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Where the problem is happening is in your initState:

futureData= courses

futureData is of type List<Classes> and courses is List<Map<String, Object>> because you haven't de-serialized its data.

    futureData = courses.map((i) => Classes.fromJson(i)).toList();

With the above snippet you have your data completely de-serialized.

Now other problems you had were that in your courses variable you had your courses list inside the coursesOptions key but in your model you look for the data key, which does not exists at least in this test data. also most probably you wont be deserializing from a list in memory and would have something like a repository method calling the Future itself so the type of futureValue should be a Future.

I made a working example and corrected the errors in the code below.

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      home: Scaffold(
    body: ClassSelectionPage(),
  )));
}

class Classes {
  late String title;
  late List<CoursesOptions> classes;

  Classes({required this.title, required this.classes});

  factory Classes.fromJson(Map<String, dynamic> parsedJson) {
    var list = parsedJson['coursesOptions'] as List;
    print(list.runtimeType);
    List<CoursesOptions> dataList = list.map((i) => CoursesOptions.fromJson(i)).toList();

    return Classes(title: parsedJson['title'], classes: dataList);
  }
}

class CoursesOptions {
  late int id;
  late String value;

  CoursesOptions({required this.id, required this.value});

  factory CoursesOptions.fromJson(Map<String, dynamic> parsedJson) {
    return CoursesOptions(id: parsedJson['id'], value: parsedJson['value']);
  }
}

class ClassSelectionPage extends StatefulWidget {
  @override
  _ClassSelectionPageState createState() => _ClassSelectionPageState();
}

class _ClassSelectionPageState extends State<ClassSelectionPage> {
  late Future<List<Classes>> futureData;

  @override
  void initState() {
    super.initState();
    var courses = [
      {
        "title": 'Choose your class',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'Grade - 10',
          },
          {
            "id": 2,
            "value": 'O/L',
          },
        ],
      },
      {
        "title": 'Choose your A/L stream',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'SO',
          },
          {
            "id": 2,
            "value": 'dart',
          },
          {
            "id": 3,
            'value': 'Java',
          },
          {
            "id": 4,
            "value": 'android',
          },
        ],
      },
      {
        "title": 'Choose your A/L stream',
        "coursesOptions": [
          {
            "id": 1,
            "value": 'SO',
          },
          {
            "id": 2,
            "value": 'dart',
          },
          {
            "id": 3,
            'value': 'Java',
          },
          {
            "id": 4,
            "value": 'android',
          },
        ],
      },
    ];

    futureData = Future.value(courses.map((i) => Classes.fromJson(i)).toList());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Container(
              child: Text('ok'),
            ),
            Expanded(
              child: FutureBuilder<List<Classes>>(
                future: futureData,
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    List<Classes>? data = snapshot.data;
                    return ListView.builder(
                        itemCount: data!.length,
                        itemBuilder: (BuildContext context, int index) {
                          return ExpansionTile(
                            title: Text(data[index].title),
                            children: data[index]
                                .classes
                                .map((e) => ListTile(
                                      title: Text(e.value),
                                    ))
                                .toList(),
                          );
                        });
                  } else if (snapshot.hasError) {
                    return Text("${snapshot.error}");
                  }
                  // By default show a loading spinner.
                  return CircularProgressIndicator();
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM