Can't Access The Snapshot.data in Futurebuilder

Issue

I Have created this class named DashboardModel with 4 items:

class DashboardModel {
  int status;
  String message;
  List<dynamic> errors;
  Data data;

  DashboardModel({
    this.status,
    this.message,
    this.errors,
    this.data,
  });
}

No problem here.
Then I have this function for getting the info from my API as below:

Future<DashboardModel> getDashboard() async {
    var url = "https://SomeAPI.kuttenbugeservice.ru";
    var _pref = await SharedPreferences.getInstance();
    String token = _pref.getString('token');
    var header = {'token': token, 'najvaToken': _pref.getString('najvaToken')};
    var response = await http.get(url, headers: header);
    //-----------------------------------------------------------------------
    var model = DashboardModel.fromJson(json.decode(response.body));
    return model;
  }

Then I want to get the model returned by getDashboard() and display it As below:

FutureBuilder > builder > AnimatedSwitcher > child:

FutureBuilder(
          future: _service.getDashboard(),
          builder: (context, snapshot) {
            print('Must Be Ckecked${snapshot.data}');
            return AnimatedSwitcher(
                duration: const Duration(seconds: 1),
                child: (snapshot.connectionState == ConnectionState.waiting)
                    ? Align(
                        alignment: Alignment.center,
                        child: Container(
                          child: LinearProgressIndicator(
                            color: Colors.amber,
                          ),
                        ))
                    : **HomeViewPagerFul(
                   data: snapshot.data,
                 );**
                );
          },
        ),

Problem Starts here as the {snapshot.data} which holds the loaded DashboardModel can’t be passed to HomeViewPagerFul() as content.

Below As You can see I have printed the snapshot.data to see what is wrong:

print('Must Be Ckecked${snapshot.data}');

but It returns :

I/flutter ( 9806): Must Be Ckecked[Instance of 'DashboardModel']

=======================================================

So basically the Dashboard model is fine. the getdashboard() function is doing it’s job.
FutureBuilder is Showing promise but I can’t access the snapshot.

I can't use snapshot.data.status which I can Access in getDashboard()

Simply I face this error:

A value of type 'Object?' can't be assigned to a variable of type 'DashboardModel'.
Try changing the type of the variable, or casting the right-hand type to 'DashboardModel'.

The HomeViewPagerFul() if needed:

class HomeViewPagerFul extends StatefulWidget {
  final DashboardModel data;

  HomeViewPagerFul({required this.data});

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

Solution

You have 2 issues:

  1. You should specify the type to FutureBuilder: FutureBuilder<DashboardModel>
  2. snapshot does not have the data while its loading, you should check snapshot.hasData and display a loading widget if the data has not yet been fetched

Concretely:

FutureBuilder<DashboardModel>(
  future: _service.getDashboard(),
  builder: (context, snapshot) {
    if (!snapshot.hasData) {
      return LoadingWidget();
    }
    print('Must Be Ckecked${snapshot.data}');
    return AnimatedSwitcher(
      duration: const Duration(seconds: 1),
      child: (snapshot.connectionState == ConnectionState.waiting)
          ? Align(
              alignment: Alignment.center,
              child: Container(
                child: LinearProgressIndicator(
                  color: Colors.amber,
                ),
              ))
          : HomeViewPagerFul(
              data: snapshot.data!, // Safe since you checked if hasData
            ),
    );
  },
)

Answered By – Lulupointu

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.