Skip to content

Snappy1

  • Home
  • Android
  • What
  • How
  • Is
  • Can
  • Does
  • Do
  • Why
  • Are
  • Who
  • Toggle search form

[FIXED] android – Why is futureBuilder stuck on the progress loader sometimes?

Posted on November 11, 2022 By

Solution 1 :

Execution is not advancing beyond this line:

  var temp = await compute(parseEvents, response.data);

Probably parseEvents is throwing something.

Notice how you never use try/catch. You have to write code to catch exceptions. parseEvents is probably throwing an exception (malformed json?, empty json->null?) and since you are not catching it you have no idea what is happening.

I would first try to get rid of the compute and just call parseEvents to see if the exception is silently ignored because of compute. Then I would place try/catch inside the parseEvents function and gradually have all execution paths to have try/catch in them, including async functions and await calls.

Problem :

I have an issue with futureBuilders in my whole flutter app. In each screen there can be 3 or 4 sections, each one loads data from a specific API endpoint. The problem is that sometimes, whole screen loads fine, and sometimes a section or two are stuck with the progress bar!.. I debugged and searched a lot and can’t find the real cause.
This is making me hate flutter :/

enter image description here

For example, here is the Home Page Code:

import 'package:carousel_pro/carousel_pro.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:soul_space/PODOs/categories.dart';
import 'package:soul_space/PODOs/event.dart';
import 'package:soul_space/PODOs/image.dart';
import 'package:soul_space/PODOs/space.dart';
import 'package:soul_space/custom_widgets/category-card.dart';
import 'package:soul_space/custom_widgets/error-card.dart';
import 'package:soul_space/custom_widgets/no-data.dart';
import 'package:soul_space/custom_widgets/search-widget.dart';
import 'package:soul_space/services/categories-service.dart';
import 'package:soul_space/services/events-service.dart';
import 'package:flutter/foundation.dart';
import 'package:soul_space/services/spaces-service.dart';
import '../custom_widgets/home-row.dart';
import 'package:async/async.dart';

class HomeTab extends StatefulWidget {
  HomeTab({Key key, this.title, this.mainScaffoldKey}) : super(key: key);

  final GlobalKey<ScaffoldState> mainScaffoldKey;
  final String title;

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

class HomeTabState extends State<HomeTab> with AutomaticKeepAliveClientMixin {
  Future _homeImagesFuture;
  final AsyncMemoizer _categoriesMemoizer = AsyncMemoizer();
  Future _categoriesFuture;
  final AsyncMemoizer _eventsMemoizer = AsyncMemoizer();
  Future _eventsFuture;
  final AsyncMemoizer _spacesMemoizer = AsyncMemoizer();
  Future _spacesFuture;

  var isLoading = false;

  final List<String> rowsTitles = ['New Events', 'Featured Spaces'];
  List colors = [
    Colors.red[500],
    Colors.teal[300],
    Colors.yellow[500],
    Colors.orange[300],
    Colors.red[400],
    Colors.blue
  ];
  Random random = new Random();

  @override
  void initState() {
    super.initState();
    _categoriesFuture = fetchCategories();
    _eventsFuture = fetchEvents();
    _spacesFuture = fetchSpaces();
    _homeImagesFuture = getHomeImages();
  }

  fetchCategories() async {
    return this._categoriesMemoizer.runOnce(() async {
      return await getCategories();
    });
  }

  fetchEvents() async {
    return this._eventsMemoizer.runOnce(() async {
      return await fetchAllEvents('approved');
    });
  }

  fetchSpaces() async {
    return this._spacesMemoizer.runOnce(() async {
      return await fetchAllSpaces('approved');
    });
  }

  String _homeSliderImages;
  Future<List<String>> getHomeImages() async {
    List<LoadedAsset> assets = await fetchSliderImages();
    List<String> temp = [];
    for (var i = 0; i < assets.length; i++) {
      temp.add(assets[i].link);
    }

    return temp;
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    debugPrint('REBUILD:' + DateTime.now().toString());
    return Scaffold(
        body: SingleChildScrollView(
      child: Column(
        children: <Widget>[
          Stack(
            children: [

              SearchBar(scaffoldKey: widget.mainScaffoldKey),
            ],
          ),
          Padding(
            padding: const EdgeInsets.only(left: 10.0, right: 10.0),
            child: FutureBuilder(
                future: _eventsFuture,
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    debugPrint('***************************DONE1');
                    if (snapshot.hasError) {
                      debugPrint(snapshot.error.toString());
                      return ErrorCard(
                        isSmall: true,
                      );
                    } else if (snapshot.hasData) {
                      final List<Event> events = snapshot.data;
                      return HomeRow(
                          title: rowsTitles[0],
                          events: events,
                          route: '/allEvents');
                    } else {
                      return NoDataCard(
                        isSmall: true,
                      );
                    }
                  } else {
                    debugPrint('***************************LOADER1');
                    return Container(
                        margin: EdgeInsets.symmetric(vertical: 0.0),
                        height: 250.0,
                        child: Center(child: RefreshProgressIndicator()));
                  }
                }),
          ),
          Padding(
            padding: const EdgeInsets.only(left: 10.0, right: 10.0),
            child: FutureBuilder(
                future: _spacesFuture,
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    debugPrint('***************************DONE2');

                    if (snapshot.hasError) {
                      debugPrint(snapshot.error.toString());
                      return ErrorCard(
                        isSmall: true,
                      );
                    } else if (snapshot.hasData) {
                      final List<Space> spaces = snapshot.data;
                      return HomeRow(
                          title: rowsTitles[1],
                          spaces: spaces,
                          route: '/allSpaces');
                    } else {
                      return NoDataCard(
                        isSmall: true,
                      );
                    }
                  } else {
                    debugPrint('***************************LOADER2');
                    return Container(
                        margin: EdgeInsets.symmetric(vertical: 0.0),
                        height: 250.0,
                        child: Center(child: RefreshProgressIndicator()));
                  }
                }),
          )
        ],
      ),
    ));
  }

  @override
  bool get wantKeepAlive => true;
}

And this is a sample of a service function that parses json data from API:

Future<List<Event>> fetchAllEvents(String approval, {int id = -1}) async {
  var url = globals.apiUrl +
      '/events/' +
      (id != -1 ? id.toString() + '/' : '') +
      _getQueryParams(false, approval);
  dio.Response<String> response = await get(url);
  debugPrint('***************************GET SUCCEES1');
  var temp = await compute(parseEvents, response.data);
  debugPrint('***************************PARSE SUCCEES1');
  return temp;
}
.
.
List<Event> parseEvents(String responseBody) {
  final parsedJson = json.decode(responseBody);
  var list = parsedJson['data'] as List;
  if (list != null) {
    List<Event> eventsList = list.map((i) => Event.fromJson(i)).toList();
    return eventsList;
  } else {
    return [];
  }
}

Furthermore, here are examples of good and bad build logs, hope they help conclude the cause:

  • ‘LOADER’ is printed when progress bar is displayed
  • ‘GET SUCCESS’ is printed when get returns
  • ‘PARSE SUCCESS’ is printed when compute function succeeds in parsing json
  • ‘DONE’ is printed when the widget is loaded correctly
READ  [FIXED] Webview not functioning properly in android studio
Powered by Inline Related Posts

enter image description here

Any solutions?

EDIT

I removed “compute” function as suggested in the accepted answer and it fixed it, but not sure why it failed sometimes without exceptions

Comments

Comment posted by Kahou

There is no

Comment posted by Abeer Sul

@Kahou, yes but what is the explanation?

Comment posted by Abeer Sul

good suggestion. I tried adding try/catch and keeping compute => still same issue without any execptions. Then I tried removing compute, tested it many times and

Comment posted by Gazihan Alankus

Did you place try/catch inside

Android Tags:android, dart, flutter, ios, json

Post navigation

Previous Post: [FIXED] java – The Android LoaderManager is deprecated. Now what?
Next Post: [FIXED] android – Is WorkManager the right solution for me?

Related Posts

[FIXED] java – How to extract data from HashMap in Retrofit2? Android
[FIXED] android – FloatingActionBar has a exception about layout_anchor Android
[FIXED] kotlin – Custom FCM notifications stopped showing up on Android Android
[FIXED] kotlin – Search encrypted text with ‘like’ in Room Database Android
[FIXED] How to build NavGraph programmatically with Java in Android Android
[FIXED] build.gradle – Android Gradle project sync failed due to unresolved dependency Android

Archives

  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022

Categories

  • ¿Cómo
  • ¿Cuál
  • ¿Cuándo
  • ¿Cuántas
  • ¿Cuánto
  • ¿Qué
  • Android
  • Are
  • At
  • C'est
  • Can
  • Comment
  • Did
  • Do
  • Does
  • Est-ce
  • Est-il
  • For
  • Has
  • Hat
  • How
  • In
  • Is
  • Ist
  • Kann
  • Où
  • Pourquoi
  • Quand
  • Quel
  • Quelle
  • Quelles
  • Quels
  • Qui
  • Should
  • Sind
  • Sollte
  • Uncategorized
  • Wann
  • Warum
  • Was
  • Welche
  • Welchen
  • Welcher
  • Welches
  • Were
  • What
  • What's
  • When
  • Where
  • Which
  • Who
  • Who's
  • Why
  • Wie
  • Will
  • Wird
  • Wo
  • Woher
  • you can create a selvedge edge: You can make the edges of garter stitch more smooth by slipping the first stitch of every row.2022-02-04
  • you really only need to know two patterns: garter stitch

Recent Posts

  • What is a good substitute for condensed milk?
  • ¿Como el cuerpo te avisa cuando te va a dar un infarto?
  • What is the luxury brand of Jaguar?
  • Who is Big poppa baseball player?
  • What material are foam runners?

Recent Comments

No comments to show.

Copyright © 2023 Snappy1.

Powered by PressBook Grid Dark theme