Home > Mobile >  Error Flutter: List<dynamic> is not a subtype of type Map<String, dynamic>
Error Flutter: List<dynamic> is not a subtype of type Map<String, dynamic>

Time:09-29

Can someone help me to fix this problem.

I am currently building an app to read data from MySQl. I can't fetch data from json using flutter http request because it got this Error: List is not a subtype of type Map<String, dynamic> Can somebody help me please.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' show get;
import 'dart:convert';

void main() => runApp(
    MyApp(
        txtscr: obtenirTxtscr()
    )
);
class Txtscr {
  final String id;
  final String content;
  Txtscr({
    required this.id,
    required this.content,
  });

  factory Txtscr.fromJson(Map<String, dynamic> jsonData) {
    return Txtscr(
      id: jsonData['id'],
      content: jsonData['content'],
    );
  }
}
Future<Txtscr> obtenirTxtscr() async {
final jsonEndpoint = Uri.parse('https://www.domaine.com/txtscr.php');
final response = await get(jsonEndpoint);
if(response.statusCode == 200) {
return Txtscr.fromJson(json.decode(response.body));
 } else {
  throw Exception("Error al obtenir el JSON");}}
class MyApp extends StatelessWidget {
final Future<Txtscr> txtscr;

  MyApp({Key? key, required this.txtscr}): super(key: key);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: "JSON URL",
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("Text Json"),
        ),
        body: Center(
          child: FutureBuilder<Txtscr>(
            future: txtscr,
            builder: (context, snapshot) {
              if(snapshot.hasData) {
                return Text(
                    "ID: "   snapshot.data!.id   "\n"  
                    "Content: "   snapshot.data!.content
                );
              } else if(snapshot.hasError) {
                return Text("${snapshot.error}");
              }
              return CircularProgressIndicator();
            },
          ),),),
    );
  }
}

How do I rectify this error?

CodePudding user response:

Your JSON result is an array (list), and not a map as expected by this part of your code: Txtscr.fromJson(json.decode(response.body)). You can solve it with these steps:

  1. Interpret your results as a List of Txtscr objects. Refactor your future like this:
Future<List<Txtscr>> obtenirTxtscr() async {      // <-- added List
  final jsonEndpoint = Uri.parse('https://www.domaine.com/txtscr.php');
  final response = await get(jsonEndpoint);
  if (response.statusCode == 200) {
      return (json.decode(response.body) as List) // <-- added mapping
          .map((entry) => Txtscr.fromJson(entry))
          .toList();
  } else {
    throw Exception("Error al obtenir el JSON");
  }
}

  1. Change the future declaration in MyApp as well:
class MyApp extends StatelessWidget {
 Future<List<Txtscr>> txtscr;
  1. Now you will get an an array (list) as a result in your FutureBuilder. You have to decide what do you want to do if the list has 1 item or more items.
FutureBuilder<Txtscr>(
  future: txtscr,
  builder: (context, snapshot) {
    if(snapshot.hasData) {
      // here you will have snapshot.data! as a list
      // so you can use the below code for first element
      // but it could have 0 or more items, you have to handle it
      return Text(
          "ID: "   snapshot.data![0].id   "\n"  
          "Content: "   snapshot.data[0]!.content
      );
    } else if(snapshot.hasError) {
      return Text("${snapshot.error}");
    }
    return CircularProgressIndicator();
  },
)

CodePudding user response:

Just Change this line from

return Txtscr.fromJson(json.decode(response.body));

to

return Txtscr.fromJson(json.decode(response.body)[0]);

Note: Array JSON is not a valid Map, that's why you are getting the error.

  • Related