0

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?

2 Answers 2

1

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)));
Sign up to request clarification or add additional context in comments.

2 Comments

With this one I am finally getting very close, just got this displayed: [Instance of 'Subject', Instance of 'Subject', Instance of 'Subject', Instance of 'Subject', Instance of 'Subject']
Yes, its because each of it is an object. In the snapshot.hasData create an new List<Subject>, and save snapshot.data to it. To show all of the data, use ListView
0

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.

1 Comment

Got the error: Expected a value of type 'FutureOr<List<Subject>>', but got one of type 'MappedListIterable<dynamic, dynamic>'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.