Home > Back-end >  Null value obtained in Flutter from JSON back-end code?
Null value obtained in Flutter from JSON back-end code?

Time:06-25

I'm currently coding a project with front-end in Flutter Dart, and back-end in JSON. I am trying to pull profile data entered by the user to display in the settings via a FutureBuilder, but every time even though I can view the profile data in the log, it keeps returning as a null value in Flutter. Any suggestions ? Thanks :)

import 'package:json_annotation/json_annotation.dart';
part 'profile_model.g.dart';

@JsonSerializable(explicitToJson: true)
class ProfileModel {
  String? firstname;
  String? lastname;
  String? birthday;
  String? weight;
  ProfileModel({this.firstname, this.lastname, this.birthday, this.weight});

  factory ProfileModel.fromJson(Map<String,dynamic> json) => _$ProfileModelFromJson(json);

  Map<String,dynamic> toJson() => _$ProfileModelToJson(this);
}
class SettingsProfile extends StatefulWidget {
  const SettingsProfile({Key? key}) : super(key: key);
  @override
  _SettingsProfileState createState() => _SettingsProfileState();}

class _SettingsProfileState extends State<SettingsProfile> {
  final _formKey = GlobalKey<FormState>();
  final networkHandler = NetworkHandler();
  bool circular = true;

  Widget page = CircularProgressIndicator();

  @override
  void initState() {super.initState(); checkProfile();}

  void checkProfile() async {
    var response = await networkHandler.get('/profile/checkProfile');
    if (response['status'] == true) {setState(() {page = showProfile();});}
    else {setState(() {page = emptyProfile();});}}

  TextEditingController firstnameController = TextEditingController();
  TextEditingController lastnameController = TextEditingController();
  TextEditingController birthdayController = TextEditingController();
  TextEditingController weightController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Mon profil')),
      body: page,);}

    Future<ProfileModel> _loadProfileModel() async {
      var response = await networkHandler.get("/profile/getData");
      setState(() {ProfileModel profileModel = ProfileModel.fromJson(response["data"]);});
      return response;}

  Widget showProfile() {

    return FutureBuilder<ProfileModel>(
      future: _loadProfileModel(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {

        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.data == null) {
            return Text('no data');
          } else {
            print((snapshot.data()! as Map<String, dynamic>)['firstname'] as String);
            return Text('data present');
          }
        } else if (snapshot.connectionState == ConnectionState.waiting) {
          return Text('Error'); // error
        } else {
          return CircularProgressIndicator(); // loading
        }
      }
    );

    /*
    return Scaffold(
        body: FutureBuilder(
          future: _loadProfileModel(),
          builder: (context, data) {
            if (data.hasError) {
              return Center(child: Text("${data.error}"));
            } else if (data.hasData) {
                    return Card(
                      elevation: 5,
                      margin: EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                      child: Container(
                        padding: EdgeInsets.all(8),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [

                            Expanded(
                                child: Container(
                                  padding: EdgeInsets.only(bottom: 8),
                                  child: Column(
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: [
                                      Padding(
                                        padding: EdgeInsets.only(left: 8, right: 8),
                                        child: Text(
                                          profileModel.firstname.toString(),
                                          style: TextStyle(
                                              fontSize: 16,
                                              fontWeight: FontWeight.bold),
                                        ),
                                      ),
                                      Padding(
                                        padding: EdgeInsets.only(left: 8, right: 8),
                                        child: Text(profileModel.lastname.toString()),
                                      )
                                    ],
                                  ),
                                ))
                          ],
                        ),
                      ),
                    );

            } else {
              return Center(
                child: CircularProgressIndicator(),
              );
            }
          },
        )
    );
     */


    /*
    void fetchData() async {
      var response = await networkHandler.get("/profile/getData");
      setState(() {
        ProfileModel profileModel = ProfileModel.fromJson(response["data"]);
      });
    }
    fetchData();
    return Text(profileModel.firstname.toUpperCase());
     */
  }

  Widget emptyProfile() {
    // GOOD CODE
  }
}

Edit : added this next block of code to simplify the one right above

class _SettingsProfileState extends State<SettingsProfile> {
  final _formKey = GlobalKey<FormState>();
  final networkHandler = NetworkHandler();
  ProfileModel profileModel = ProfileModel();
  bool circular = true;

  TextEditingController firstnameController = TextEditingController();
  TextEditingController lastnameController = TextEditingController();
  TextEditingController birthdayController = TextEditingController();
  TextEditingController weightController = TextEditingController();

  Widget page = CircularProgressIndicator();

  @override
  void initState() {super.initState(); checkProfile(); fetchData();}

  void checkProfile() async {
    var response = await networkHandler.get('/profile/checkProfile');
    if (response['status'] == true) {setState(() {
      page = showProfile();
    });}
    else {setState(() {page = emptyProfile();});}}

  void fetchData() async {
    var foundDetails = await networkHandler.get("/profile/getData");
    setState(() {
      ProfileModel profileModel = ProfileModel.fromJson(foundDetails);
      circular = false;});}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Mon profil')),
      body: page,);}

  Widget showProfile() {
    return Container(
      child: Text(
        profileModel.weight.toString(),
        style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),);}

CodePudding user response:

Try this:

void fetchData() async {
var foundDetails = await networkHandler.get("/profile/getData");
setState(() {
  /*ProfileModel*/ profileModel = ProfileModel.fromJson(foundDetails);
  circular = false;});}

CodePudding user response:

Future<ProfileModel> _loadProfileModel() async {
  var response = await networkHandler.get("/profile/getData");
  setState(() {ProfileModel profileModel = ProfileModel.fromJson(response["data"]);});
  return response;}

What does this method do? it is supposed to return a ProfileModel but instead, it returns the API response, plus, your are declaring a variable inside the setState, this means that it's scope is only that setState method. your method should be:

Future<ProfileModel> _loadProfileModel() async {
    var response = await networkHandler.get("/profile/getData");
    return ProfileModel.fromJson(response["data"]);
}
  • Related