I have a list using flutter provider.But firestore data works.The problem is that provider. Error is the getter length was called on null. I searched this question in stackoverflow, i tried every answer but they did not solve my problem. Here is included code in bellow :
GameServices Class
class GamesServices {
String collection = 'games';
Firestore _firestore = Firestore.instance;
Future<List<GamesModel>> getGames() async {
_firestore.collection(collection).getDocuments().then((result) {
List<GamesModel> gameList = <GamesModel>[];
for (DocumentSnapshot game in result.documents) {
gameList.add(GamesModel.fromSnapshot(game));
}
return gameList;
});
}
Provider Class
class BoshphelmProvider with ChangeNotifier {
GamesServices _gamesServices = GamesServices();
List<GamesModel> _games = <GamesModel>[];
List<GamesModel> get games => _games;
BoshphelmProvider.initialize() {
loadGames();
}
loadGames() async {
_games = await _gamesServices.getGames();
notifyListeners();
}
}
Main Class
void main() {
setupLocator();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(
value: BoshphelmProvider.initialize(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Boshphelm',
theme: ThemeData(
primaryColor: Constant.primaryColor,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
),
);
}
}
you are missing the code part where you try to get the length of something and it throws that error
without that i would guess you are trying to access games list before it finishes initializing, as you are not waiting for it
try this
void main() async {
WidgetsFlutterBinding.ensureInitialized();
BoshphelmProvider _provider = BoshphelmProvider();
await _provider.initialize()
setupLocator();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(
value: _provider,
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Boshphelm',
theme: ThemeData(
primaryColor: Constant.primaryColor,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
),
);
}
}
Related
I want to get user's data from server and set State, when app is loading. so I use flutter_native_splash package and provider for app. the provider doesn't work.
stock_notifier.dart
class StockCodeNotifier extends ChangeNotifier {
final List<StockModel> _stocks = [];
String _stockCode = '';
String get stockCode => _stockCode;
void getStocks() {
List<StockModel> data = allStocks;
_stocks.clear();
_stocks.addAll(data);
_stockCode = _stocks[0].code;
notifyListeners();
}
main.dart
void main() {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
runApp(MyApp());
Provider.of<StockCodeNotifier>(context).getStocks();
FlutterNativeSplash.remove();
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider<StockCodeNotifier>(
create: (_)=>StockCodeNotifier(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Home(),
),
);
}
}
When app is open,the first_screen widget must display until 3seconds and after the time passed home_page widget must show that I expect.But,after over 3seconds,home_page is not appear.State changing is notified from provider to Router.Which part is error?Please!!
My router app_route.dart is
import 'package:flutter/material.dart';
import 'package:navigator_2/keys/screen_keys.dart';
import 'package:navigator_2/provider/tab_provider.dart';
import 'package:navigator_2/root_screen.dart';
import 'package:navigator_2/screens/first_screen.dart';
class AppRoute extends RouterDelegate<AppKey> with ChangeNotifier,PopNavigatorRouterDelegateMixin{
#override
late final GlobalKey<NavigatorState> navigatorKeys;
final TabManager _tabManager;
AppRoute(this._tabManager) : navigatorKeys = GlobalKey<NavigatorState>(){
_tabManager.addListener(() {notifyListeners();});
}
#override
Widget build(BuildContext context) {
print("${_tabManager.isInitialPage}");
print("${_tabManager.currentTab}");
return Navigator(
key: navigatorKeys,
onPopPage: _handlePopPage,
pages: [
if(!_tabManager.isInitialPage) FirstScreen.page(),
if(_tabManager.isInitialPage == true)...{
RootScreen.page(_tabManager.currentTab)
},
],
);
}
#override
Future<void> setNewRoutePath(configuration) {
// TODO: implement setNewRoutePath
throw UnimplementedError();
}
bool _handlePopPage(Route<dynamic> route, result) {
if(!route.didPop(result)){
return false;
}
return true;
}
#override
// TODO: implement navigatorKey
GlobalKey<NavigatorState>? get navigatorKey => navigatorKeys;
}`
--------------------------------------------------------------------------------------------------
main.dart is
import 'package:flutter/material.dart';
import 'package:navigator_2/provider/tab_provider.dart';
import 'package:navigator_2/router_api/app_route.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
// This widget is the root of your application.
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late AppRoute _appRoute;
TabManager tabManager = TabManager();
#override
void initState() {
super.initState();
_appRoute = AppRoute(tabManager);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => TabManager())
],
child: Router(routerDelegate: _appRoute),
),
);
}
}
I'm trying to load a json file into my main() app method.
Can you tell me if this is possible? I've tryed File and rootBundle but it seems that Assets' folder are not ready yet.
here is my code:
ASSETS
assets:
- assets/settings/settings.json
MAIN METHOD
void main() async {
final file = await rootBundle.loadString('assets/settings/settings.json');
final data = jsonDecode(file);
Settings settings = Get.put(Settings.fromJson(data), permanent: true);
runApp(MyApp());
}
Found the Solution using FutureBuilder
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
_load() async {
final file = await rootBundle.loadString('assets/j.json');
final data = await jsonDecode(file);
print(data.toString());
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: _load(),
builder: (_, AsyncSnapshot<dynamic> snapshot) {
return !snapshot.hasData
? Container(
color: Colors.white,
child: Center(
child: Container(
child: CircularProgressIndicator(),
width: 20,
height: 20,
)),
)
: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
appBarTheme: AppBarTheme(
titleTextStyle: Theme.of(context).textTheme.headline1,
),
),
home: Scaffold(
body: Text("Body"),
// MaxWidthButton(),
),
);
});
}
}
I dont seems it is, instead try on MyApp and make it statefullWidget
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
_load();
}
_load() async {
final file = await rootBundle.loadString('assets/j.json');
final data = await jsonDecode(file);
print(data.toString());
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
appBarTheme: AppBarTheme(
titleTextStyle: Theme.of(context).textTheme.headline1,
),
),
home: Scaffold(
body: Text("Body"),
// MaxWidthButton(),
),
);
}
}
I'm very new to flutter.
I've created an app that should open up google maps on click but it wont open.
Please help me out.
forMap.dart file (This is the file which has the method to launch google maps):
import 'package:url_launcher/url_launcher.dart';
class MapUtils {
MapUtils._();
static Future<void>openMap(double latitude,double longitude) async {
String googleUrl = 'https://www.google.com/maps/search/?api=1&query=$latitude,$longitude';
if(await canLaunch(googleUrl) != null) {
await canLaunch(googleUrl);
} else {
throw 'Could not open the map.';
}
}
}
main.dart file (This is the file which will use the method of the forMap.dart file and launch it):
import 'package:flutter/material.dart';
import 'forMap.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: (){
MapUtils.openMap(38.8977,77.0365);
},
child: Text('get map'),
),
],
),
),
);
}
}
It is because you have incorrectly calling a function. You're using await canLaunch(googleUrl); instead of await launch(googleUrl); in the if part.
So, your code should be like this:
static Future<void> openMap(double latitude,double longitude) async {
String googleUrl = 'https://www.google.com/maps/search/?api=1&query=$latitude,$longitude';
if(await canLaunch(googleUrl) != null) {
await launch(googleUrl);
} else {
throw 'Could not open the map.';
}
}
You probably don't need to use Future<void> so, change the function name to:
static void openMap(double latitude,double longitude) async {
...
}
I'm new to flutter. I am trying to set up an authentication flow. if the user is not logged in, I plan to build a MaterialApp with certain routes (eg Facebook Auth, Google Auth and Email Auth). If the user is logged in, they ll see another MaterialApp with routes such as HomePage, ListPage, CreatePage etc.
I tried but below codes fail. Anyone with experience can advise? thanks in advance
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import './pages/email.dart';
import './pages/auth.dart';
import './pages/home.dart';
import './pages/list.dart';
import './pages/create.dart';
import './scoped-models/main.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
final MainModel _model = MainModel();
bool _isAuthenticated = false;
#override
void initState() {
_model.autoAuthenticate();
_model.userSubject.listen((bool isAuthenticated) {
setState(() {
_isAuthenticated = isAuthenticated;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
print(_isAuthenticated);
return ScopedModel<MainModel>(
model: _model,
child: !_isAuthenticated == true
? MaterialApp(
theme: ThemeData(
primaryColor: Colors.lime, buttonColor: Colors.teal),
routes: {
'/': (BuildContext context) => AuthPage(),
'/email': (BuildContext context) => EmailPage(),
},
)
: MaterialApp(
theme: ThemeData(
primaryColor: Colors.lime, buttonColor: Colors.teal),
routes: {
'/': (BuildContext context) => HomePage(),
'/list': (BuildContext context) => ListPage(),
'/create': (BuildContext context) => CreatePage()
},
),
);
}