Set a provide after Future returns results - flutter

I'm trying to modify data using a provider after a Future returns with data.
class FirstPart extends StatelessWidget {
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getAll(),
initialData: Text('Loading Bro'),
builder: (context, snapshot) {
if (snapshot.hasError)
return Text('error here bro');
else if (snapshot.hasData) {
final toDoListManager = Provider.of<ListManager>(context);
toDoListManager.list = snapshot.data;
return Text('loaded');
}
return Text('load');
},
);
}
}
Future<void> getAll() async {... API Request}
I get an error when I set the value of the provider. (I removed a lot of the error because it was too long for Stack Overflow.)
How can I modify a provider after a Future has results?
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building FutureBuilder<void>(dirty, dependencies:
flutter: [InheritedProvider<ListManager>], state: _FutureBuilderState<void>#fe02e):
flutter: type 'Text' is not a subtype of type 'List<ListItem>'
flutter:
flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially
flutter: more information in this error message to help you determine and fix the underlying cause.
flutter: In either case, please report this assertion by filing a bug on GitHub:
flutter: https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: User-created ancestor of the error-causing widget was:
flutter: FirstPart
package:crud_todo/home.dart:16
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 FirstPart.build.<anonymous closure>
package:crud_todo/home.dart:32
flutter: #1 _FutureBuilderState.build (package:flutter/src/widgets/async.dart)
setState() or markNeedsBuild() called during build.

There are some strange things going on there:
Your toDoListManager is a ListManager, toDoListManager.list returns a List and you are trying to assing a Text to thise list item since snapshot.data returns a Text Widget as initialData toDoListManager.list = snapshot.data;
Another strange thing is that your getAll returns a future of void when in my opinion should return a future of List

Related

Flutter Navigation 2.0 + Bloc

I am currently trying to learn Navigation 2.0 in conjunction with BLoC.
I've followed the raywenderlich's guide [1] successfully (it's a bit outdated) and i tried to move forward managing the state with BLoC (this guide uses Provider) and when i did it successfully, i tried to take a step further and i tried to follow JalalOkbi's guide [2] because of a more advanced abstraction level provided. The third link [3] is the github repo with the full (now failing) project.
But after 5 days of trying i stumbled in several errors and i can't figure this out: i am currently facing this error:
I/flutter (10212): looking for /
I/flutter (10212): found Splash("null", null, null)
I/flutter (10212): looking for /
I/flutter (10212): found Splash("null", null, null)
════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building Builder:
The settings getter of a page-based Route must return a Page object. Please set the settings to the Page in the Page.createRoute method.
'package:flutter/src/widgets/navigator.dart':
package:flutter/…/widgets/navigator.dart:1
Failed assertion: line 3361 pos 9: 'entry.route.settings == page'
════════ Exception caught by widgets library ═══════════════════════════════════
A GlobalKey was used multiple times inside one widget's child list.
The relevant error-causing widget was
MaterialApp
lib\main.dart:40
════════════════════════════════════════════════════════════════════════════════
[1] https://www.raywenderlich.com/19457817-flutter-navigator-2-0-and-deep-links
[2] https://medium.com/#JalalOkbi/flutter-navigator-2-0-with-bloc-the-ultimate-guide-6672b115adf
[3] https://github.com/msimoncini90/flutter_navigation_2.0
If your page object is defined like
class SplashPage extends Page {
#override
Route createRoute(BuildContext context) {
return MaterialPageRoute(
builder: (BuildContext context) => const SplashScreen(),
);
}
}
The issue is that there is a missing setting in the page definition, which is what the error is showing. The correct code looks like
class SplashPage extends Page {
#override
Route createRoute(BuildContext context) {
return MaterialPageRoute(
settings: this,
builder: (BuildContext context) => const SplashScreen(),
);
}
}
Notice that the settings: this parameter, which solves what the error is describing.

setState() or markNeedsBuild() called during build inside a StreamBuilder

I am using this StreamBuilder to get the current location:
StreamBuilder<UserLocation>(
stream: locationService.locationStream,
builder: (context, snapshot) {
if (snapshot.data != null) {
bool es_actual = ubicacionesProvider.ubicacionActualSeleccionada;
bool es_elegida = ubicacionesProvider.ubicacionElegidaSeleccionada;
if(es_actual){
latitudData = snapshot.data.latitude;
// ubicacionesProvider.setlatitudActual(latitudData);
longitudData = snapshot.data.longitude;
//ubicacionesProvider.setlongitudActual(longitudData);
Coordinates misCoordenadas =
new Coordinates(latitudData, longitudData);
// ubicacionesProvider.setubicacionActual(_miDireccionActual);
getAddress(misCoordenadas);
}
if(es_elegida){
_latitudElegida = ubicacionesProvider.latitudElegida;
_longitudElegida = ubicacionesProvider.longitudElegida;
_miDireccionActual = ubicacionesProvider.ubicacionElegida;
}
}
I want to update a provider called ubicacionesProvider with some changes:
ubicacionesProvider.setlatitudActual(latitudData)
ubicacionesProvider.setlongitudActual(longitudData)
ubicacionesProvider.setubicacionActual(_miDireccionActual)
But I am getting a warning using one or all of them, the app is not exiting but the warning is shown:
======== Exception caught by foundation library ====================================================
The following assertion was thrown while dispatching notifications for UbicacionesProvider:
setState() or markNeedsBuild() called during build.
This _InheritedProviderScope<UbicacionesProvider> widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: _InheritedProviderScope<UbicacionesProvider>
value: Instance of 'UbicacionesProvider'
listening to value
The widget which was currently being built when the offending call was made was: StreamBuilder<UserLocation>
dirty
dependencies: [MediaQuery]
state: _StreamBuilderBaseState<UserLocation, AsyncSnapshot<UserLocation>>#39568
When the exception was thrown, this was the stack:
#0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4292:11)
#1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4307:6)
#2 _InheritedProviderScopeElement.markNeedsNotifyDependents (package:provider/src/inherited_provider.dart:496:5)
#3 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:226:25)
#4 UbicacionesProvider.setlatitudActual (package:flutter_qplan/providers/ubicaciones_provider.dart:50:5)
...
The UbicacionesProvider sending notification was: Instance of 'UbicacionesProvider'
====================================================================================================
I would like to update the provider without getting that warning.
Usually this happens when you setState or notifyListeners before the build has finished building all the widgets. Maybe you can add your update logic like this :
WidgetsBinding.instance!.addPostFrameCallback((_) {
// Add Your Update Code here.
});

No Overlay widget found despite Scaffold and MaterialApp

I'm using Riverpod as global state manager on my application; in this case, I'm using it to handle the application's launch: if there is a profile persited on device, it will go directly to one screen based on the user's role, if there is no such profile, it will send us to the login screen.
Given a persisted user I am getting the next bug:
======== Exception caught by widgets library =======================================================
The following assertion was thrown building Tooltip("Open navigation menu", dirty, state: _TooltipState#4e2ac(ticker inactive)):
No Overlay widget found.
Tooltip widgets require an Overlay widget ancestor for correct operation.
The most common way to add an Overlay to an application is to include a MaterialApp or Navigator widget in the runApp() call.
The specific widget that failed to find an overlay was: Tooltip
"Open navigation menu"
The relevant error-causing widget was:
AppBar file:///home/luisalaguna/Projects/thesis_cancer/lib/core/presentation/widgets/header.dart:17:12
When the exception was thrown, this was the stack:
#0 Overlay.of.<anonymous closure> (package:flutter/src/widgets/overlay.dart:306:9)
#1 Overlay.of (package:flutter/src/widgets/overlay.dart:309:6)
#2 _TooltipState.build (package:flutter/src/material/tooltip.dart:457:20)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4612:27)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
Header is an AppBar widget; this bug would not be strange if all the widget wouldn't be wrapped by an Scaffold and a MaterialApp widgets:
The code on main file is this:
class CancerApp extends HookWidget {
#override
Widget build(BuildContext context) {
final _appRouter = AppRouter();
final bool darkTheme = useProvider(darkThemeProvider);
final launcherState = useProvider(launcherProvider);
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
return MaterialApp.router(
title: 'Thesis Cancer',
theme: darkTheme ? ThemeData.dark() : ThemeData.light(),
routerDelegate: _appRouter.delegate(),
routeInformationParser: _appRouter.defaultRouteParser(),
// home: SplashScreen()
builder: (context, router) => launcherState.when(
loading: () => SplashScreen(),
needsProfile: () => LoginPage(),
profileLoaded: () => MainScreen()),
);
}
}
About the launcher notifier, you can see it here.
After rafactoring this workflow I am getting this bug, i didn't get it when the profileLoaded state was returning the user(I was getting another issue).
What can be the problem?
Add applyElevationOverlayColor: true, on your Theme

issues with consumers and providers

Hello I am facing an issue with my flutter app using providers and consumer.
everything works fine how ever I have this issue in my debugger:
════════ Exception caught by foundation library ════════════════════════════════
The following assertion was thrown while dispatching notifications for CatergoryProvider:
setState() or markNeedsBuild() called during build.
This _InheritedProviderScope<CatergoryProvider> widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: _InheritedProviderScope<CatergoryProvider>
value: Instance of 'CatergoryProvider'
listening to value
The widget which was currently being built when the offending call was made was: Consumer<CatergoryProvider>
dirty
dependencies: [_InheritedProviderScope<CatergoryProvider>]
When the exception was thrown, this was the stack
#0 Element.markNeedsBuild.<anonymous closure>
package:flutter/…/widgets/framework.dart:4138
#1 Element.markNeedsBuild
package:flutter/…/widgets/framework.dart:4153
#2 _InheritedProviderScopeElement.markNeedsNotifyDependents
package:provider/src/inherited_provider.dart:496
#3 ChangeNotifier.notifyListeners
package:flutter/…/foundation/change_notifier.dart:243
#4 CatergoryProvider.setLoading
package:quizz_app/provider/catergoryProvider.dart:43
...
The CatergoryProvider sending notification was: Instance of 'CatergoryProvider'
here is the consumer in question:
Consumer<CatergoryProvider>(
builder: (context, catergory, child) {
if (!catergory.isLoading() && !catergory.isList()) {
catergory.fetchCatergory();
}
catergories = catergory.getList();
return catergory.isLoading()
? ModalProgressHUD(
opacity: 0,
inAsyncCall: catergory.isLoading(),
child: Container())
: catergoryPage(catergories, context);
},
),
and this is where the stack trace leads me to:
void setLoading(value) {
loading = value;
notifyListeners();
}
It looks like you are probably calling setLoading(value) inside of a build method.. This would try to trigger a rebuild of the widget when notifyListeners() is invoked during the build of the widget.
Consider using a FutureBuilder or a StreamBuilder to change state depending when waiting on an async action.

Failed assertion: line 556 pos 15: 'scrollOffsetCorrection != 0.0': is not true

After Upgrading the flutter to the latest version. I'm facing this issue, I've the same code for another application having earlier version of flutter and it is working fine.
With the new ListView add two or more children.
Scroll down the list to the point where the first child is entirely off the screen.
Scroll all the way back up to the initial position. The ListView shows nothing on screen (just white empty space).
Attaching minimal reproducible code:
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MYYApp(),
);
}
}
class MYYApp extends StatefulWidget {
#override
_MYYAppState createState() => _MYYAppState();
}
class _MYYAppState extends State<MYYApp> {
final list = [
'BMW',
'Fiat',
'Toyota',
'Fiat',
'Testa',
'Fiat',
'Ford',
'Fiat',
'BMW',
'Fiat',
'Toyota',
'Fiat',
'Testa',
'Fiat',
'Ford',
'Fiat'
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ListView.builder(
itemCount: list.length,
itemBuilder: (context,index){
return list[index]=='Fiat'? //list[index] == 'Fiat' (this condition check is responsible for the issue and earlier it was not an issue)
Container(
height: 300,
child: Center(child: Text(list[index])),
):Container();
})
),
);
}
}
Here's the error:
════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The method '-' was called on null.
Receiver: null
Tried calling: -(223.60756587000844)
The relevant error-causing widget was:
ListView file:///C:/Users/prave/AndroidStudioProjects/for_stackoverflow/lib/main.dart:49:25
════════════════════════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during performLayout():
'package:flutter/src/rendering/sliver.dart': Failed assertion: line 556 pos 15: 'scrollOffsetCorrection != 0.0': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
The relevant error-causing widget was:
ListView file:///C:/Users/prave/AndroidStudioProjects/for_stackoverflow/lib/main.dart:49:25
When the exception was thrown, this was the stack:
#2 new SliverGeometry (package:flutter/src/rendering/sliver.dart:556:15)
#3 RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:180:20)
#4 RenderObject.layout (package:flutter/src/rendering/object.dart:1769:7)
#5 RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:137:11)
#6 RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:377:11)
This is only a part of error,it produces nearly 10 same kind of errors.
The error vanishes as soon as you give your alternative non-Fiat container a height of non-zero.
I don't know exactly why that is or if it's on purpose, but the list seems to have problems with zero-height elements.
I suggest you actually use a filtering mechanism on your data and not work around that part by making it zero height in the view as an afterthought.
I have same issue after upgrade flutter framework.
For me the description of problem is:
The issue: when you use a Container or Widget without child and or without height property inside ListVIew
The solution: Just give height property to Widget that inside ListView.
This is my code, that's worked for me
.......
body: ListView(
shrinkWrap: true,
children: <Widget>[
Auth ? Container(height: 1): signUpWidget() , // Add height property to Container
.....
......
]
)
Min height should be greater than 0. You can put it 0.1. It may be a bug but it works.
ListView(
shrinkWrap: true,
children: <Widget>[
SizedBox(height: 0.1,);
]