ChangeNotifier isn't recognized by provider package - flutter

so I have this simple code:
import 'package:provider/provider.dart';
class DataModel with ChangeNotifier{
bool _isLoading = true;
set isLoading(bool value){
_isLoading = value;
notifyListeners();
}
get isLoading => _isLoading;
}
ChangeNotifier and notifyListeners() aren't recognized.
My dependencies:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
provider: ^4.3.3
I'm very confused as to why is it happening, this is the exact setup in the installation page (and it worked in other projects).
This project is also connected to a git lab project, I don't know if it is related.
btw, it's not like that with other keywords that are in the provider package - it perfectly recognizes ChangeNotifierProvider i.e

You are importing an incorrect package, the correct one is package:flutter/foundation.dart or alternatively package:flutter/material.dart, try with:
import 'package:flutter/material.dart';
class DataModel with ChangeNotifier{
bool _isLoading = true;
set isLoading(bool value){
_isLoading = value;
notifyListeners();
}
get isLoading => _isLoading;
}
package:provider/provider.dart is used in the files where the calls to the provider are made, not where it is defined.
See the example from the docs: https://github.com/flutter/samples/blob/master/provider_shopper/lib/models/cart.dart
A hint, in VS Code if you right click on ChangeNotifier and select Go to Definition, the definition can be traced to the foundation package.

Related

ReactionDisposer is not recognizing change in enum ( mobx )

After the update of flutter_mobx: ^2.0.6+1 and mobx_codegen: ^2.0.7 the ReactionDisposer is not recognizing changes in enum
late ReactionDisposer _refreshDisposer;
Completer<dynamic> refreshCompleter = new Completer();
#override
void initState() {
super.initState();
_refreshDisposer = reaction((_) => _vendorStore.serviceState, (_) {
if (_ != LoadingEnum.loading) {
refreshCompleter.complete();
refreshCompleter = Completer();
}
});
}
Observer is working fine but ReactionDisposer is not working according to change
flutter :3.0.5
Dart 2.17.6
The new flutter_mobx: ^2.0.6+1 and mobx_codegen: ^2.0.7 has no effect on the below import
import 'package:mobx/mobx.dart';
so to work the ReactionDisposer add this plugin mobx: ^2.0.7+5 in you'r dependencies else it won't recognize the change

How to mock url_launcher package for flutter test?

I used url_launcher: ^6.1.0 in my flutter project.
I start to write tests for my widgets, but the part of widgets that used the url_launcher method to launch an URL, not worked properly when running the test.
One of the methods that I used inside my Widget is like below method:
Future<void> _onTapLink(String? href) async {
if (href == null) return;
// canLaunchUrl method never return anything when we are calling this function inside flutter test
if (await canLaunchUrl(Uri.parse(href))) {
await launchUrl(Uri.parse(href));
} else {
print('cannot launch url: $href');
}
}
canLaunchUrl method never returns anything when we are calling this function inside the flutter test.
I'm looking for a way to mock the url_launcher package for using inside
flutter tests.
To mock url_launcher you may:
Add plugin_platform_interface and url_launcher_platform_interface packages to dev_dependencies section in the pubspec.yaml file.
Implement the mock class. For example, with mocktail the implementation would be:
import 'package:mocktail/mocktail.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';
class MockUrlLauncher extends Mock
with MockPlatformInterfaceMixin
implements UrlLauncherPlatform {}
Notice that here MockPlatformInterfaceMixin mixin is used.
Configure the mock as usual. With mocktail that might be:
MockUrlLauncher setupMockUrlLauncher() {
final mock = MockUrlLauncher();
registerFallbackValue(const LaunchOptions());
when(() => mock.launchUrl(any(), any())).thenAnswer((_) async => true);
return mock;
}
Tell url_launcher to use mocked version by setting it in UrlLauncherPlatform.instance:
final mock = setupMockUrlLauncher();
UrlLauncherPlatform.instance = mock;
This is an article that explicitly explains how to mock or fake the launchUrl function. Here is an example of how to mock it with mocktail. It also uses the ioc_container package to handle substitution with dependency injection.
import 'package:fafsdfsdf/main.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter/material.dart';
class LaunchMock extends Mock {
Future<bool> call(
Uri url, {
LaunchMode? mode,
WebViewConfiguration? webViewConfiguration,
String? webOnlyWindowName,
});
}
void main() {
testWidgets('Test Url Launch', (tester) async {
//These allow default values
registerFallbackValue(LaunchMode.platformDefault);
registerFallbackValue(const WebViewConfiguration());
//Create the mock
final mock = LaunchMock();
when(() => mock(
flutterDevUri,
mode: any(named: 'mode'),
webViewConfiguration: any(named: 'webViewConfiguration'),
webOnlyWindowName: any(named: 'webOnlyWindowName'),
)).thenAnswer((_) async => true);
final builder = compose()
//Replace the launch function with a mock
..addSingletonService<LaunchUrl>(mock);
await tester.pumpWidget(
builder.toContainer()<MyApp>(),
);
//Tap the icon
await tester.tap(
find.byIcon(Icons.favorite),
);
await tester.pumpAndSettle();
verify(() => mock(flutterDevUri)).called(1);
});
}

Flutter: Non-nullable instance field 'currentLocation' must be initialised

I'm getting an error with the new flutter changes on null safety. Am not sure whether I am supposed to add final/late/! in this code.
I have a code to connect to Google Maps and now I want to be able to store the data collected.
Right now I facing an error at the Application Bloc: Non-nullable field 'currentLocation' must be initialized.
import 'package:flutter/material.dart';
import 'package:hawkepedia/services/geolocator_Services.dart';
import 'package:geolocator/geolocator.dart';
class ApplicationBloc with ChangeNotifier {
final geoLocatorService = GeolocatorService();
//Variables
Position currentLocation;
//fire function when the app starts
ApplicationBloc(){
setCurrentLocation();
}
//gets current location
setCurrentLocation() async {
currentLocation = await geoLocatorService.getCurrentLocation();
notifyListeners();
}
}
As it is state in the error, the field causing the issue is currentLocation.
You can:
set it as late meaning you will initilize it during initState for example.
set it a nullable, not sure it is possible in this case, Position? currentLocation. (But it is for primary types)
Initialize it with a neutral value that you know is not initialized yet
Edit:
import 'package:flutter/material.dart';
import 'package:hawkepedia/services/geolocator_Services.dart';
import 'package:geolocator/geolocator.dart';
class ApplicationBloc with ChangeNotifier {
final geoLocatorService = GeolocatorService();
//Variables
late Position currentLocation;
//fire function when the app starts
ApplicationBloc(){
setCurrentLocation();
}
//gets current location
setCurrentLocation() async {
currentLocation = await geoLocatorService.getCurrentLocation();
notifyListeners();
}
}

ChangeNotifier can't no longer be used in Riverpod?

I am a beginner in Flutter, and I am trying to use Riverpod. here is the sample code
import "package:flutter_riverpod/flutter_riverpod.dart";
class CounterNotifier extends ChangeNotifier {
int _value = 0;
int get value => _value;
void incrementValue() {
_value++;
notifyListeners();
}
}
but I have error, I can't find ChangeNotifier and notifyListeners() like this
in pubspec.yaml file, I am using flutter_riverpod: ^0.14.0+3
am I misising something?
ChangeNotifier is a Flutter class, not a Riverpod one; when working with it, you have to ensure you have imported it.
It gets bundled in with common imports such as package:flutter/material.dart, and as Reign mentioned in his comment, can be directly imported via package:flutter/src/foundation/change_notifier.dart.

Flutter GetIt Plugin - No type xxx is registered inside GetIt

I set everything up as shown in the example project:
import 'package:get_it/get_it.dart';
import 'package:places/services/authService.dart';
final locator = GetIt.instance;
void setupLocator() {
locator.registerSingleton<AuthService>(AuthService());
print("registered");
}
with the call in the main file
void main() {
setupLocator();
runApp(MyApp());
}
I have some Check where the locator also correctly return my AuthService
class AuthGuardView extends StatefulWidget {
AuthGuardView({Key key}) : super(key: key);
#override
_AuthGuardViewState createState() => _AuthGuardViewState();
}
class _AuthGuardViewState extends State<AuthGuardView> {
#override
Widget build(BuildContext context) {
return ViewModelProvider<AuthGuardViewModel>.withConsumer(
viewModel: AuthGuardViewModel(),
onModelReady: (model) => model.initialise(),
builder: (context, model, child) => model.isLoggedIn
? Container(
color: Colors.white,
child: Text("Logged In"),
)
: SignUpView(),
);
}
}
class AuthGuardViewModel extends ChangeNotifier {
AuthService _authService = locator<AuthService>();
bool isLoggedIn = false;
void initialise() async {
isLoggedIn = await _authService.isLoggedIn();
notifyListeners();
}
}
If I do the exact same thing inside the ViewModel for the SignUpView I get the following error
flutter: The following assertion was thrown building SignUpView(dirty, state: _SignUpViewState#01129):
flutter: No type AuthService is registered inside GetIt.
flutter: Did you forget to pass an instance name?
flutter: (Did you accidentally do GetIt sl=GetIt.instance(); instead of GetIt sl=GetIt.instance;did you
flutter: forget to register it?)
flutter: 'package:get_it/get_it_impl.dart':
flutter: Failed assertion: line 248 pos 14: 'instanceFactory != null'
In the ViewModel for the AuthGuard I do successfully retrieve the auth service. I also commented out the locator code (because I thought it might be the async call or something like that) but the same error persists.
I am using get_it: ^4.0.1 but the error persists when downgrading to 3.x.x
Here the SignUpViewModel
class SignUpViewModel extends ChangeNotifier {
SignUpViewModel(){
if(locator.isRegistered<AuthService>()) {
AuthService _authService = locator<AuthService>();
}
}
var textInputFormatter = [
WhitelistingTextInputFormatter(RegExp(r'\d')),
PhoneNumberTextInputFormatter()
];
var textEditingController;
var context;
}
This happens when the class to be registered as singleton has async methods. To fix this you need to await the singleton to be fully generated before runApp() is ran.
void main() async {
/* WidgetsFlutterBinding.ensureInitialized() is required in Flutter v1.9.4+
* before using any plugins if the code is executed before runApp.
*/
WidgetsFlutterBinding.ensureInitialized();
// Configure injecction
await setupLocator();
runApp(MyApp());
}
Adding this answer, as I think it might help others!
I have faced the same issue earlier. For me, it was due to an ordering issue. So make sure to initiate/declare the dependency objects first and then instantiate/declare the dependent one.
Using the latest get_it version in pubspec.yaml ( now it is get_it: ^4.0.2 ) resolve the issue for me.
I have also faced this issue. Nothing made sense. Then I remembered, that I recently did case sensitive renaming.
I changed i.e. Services/Database/Database.dart to services/database/database.dart, but in one file, I used import with the lowercased version, while in the other, it still was the uppercased version. Making the case consistent throughout the project was the fix I needed.