I am new to flutter and trying to develop a login screen, I am facing issue while implementing ChangeNotifierProvider. I tried using both MultiProvider and ChangeNotifierProvider widgets and both produces same exception.
Exception
The following _TypeError was thrown building LandingPage(dirty, dependencies: [_InheritedProviderScope<AuthState?>]):
type '_Type' is not a subtype of type 'String' in type cast
The relevant error-causing widget was:
LandingPage LandingPage:file:///Users/hatimtai/Flutter%20Projects/myapp/lib/main.dart:32:21
When the exception was thrown, this was the stack:
#0 new AuthState (package:myapp/states/auth_state.dart:4:27)
#1 MyApp.build.<anonymous closure> (package:myapp/main.dart:23:53)
#2 _CreateInheritedProviderState.value (package:provider/src/inherited_provider.dart:736:36)
#3 _InheritedProviderScopeElement.value (package:provider/src/inherited_provider.dart:590:33)
#4 Provider.of (package:provider/src/provider.dart:303:37)
#5 LandingPage.build (package:myapp/main.dart:43:32)
#6 StatelessElement.build (package:flutter/src/widgets/framework.dart:5541:49)
#7 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5471:15)
#8 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#9 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5453:5)
#10 ComponentElement.mount (package:flutter/src/widgets/framework.dart:5447:5)
... Normal element mounting (220 frames)
#230 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#231 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6871:36)
#232 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6883:32)
... Normal element mounting (453 frames)
#685 _InheritedProviderScopeElement.mount (package:provider/src/inherited_provider.dart:411:11)
... Normal element mounting (7 frames)
#692 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
... Normal element mounting (7 frames)
#699 _NestedHookElement.mount (package:nested/nested.dart:187:11)
... Normal element mounting (7 frames)
#706 _InheritedProviderScopeElement.mount (package:provider/src/inherited_provider.dart:411:11)
... Normal element mounting (7 frames)
#713 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
... Normal element mounting (7 frames)
#720 _NestedHookElement.mount (package:nested/nested.dart:187:11)
... Normal element mounting (7 frames)
#727 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
... Normal element mounting (33 frames)
#760 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#761 Element.updateChild (package:flutter/src/widgets/framework.dart:3837:18)
#762 _RawViewElement._updateChild (package:flutter/src/widgets/view.dart:289:16)
#763 _RawViewElement.mount (package:flutter/src/widgets/view.dart:312:5)
... Normal element mounting (7 frames)
#770 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#771 Element.updateChild (package:flutter/src/widgets/framework.dart:3837:18)
#772 RootElement._rebuild (package:flutter/src/widgets/binding.dart:1334:16)
#773 RootElement.mount (package:flutter/src/widgets/binding.dart:1303:5)
#774 RootWidget.attach.<anonymous closure> (package:flutter/src/widgets/binding.dart:1256:18)
#775 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2835:19)
#776 RootWidget.attach (package:flutter/src/widgets/binding.dart:1255:13)
#777 WidgetsBinding.attachToBuildOwner (package:flutter/src/widgets/binding.dart:1083:27)
#778 WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:1065:5)
#779 WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:1051:7)
#783 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
(elided 3 frames from class _Timer and dart:async-patch)
I am following google codelabs "Your first Flutter app", have gone through it multiple times and am not able to find what is going wrong and hence need your help.
main.dart
import 'package:flutter/material.dart';
import 'package:myapp/states/auth_state.dart';
import 'package:myapp/states/myapp_state.dart';
import 'package:provider/provider.dart';
import 'package:myapp/pages/login_page.dart';
import 'package:myapp/pages/home_page.dart';
import 'package:myapp/utils/login_utils.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => MyAppState()),
ChangeNotifierProvider(create: (context) => AuthState()),
],
child: MaterialApp(
title: 'My App',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color.fromARGB(255, 31, 136, 105)),
useMaterial3: true,
),
home: const LandingPage(),
),
);
}
}
class LandingPage extends StatelessWidget {
const LandingPage({super.key});
@override
Widget build(BuildContext context) {
final authState = Provider.of<AuthState>(context);
Widget page;
bool isUserLoggedIn = false;
isLoggedIn(authState.refreshToken, authState.accessToken)
.then((value) => isUserLoggedIn = value);
switch (isUserLoggedIn) {
case true:
page = const HomePage();
break;
default:
page = const LoginPage();
}
return page;
}
}
states/auth_state.dart
import 'package:flutter/material.dart';
class AuthState extends ChangeNotifier {
var refreshToken = Null as String;
var accessToken = Null as String;
void setCredentials(String refresh, String access) {
refreshToken = refresh;
accessToken = access;
notifyListeners();
}
}
states/myapp_state.dart
import 'package:flutter/material.dart';
class MyAppState extends ChangeNotifier {}
var refreshToken = Null as String;
is the problem. Null
is a type. If you want to set the value to null, use null
(small 'n' letter). And you can't cast a null to String
. Type-annotate the variable with String?
instead.
String? refreshToken; // No need "= null", nullable variable is null by default
You might want to try the Null safety codelab.
See also: