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:
- Interpret your results as a
List
ofTxtscr
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");
}
}
- Change the future declaration in
MyApp
as well:
class MyApp extends StatelessWidget {
Future<List<Txtscr>> txtscr;
- 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.