I'm trying to make a Flutter app, using Riverpod for state management and FlutterMaps. I have set up notifiers for pages, and am also using a (State)NotifierProvider for the map page. I am building a search function, which goes to a search page which displays a list with search results. When one of these results (in a list) is clicked, I update the notifier of the map page. However, here comes the tricky part: I want to update the map according to the LatLng of the search result (center it).
My implementation of the Notifier contains:
late MapController? _mapController;
My map page is loaded in and gets the mapController from the Notifier: mapController: notifier.getMapController()
Using Riverpod state management, this all should work, however I get the following Error:
LateError (LateInitializationError: Field '_state#1225051772' has already been initialized.)
This Error is within the MapController itself (which is part of the FlutterMaps package), so I do not want to touch that. Does anyone have any idea how to tackle this?
lateerror is caused by nulling a variable that will fill before the application starts.
late MapController? _mapController;
this definition is wrong. Here, you are saying that this value will fill in soon. You also say that this value can be null.
late MapController _mapController;
if you do so this variable should not be null at runtime. if it is null you will get a lateerror error.
MapController? _mapController;
if you do it this way. This means that the value can be null. You should check when using.
like this
void sameFunction(){
if(_mapController!=null){
... your code
// here make sure this variable is not null. For this reason ! i put this
MapController anotherController=_mapController!;
}
}
or
void sameFunction(){
// Your code will not throw an error if this variable is null. Because specify that
//it can be null
mapController?.moveTo(...)
}
for more detailed information
you should remove the late keyword or you should intialise it in the initState
method.
Related
I'm getting The argument type BuildContext Function() can't be assigned to the parameter type BuildContext.
You can't send context to a function when it isn't even defined in the initstate function. Here you are trying to use provider outside the Build Function which is a no no. What you can do as an alternative is to wrap the function with a Future to give it a valid context :
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
myString = Provider.of<AppData>(context, listen: false).testString;
});
I solved this by removing the flutter whole folder where it is saved and than remove the Environmental Values and remove path and add new download new Flutter SDK and than again update the path in Environmental Values
I am using riverpod package for state management in a Flutter app and I have a search sort provider as follows:
final searchSortStateProvider = StateProvider<SearchSort?>((ref) { return SearchSort.relevance; });
But when the user searches again I want to reset the state of the search sort provider using the following code:
ref.read(searchSortStateProvider.notifier).state = SearchSort.relevance;
It throws:
"setState() or markNeedsBuild called during build"
Exception because I call it inside the init() method of the parent widget.
My question is how can I change the state of the provider without needing to rebuild the sort widget?
maybe you try ref.refresh or ref.invalidate/ref.invalidateSelf()?
I need a reference to the current OverlayState from a service where I don't have access to the current context. I've tried to use the "trick" of getting my BuildContext from a navigator key, but while this works for dialogs and navigation, does not seem to be valid for this use case. I've tried following approaches:
Overlay.of(navigatorKey.currentContext, rootOverlay: false);
Overlay.of(navigatorKey.currentState!.context, rootOverlay: false);
Overlay.of(navigatorKey.currentState!.overlay!.context, rootOverlay: false);
And all of them return null. Same piece of code, called from a widget (Overlay.of(context)) returns a valid OverlayState. Is there any way of achieving this?
I made an API call and returned a list data and few other values. I made the API call in one screen in the initState now and I need the list and other data in other 2 screens without Navigation. Is this possible. I am also using provider package. I am new to flutter so any help would be highly appreciated. Thank You.
List<YourClassName> list = [];
class ExampleProvider with ChangeNotifier {
getList(){
list = await yourApiCall();
notifyListeners();
}
}
Your provider class should look like this. When your api returns, you need to use that equation. With that way you can call it everywhere your list with
Provider.of<ExampleProvider>(context).list;
I have a list that I am trying to delete a specific item from.
I first tried:
Provider.of<WeekList>(context, listen: false).listOfWeeks.remove(widget.index);
That did not work.
After thinking about it I realized that the Provider is retrieving the list but not actually updating the provider.
So then I decided to use the provider to save retrieve the list and save it to a new list:
List<Week> myList =Provider.of<WeekList>(context, listen: false).listOfWeeks;
I then tried to delete an item at the current position:
myList.remove(widget.index);
I expected the myList to be shortened by one after that last line of code. But I put a print before and after it and they both still say the length is 6...
not sure why its not removign anything from myList. If it worked it should shorten it by one and I planned on then trying to update the provider.... But maybe I am not goign about this correctly.
in your last approach you are changing a "copy" of your list, what you need to do to achieve your goal is to make function inside your state that updates your list and notifies the listeners,
this function to be put inside your ChangeNotifier class:
void updateList(int index)
{
listOfWeeks.removeAt(widget.index);
notifyListeners();
}
and you can call it like:
Provider.of<WeekList>(context, listen: false).updateList(index);
If you're removing by index, you need to use removeAt.