0

I'm new to Flutter and Dart, and I'm trying to write a application to test it. I have an api that I'm getting the data for the app, and was trying to use the StatefulWidget and the FutureBuilder.

When I run the method to call the api I have the results (used print() to test it), but when I get the data from loadData method it retrives null.

So loadData prints the data, initState and FutureBuilder the data returns null. What am I missing here.

I have added the service and the models used for the request... hope it help.

Future<CoachesModelRes> loadData(Profile _profile) async {
await getPost(_profile.getToken()).then((response) {
  if (response.statusCode == 200) {
    CoachesModelRes coaches = coachesModel.postFromJson(response.body);

    if (coaches.count > 0) {
      print(coaches.count);
      print(coaches.coaches[0].description);
      return coaches;
    } else {
      return null;
    }
  } else {
    String code = response.statusCode.toString();
    return null;
  }
}).catchError((error) {
  print(error.toString());
  return null;
});
}

@override
void initState() {
  super.initState();
  print(widget.profile.getToken());
  data = loadData(widget.profile);
  data.then((data_) async {
    var cenas = data_.count;
    print("asdasd $cenas");
  });
}

Future<CoachesModelRes> data;

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: appWhiteColor,
  appBar: applicationBar(),
  drawer: adminDrawer(widget.profile, AdminDrawerListEnum.coaches, context),
  body: FutureBuilder<CoachesModelRes>(
    future: data,
    builder: (context, snapshot) {
      //print(snapshot.data.count.toString());
      if (snapshot.hasData) {
        return Text("nop");
      } else if (snapshot.hasError) {
        return Text("${snapshot.error}");
      }
      return Text("nop");
      // By default, show a loading spinner.
      return CircularProgressIndicator();
    },
  ),
);
}

Future<http.Response> getPost(String token) async {
   final response = await http.get(new Uri.http("$apiUrl", "$coachesEndPoint"),
     headers: {
      HttpHeaders.contentTypeHeader: 'application/json',
      HttpHeaders.authorizationHeader : 'Bearer $token'
     },
  );
  return response;
}


CoachesModelRes postFromJson(String str) => CoachesModelRes.fromJson(json.decode(str));

class CoachesModelRes {

 int count;
 List<CoachModelRes> coaches;

 CoachesModelRes({
    this.count,
    this.coaches,
 });

 factory CoachesModelRes.fromJson(Map<String, dynamic> json) => new CoachesModelRes(
    count: json["count"],

    coaches: (json["coaches"] as List).map((i) => CoachModelRes.fromJson(i)).toList(),
 );
}


CoachModelRes postFromJson(String str) => CoachModelRes.fromJson(json.decode(str));

class CoachModelRes {

    String id;
    String firstName;
    String lastName;
    String description;
    String username;
    String notes;
    List<String> roles;

    CoachModelRes({
        this.id,
        this.firstName,
        this.lastName,
        this.description,
        this.username,
        this.notes,
        this.roles,
    });

    factory CoachModelRes.fromJson(Map<String, dynamic> json) => new CoachModelRes(
        id: json["id"],
        firstName: json["firstName"],
        lastName: json["lastName"],
        description: json["description"],
        username: json["username"],
        notes: json["notes"],
        roles: new List<String>.from(json["roles"]),
    );
}
guren
  • 122
  • 2
  • 9
  • 1
    If I'm not mustaken, the issue that I'm having here is that I'm not returning the data in the loadData method at the end. I'm building other app and with a different aproach it is working. I'll update this in some days, with a valid response. – guren Feb 18 '20 at 11:11

2 Answers2

0
 Future<CoachesModelRes> loadData(Profile _profile) async {
     final response = await  getPost(_profile.getToken());
    try{if (response.statusCode == 200) {
    CoachesModelRes coaches = coachesModel.postFromJson(response.body);
    if (coaches.count > 0) {
      print(coaches.count);
      print(coaches.coaches[0].description);
      return coaches;
    } else {
      return null;
    }
  } else {
    String code = response.statusCode.toString();
    return null;
  }}catch(e){

    return null ; 
  }
   } 
@override
void initState() {
  super.initState();

}

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: appWhiteColor,
  appBar: applicationBar(),
  drawer: adminDrawer(widget.profile, AdminDrawerListEnum.coaches, context),
  body: FutureBuilder<CoachesModelRes>(
    future: loadData(widget.profile),
    builder: (context, snapshot) {
      //print(snapshot.data.count.toString());
      if (snapshot.hasData) {
        return Text("nop");
      } else if (snapshot.hasError) {
        return Text("${snapshot.error}");
      }
      return Text("nop");
      // By default, show a loading spinner.
      return CircularProgressIndicator();
    },
  ),
);
}
nordine enn
  • 78
  • 1
  • 8
0

The issue here is that the return statement should be at the end of the method.

Because the getPost will return data to the loadData.

And when the getPost finishes the loadData will return data to the method that invoked him.

In my case, the loadData is not returning anything so the snapshot in the FutureBuilder it's always null.

It's logic that it is this way now, but at the time I could not figure it out :\

Future<CoachesModelRes> loadData(Profile _profile) async {
// So I need to create a variable to return
CoachesModelRes response;
//-----
await getPost(_profile.getToken()).then((response) {
  if (response.statusCode == 200) {
    CoachesModelRes coaches = coachesModel.postFromJson(response.body);

       if (coaches.count > 0) {
         print(coaches.count);
         print(coaches.coaches[0].description);
         // Set the variable value
         response = coaches;
         //-----
       } else {
         // Set the variable value
         response = null;
         //-----
       }
     } else {
       String code = response.statusCode.toString();
       // Set the variable value
       response = null;
       //-----
     }
   }).catchError((error) {
     print(error.toString());
     // Set the variable value
     response = null;
     //-----
   });
   // And at the end return the response variable
   return response;
   //-----
}
guren
  • 122
  • 2
  • 9