Home > Software design >  How to access an item from a json through FutureBuilder?
How to access an item from a json through FutureBuilder?

Time:03-18

i'm getting a json and would like to access certain items.

The method below returns the json I need to access.

search(cpf) async {
    try {
      final response = await http.get(
          Uri.parse(BaseUrl.baseUrl   'api/produtor/serach/$data'));
      if (response.statusCode == 200) {
        final jsonMap = jsonDecode(response.body) as Map<String, dynamic>;
        final user = User.fromJson(jsonMap);
        return user;
      } else {
        throw Exception("Error");
      }
    } catch (e) {
      throw Exception(e.toString());
    }
  }

I created this example to try to access the items.

Future? _list;

  @override
  void initState() {
    super.initState();
    _list = widget.produtorServices.buscaProdutorPorCPF("56039891653");
  }

 Widget build(BuildContext context) {
    return new Scaffold(
      body: Container(
        child: FutureBuilder(
          future: widget.produtorServices.buscaProdutorPorCPF("56039891653"),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.connectionState != ConnectionState.done) {
              return const Center(child: CircularProgressIndicator());
            }
            if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }
            if (!snapshot.hasData) {
              return Text("Null returned");
            }
            final user = snapshot.data as Produtor;
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('${user.id}: ${user.name}'),
              ],
            ); //Text(snapshot.data!.ip);
          },
        ),
      ),
    );
  }
}

Here is json

[
   {
      "user":{
         "roles":[
            "622f533b5ee724631428f469"
         ],
         "_id":"622f78fbf297571510cb4e32",
         "nome":"XXXX",
         "email":"[email protected]"
      }
   }
]

How do I add eg a text widget and access the json item?

I've already tried to solve using the model too. I declare User user and then I try to access the variable like this: user.name

But I get the error:

Error: Exception: Expected a value of type 'Map<String, dynamic>', but got one of type 'List'

I appreciate if anyone can help me analyze this!

CodePudding user response:

You create two data classes to hold your JSON object.

class Users {
  List<User> users;

  Users({
    required this.users,
  });

  factory Users.fromJson(Map<String, dynamic> json) => Users(
    users: (json['users'] as List<dynamic>)
      .map((e) => User.fromJson(e as Map<String, dynamic>))
      .toList(),
  );
}

class User {
  List<String>? roles;
  String? id;
  String? nome;
  String? email;

  User({
    this.roles,
    this.id,
    this.nome,
    this.email,
  });

  factory User.fromJson(Map<String, dynamic> json) => User(
    roles: (json['roles'] as List<dynamic>?)?.map((e) => 
      e as String).toList(),
    id: json['id'] as String?,
    nome: json['nome'] as String?,
    email: json['email'] as String?,
  );
}

Then in your search method:

if (response.statusCode == 200) {
  final jsonMap = jsonDecode(response.body) as Map<String, dynamic>;
  final users = Users.fromJson(jsonMap);
  return users;
} else {
  throw Exception("Error");
}

In your FutureBuilder:

if (snapshot.connectionState != ConnectionState.done) {
  return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
  return Text("${snapshot.error}");
}
if (!snapshot.hasData) {
  return Text("Null returned");
}
final userList = snapshot.data as Users;
return Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: List<Text>.generate(
    userList.users.length,
    (index) {
      final user = userList.users[index];
      return Text('${user.id}: ${user.nome}, ${user.email}, ${user.roles}');
    },
  ),
); //Text(snapshot.data!.ip);
  • Related