st4tic
st4tic

Reputation: 427

My future builder is not working, snapshot data is empty

My future builder is not working snapshot data is empty. In other future builder cases my code works correctly. My api gets correct data too. this is my run terminal:


  static Future<List<User>> getUser() async {
    var url = '${Constants.BASE_NO_TOKEN_DOMAIN}api?action=user_profile&token=${Constants.USER_TOKEN}';
    final response = await http.get(Uri.parse(url));
    final body = jsonDecode(response.body);
    return body['data'].map<User>(User.fromJson).toList();
  }

  @override
  void initState() {
    super.initState();
    userFuture = getUser();
    getToken();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Color.fromRGBO(245, 248, 250, 1),
        padding: EdgeInsets.only(left: 16, top: 25, right: 16),
        child: ListView(
          children: [
            Container(
              decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.all(Radius.circular(12))),
              padding: EdgeInsets.only(left: 10, right: 10),
              height: 120,
              child: FutureBuilder<List<User>>(
                future: userFuture,
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return CircularProgressIndicator();
                  } else if (snapshot.hasData) {
                    final user = snapshot.data!;
                    return buildUser(user);
                  } else {
                    print(snapshot.data);
                    print(snapshot.error);
                    return Text("No widget to build");
                  }
                },
              ) // FutureBuilder
            ),  //Container
             

Upvotes: 1

Views: 717

Answers (2)

eamirho3ein
eamirho3ein

Reputation: 17950

First you have a Map not list so you need to change your getUser to this:

static Future<User> getUser() async {//<--- change this
    var url = '${Constants.BASE_NO_TOKEN_DOMAIN}api?action=user_profile&token=${Constants.USER_TOKEN}';
    final response = await http.get(Uri.parse(url));
    final body = jsonDecode(response.body);
    return User.fromJson(body['data']);//<--- change this
  }

second in your model class you are parsing avatar wrong, try this:

class User {
  final String fullName;
  final String avatar;
  final int phone;
  const User({
    required this.fullName,
    required this.avatar,
    required this.phone,
  });
  static User fromJson(json) => User(
        fullName: json['full_name'],
        avatar: json['avatar']['100'], // <--- change this
        phone: json['phone'],
      );
}

also change your FutureBuilder to this:

FutureBuilder<User>(
  ...
)

Upvotes: 2

Ivo
Ivo

Reputation: 23357

Most likely your api returns a single user and not a list of them. If you still need a list you could wrap it in one. So maybe try this:

  static Future<List<User>> getUser() async {
    var url = '${Constants.BASE_NO_TOKEN_DOMAIN}api?action=user_profile&token=${Constants.USER_TOKEN}';
    final response = await http.get(Uri.parse(url));
    final body = jsonDecode(response.body);
    return [User.fromJson(body['data'])];
  }

EDIT:

From you other comments I could conclude that the parsing of the user goes wrong. You do

avatar: json['avatar_100']

but there is no field named that. You should try

avatar: json['avatar']['100']

Upvotes: 1

Related Questions