Home > Blockchain >  Mysql query result in Flutter Widgets
Mysql query result in Flutter Widgets

Time:10-13

Trying to display in Flutter a result I am receiving from my Node.JS server via MySQL query:

[{"NAME":"Matematicas"},
{"NAME":"Naturales"},
{"NAME":"Ciencias Sociales"},
{"NAME":"Lenguaje"},
{"NAME":"Religion"}]

This is the class I am using in Flutter to handle it:

class Subject {
  final String name;

  Subject({
    required this.name,
  });

  factory Subject.fromJson(Map<String, dynamic> json) {
    return Subject(name: json['NAME']);
  }
}

This is the method from which I obtain the data:

Future<Subject> fetchSubject() async {
  var prefs = await SharedPreferences.getInstance();
  var token = prefs.getString('token');
  var response = await http.get(Uri.parse('http://localhost:8000/subjects'),
      headers: {'x-access-token': token!});

  print(response.body);
  return Subject.fromJson(jsonDecode(response.body));
}

This is my initState

void initState() {
    super.initState();
    futureSubject = fetchSubject();
  }

This is my Widget build piece:

Widget build(BuildContext context) {
    return FutureBuilder<Subject>(
        future: fetchSubject(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return const Center(
              child: Text('Error'),
            );
          } else if (snapshot.hasData) {
            return Scaffold(
                appBar: AppBar(
                  title: Text('Materias'),
                  backgroundColor: Colors.green[300],
                  actions: [
                    Padding(
                      padding: EdgeInsets.only(right: 3.0),
                      child: IconButton(
                        icon: Icon(Icons.logout),
                        //TODO llamar funcion logout
                        onPressed: () {},
                        iconSize: 26,
                      ),
                    )
                  ],
                ),
                body: Text(snapshot.data!.name));
          } else {
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
        });
  }

This is what I get:

Uncaught (in promise) Error: Expected a value of type 'Map<String, dynamic>', but got one of type 'List<dynamic>'

I just want to display the information I am receiving as a List or table like fashion. Any ideas on what and how to refactor this?

CodePudding user response:

Its happened because your return data is an array. Try this

 final data = json.decode(response.body);
 return List<Subject>.from(data.map((value) => Subject.fromJson(value)));

CodePudding user response:

It looks like the fetchSubject method needs to be modified and the widget itself. The data you displayed is a List of objects, thus the error that you are trying to see type Map<String, dynamic> from jsonDecode(response.body) but it returns a List<dynamic> instead. Thus, you need to modify fetchSubject and get a List<Subject from your API not just an object. Or, you need to update an API. Just as an example (haven't tested it but should work):

Future<List<Subject>> fetchSubject() async {
  var prefs = await SharedPreferences.getInstance();
  var token = prefs.getString('token');
  var response = await http.get(Uri.parse('http://localhost:8000/subjects'),
      headers: {'x-access-token': token!});

  print(response.body);
  return jsonDecode(response.body).map((item) => Subject.fromJson(item));
}

and change all logic to handle a List of Subject and not just Subject. The JSON your API returns is a list (array) of objects, not just an object.

  • Related