Sam Allen
Sam Allen

Reputation: 35

Value is retrieved only after hot reload in flutter from API

I'm kinda new to flutter, I've been building app using rest API as the backend, whenever I try to load data to display on home page screen from GET API I'm not able to fetch the value until I reload or refresh the widget on the app after pushandreplacement from login screen. Please help me!!! already a week, I still stuck at that bugs.

My code:

class HomePage extends StatefulWidget{

  final String name;
  HomePage(this.name);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage>{

  String token;

  void iniState() {
    super.initState();
    GetRequest().getUserName(token);
  }
  
  Widget build(BuildContext context){
    return Scaffold(
      body: Container(
        alignment: Alignment.topCenter,
        child: SafeArea(
          child: bodyPage(context),
        ),
      ),  
    );   
  }
}

Widget bodyPage(BuildContext context) {
  
  return Scaffold(
    body: SafeArea(
      child: SingleChildScrollView(
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 20.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              SizedBox(height: 15),
              _appBar(context),
            ],
          ),
        ),
      ),
    ),
  );
}

  _appBar(context) {

    String myName = mData.fullname;

    return Row(
      children: <Widget>[
        CircleAvatar(
          backgroundImage: NetworkImage(
              "https://jshopping.in/images/detailed/591/ibboll-Fashion-Mens-Optical-Glasses-Frames-Classic-Square-Wrap-Frame-Luxury-Brand-Men-Clear-Eyeglasses-Frame.jpg"),
        ),
        SizedBox(width: 15),
        Text("Hello, ", 
          style: TextStyle(
            fontWeight: FontWeight.bold,
            fontSize: 18,
          ),
        ),
        Text( 
          myName ?? 'KOOMPI',
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.w600,
              color: Colors.blueAccent)),
      ],
    );
  }

EDIT

getUserName code:

class GetRequest{

  String messageAlert;

  Future<void> getUserName(String _token) async {
    var response = await http.get("${ApiService.url}/dashboard", 
        headers: <String, String>{
        "accept": "application/json",
        "authorization": "Bearer " + _token,
        //"token": _token,
    });
    var responseBody = json.decode(response.body);
    mData = ModelUserData.fromJson(responseBody);
  }
  
}

Here is mData:

class ModelUserData{

  String fullname;

  ModelUserData({
    this.fullname
  });

  ModelUserData.fromJson(Map<String,dynamic> parseJson){
    fullname = parseJson['full_name'];
  }

}
  
var mData = ModelUserData();

Upvotes: 2

Views: 2097

Answers (2)

MickaelHrndz
MickaelHrndz

Reputation: 3832

Firstly, there's a typo and no @override tag to your initState. It should be like that :

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

Then, you don't show where mData comes from. The business logic code is generally essential to give. So that would be GetRequest().

Anyway, the simplest way would be to make getUserName like this :

Future<String> getUserName(String token) async {
     // do your thing
     return userName;
}

With that, you can await getUserName and rebuild when it comes back. So like that in the initState (like token, make a userName State variable) :

() async {
    userName = await GetRequest().getUserName(token);
    setState((){}); // this triggers the widget to rebuild
}();

Now, the widget rebuilds when the request resolves, and you can directly use the userName variable in your UI code.

However, as your app grows, this will quickly become tedious. To make it cleaner, learn state management.

Upvotes: 1

Claudio Redi
Claudio Redi

Reputation: 68400

I changed your method getUserName to return data instead of assigning mData inside it

class GetRequest{

    String messageAlert;

    Future<ModelUserData> getUserName(String _token) async {
        var response = await http.get("${ApiService.url}/dashboard", 
            headers: <String, String>{
            "accept": "application/json",
            "authorization": "Bearer " + _token,
            //"token": _token,
        });
        var responseBody = json.decode(response.body);
        return ModelUserData.fromJson(responseBody);
    }
}

Then on initState you should do

@override
void initState() {
    GetRequest().getUserName(token).then((model) => {
        setState(() => mData = model);
    })

    super.initState();        
} 

The important thing here is to cal setState when model arrives

Upvotes: 1

Related Questions