Riverpod – FutureProvider refresh data, does go to loading

I’m using FutureProvider in Riverpod for Flutter to return an API call with data and update the UI. While its loading it shows the CircularIndicator, then when loaded it displays the data on the home page. This is working the first time.

However, at a later stage in the app, the user triggers the call again, and it updates the UI on the home page. This is working, and I refresh the provider from the other screen, and the UI of the main screen updates. However, it doesn’t show the loading indicator, it just updates automatically after a few seconds when it fetchs the result.

Why isn’t the loading() state being called the second time.

Here are my 2 providers:

final getCalendarApiProvider = Provider<GetCalendarApi>(
  (ref) => GetCalendarApi(),

final calendarResponseProvider = FutureProvider<List<CalendarResponse>>((ref) async {
  return ref.read(getCalendarApiProvider).getCalendar(ref.read(startDateProvider), ref.read(endDateProvider));

Here is my main page:

class MainMenuScreen extends ConsumerStatefulWidget {
  const MainMenuScreen({
    Key? key,
  }) : super(key: key);

  ConsumerState createState() => _MainMenuScreenState();

class _MainMenuScreenState extends ConsumerState<MainMenuScreen> {
  String _selectedDate = '';

  Widget build(BuildContext context) {

    print('Main Build Called');

    AsyncValue<List<CalendarResponse>> calendarResponse = ref.watch(calendarResponseProvider);

    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: true,
        title: const Text(
          "My Sessions",
          style: TextStyle(fontSize: 18, fontWeight: FontWeight.normal),
        actions: [
            icon: Icon(
              color: Colors.white,
            onPressed: () {
        centerTitle: true,
      drawer: const DrawerWidget(),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          calendarResponse.when(data: (data) {
            print('DATA length: ${data.length}');
            return Expanded(
              child: ListView.builder(

                  scrollDirection: Axis.vertical,
                  shrinkWrap: true,
                  itemCount: data.length,
                  itemBuilder: ((context, index) {

                    return Text(data[index].studentNames ?? '-');

          }, error: ((error, stackTrace) {
            return Text('Error: ${error.toString()}');
          }), loading: (() {
            return const Center(
              child: CircularProgressIndicator(),

Here is the class of the api call:

class GetCalendarApi {

  Future<List<CalendarResponse>> getCalendar(DateTime startTime, DateTime endTime) async {

    log('startTime $startTime', name: logGetCalendarApi);
    log('endTime $endTime', name: logGetCalendarApi);

    String token = await SharedPrefsMethods.getStringFromPrefs(PREF_TOKEN_KEY);


    List<CalendarResponse> calendarResponseList;

    Map<String, String> queryParameters = {
      "startTime": "${formatDate(startTime)}",
      "endTime": "${formatDate(endTime)}",


    Uri uri = Uri.parse(url).replace(queryParameters: queryParameters);

    log('Uri: (logGetCalendarApi) $uri', name: logGetCalendarApi);

    return http.get(uri, headers: {
      HttpHeaders.contentTypeHeader: "application/json",
      HttpHeaders.authorizationHeader: "Bearer $token",
      'accept': 'text/plain'
    }).then((http.Response response) {

      int statusCode = response.statusCode;
      log('Status Code: $statusCode', name: logGetCalendarApi);
      log('RESPONSE BODY (get students and mandates): ${response.body}', name: logGetCalendarApi);

      // dynamic data = json.decode(DummyResponses.getMandatesForProvider);
      dynamic data = json.decode(response.body);

      if (statusCode < 200 || statusCode >= 400) {
        log('Error: ${response.body}', name: logGetCalendarApi);
            msg: data['Message'] ??
                'An internal error has occurred.',
            toastLength: Toast.LENGTH_LONG,
            timeInSecForIosWeb: 3);
        throw Exception(data['Message'] ?? 'An internal error has occurred.');

      calendarResponseList = data
              (json) => CalendarResponse.fromJson(json))

      log('Calendar result List Size: ${calendarResponseList.length}', name: logGetCalendarApi);

      return calendarResponseList;


I call this from another screen to trigger the http request again:


Thanks very much

>Solution :

You need to check one more condition for that is check for isRefreshing for your provider variable.

same as calendarResponse.isRefreshing

         data: (data) {
            print('DATA length: ${data.length}');
           if (calendarResponse.isRefreshing){
              return const CircularProgressIndicator();
            return ...;
          }, error: ((error, stackTrace) {
            return Text('Error: ${error.toString()}');
          }), loading: (() {
            return const Center(
              child: CircularProgressIndicator(),

Leave a Reply