NoSuchMethodError (NoSuchMethodError: Class 'String' has no instance getter 'code' - flutter

Full error -
NoSuchMethodError (NoSuchMethodError: Class 'String' has no instance getter 'code'.
Receiver: "http://download.jimicloud.com/webDown/mibike?no=75039909"
Tried calling: code)
Hi all! I'm trying to scan the qr code and send the data to the server, but I'm running into the error you see above.
Package for code scanning - qr_code_scanner: ^1.0.1
Here is my scan widget code -
import 'dart:developer';
import 'package:eco_city/features/presentation/scanner/cubit/scanner_cubit.dart';
import 'package:eco_city/features/presentation/scanner/cubit/scanner_state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:http/http.dart';
// import 'package:mobile_scanner/mobile_scanner.dart';
import 'dart:io';
import '../home/home.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class MyQr extends StatelessWidget {
#override
Widget build(BuildContext context) {
return BlocProvider<ScannerCubit>(
create: (context) => ScannerCubit(),
child: QRViewExample(),
);
}
}
class QRViewExample extends StatefulWidget {
#override
_QRViewExampleState createState() => _QRViewExampleState();
}
class _QRViewExampleState extends State<QRViewExample> {
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
Barcode? result;
QRViewController? controller;
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
#override
void reassemble() {
super.reassemble();
print('первая функция');
if (Platform.isAndroid) {
controller!.pauseCamera();
} else if (Platform.isIOS) {
controller!.resumeCamera();
}
}
getQr(qr) {
if (qr != null) {
RegExp exp = RegExp(r"[^0-9]+");
final stringFormat = qr.code.rawContent.replaceAll(exp, '');
return stringFormat;
}
}
#override
Widget build(BuildContext context) {
return BlocBuilder<ScannerCubit, ScannerState>(
builder: (context, state) {
if (state is ScannerNotScan) {
return SafeArea(
child: Scaffold(
body: Column(
children: <Widget>[
Expanded(
flex: 5,
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
),
),
Expanded(
flex: 1,
child: Center(
child: (result != null)
? Text(
'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}')
: Text('Scan a code'),
),
)
],
),
));
} else if (state is ScannerLoading) {
return Scaffold(
body: Center(child: CircularProgressIndicator()),
);
} else if (state is ScannerLoaded) {
return Scaffold(
body: Center(child: Text('Успех!')),
);
} else if (state is ScannerError) {
return Scaffold(
body: Center(child: Text('Ошибка!')),
);
}
throw StateError('err');
},
);
}
void _onQRViewCreated(QRViewController controller) async {
print('последняя функция');
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
if (result != null) {
getNextScreen();
}
});
});
}
void getNextScreen() async {
if (result != null) {
await context.read<ScannerCubit>().scanner(getQr(result!.code));
// log(await getQr(result!.code.toString()));
}
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
}
And here is my cubit -
import 'dart:convert';
import 'dart:developer';
import 'package:eco_city/features/data/scanner/scanner_models.dart';
import 'package:eco_city/features/presentation/scanner/cubit/scanner_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import '../../config.dart';
class ScannerCubit extends Cubit<ScannerState> {
ScannerCubit? bloc;
ScannerCubit() : super(ScannerNotScan());
Future<void> scanner(String qr) async {
if (isClosed) return;
emit(ScannerLoading());
final prefs = await SharedPreferences.getInstance();
final token = prefs.getString('token');
final response = await http.post(Uri.parse(ConfigUrl.sendQrCodeScanner),
headers: {
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer $token"
},
body: jsonEncode(<String, dynamic>{
"qr_code": qr,
}));
if (isClosed) return;
if (response.statusCode == 200) {
log(qr);
final responseJson = json.decode(response.body) as Map<String, dynamic>;
emit(ScannerLoaded(scannerModel: ScannerModel.fromJson(responseJson)));
} else {
log(qr);
log(response.statusCode.toString());
log(json.decode(response.body).toString());
emit(ScannerError());
}
}
}
I don’t understand at all what the error is, and how can I send ONLY numbers to the server?
and my vscode -

first print the this line *** log(await getQr(result!.code.toString())) ****
and check whether is function is return the value or returning the null.

Related

flutter does not show data from API

When I try to pull data from the jsonplaceholder API and put it on the screen, I don't have any problems, but when I try to change the data in this link (https://reqres.in/api/users?page=2 ) on the reqres.io site with the same codes, only by changing the API and model, the text no data appears on the screen. I'm getting it can you help me ?
My project with JsonPlaceHolder
main.dart
import 'package:flutter/material.dart';
import 'package:my_app/models/json_model.dart';
import 'service/api_service.dart';
void main() =\> runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Json Deneme'),
),
body: const Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
#override
State\<Home\> createState() =\> \_HomeState();
}
class \_HomeState extends State\<Home\> {
List\<JsonModel\>? \_postItems;
bool \_isLoading = false;
String? \_errorMessage;
#override
void initState() {
super.initState();
loadData();
}
Future\<void\> loadData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final postItems = await Api.fetchApi();
setState(() {
_postItems = postItems;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error fetching data: $e';
});
}
}
#override
Widget build(BuildContext context) {
if (\_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (\_postItems == null || \_postItems!.isEmpty) {
return const Center(child: Text('No Data'));
} else {
return ListView.builder(
itemCount: \_postItems!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(\_postItems!\[index\].name),
);
},
);
}
}
}`
api_service.dart
`import 'dart:io';
import 'package:my_app/models/json_model.dart';
import 'package:dio/dio.dart';
class Api {
static Future<List<JsonModel>?> fetchApi() async {
final res = await Dio().get("https://jsonplaceholder.typicode.com/users");
if (res.statusCode == HttpStatus.ok) {
final data = res.data!;
if (data is List) {
return data.map((e) =\> JsonModel.fromMap(e)).toList();
}
}
return <JsonModel>[];
}
}
`
conclusion
conclusion
My project with reqres.in
main.dart
`import 'package:flutter/material.dart';
import 'package:my_app/models/json_model.dart';
import 'service/api_service.dart';
void main() =\> runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Json Deneme'),
),
body: const Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<ReqresModel>? _postItems;
bool _isLoading = false;
String? _errorMessage;
#override
void initState() {
super.initState();
loadData();
}
Future<void> loadData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final postItems = await Api.fetchApi();
setState(() {
_postItems = postItems;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error fetching data: $e';
});
}
}
#override
Widget build(BuildContext context) {
if (_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (_postItems == null || _postItems!.isEmpty) {
return const Center(child: Text('No Data'));
} else {
return ListView.builder(
itemCount: _postItems!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(\_postItems!\[index\].data\[index\].firstName),
);
},
);
}
}
}`
api_servise.dart
`import 'dart:io';
import 'package:my_app/models/json_model.dart';
import 'package:dio/dio.dart';
class Api {
static Future<List<ReqresModel>?> fetchApi() async {
final res = await Dio().get("https://reqres.in/api/users?page=2");
if (res.statusCode == HttpStatus.ok) {
final data = res.data!;
if (data is List) {
return data.map((e) => ReqresModel.fromMap(e)).toList();
}
}
return <ReqresModel>[];
}
}`
conclusion
conclusion
**Thank you **
I sent the API using Postman, there was no problem, I don't think the problem was caused by the API, sorry for my bad English
Change your api_service.dart for reqres.in project with following code.
First api which returns List directly, but second api which return Json which has data as List
Edited
main.dart
import 'package:flutter/material.dart';
import 'package:my_app/models/json_model.dart';
import 'service/api_service.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Json Deneme'),
),
body: const Home(),
),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<ReqresModel>? _postItems;
bool _isLoading = false;
String? _errorMessage;
#override
void initState() {
super.initState();
loadData();
}
Future<void> loadData() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final postItems = await Api.fetchApi();
setState(() {
_postItems = postItems;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error fetching data: $e';
});
}
}
#override
Widget build(BuildContext context) {
if (_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (_postItems == null || _postItems!.isEmpty) {
return const Center(child: Text('No Data'));
} else {
return ListView.builder(
itemCount: _postItems!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_postItems![index].firstName),//Updated here
);
},
);
}
}
}
api_service.dart
import 'dart:io';
import 'package:my_app/models/json_model.dart';
import 'package:dio/dio.dart';
class Api {
static Future<List<ReqresModel>?> fetchApi() async {
final res = await Dio().get("https://reqres.in/api/users?page=2");
if (res.statusCode == HttpStatus.ok) {
final data = res.data!['data'];//Updated here
if (data is List) {
return data.map((e) => ReqresModel.fromMap(e)).toList();
}
}
return <ReqresModel>[];
}
}
ReqresModel - should be updated
//Updated here
class ReqresModel {
int? id;
String? email;
String? firstName;
String? lastName;
String? avatar;
ReqresModel(
{this.id, this.email, this.firstName, this.lastName, this.avatar});
ReqresModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
email = json['email'];
firstName = json['first_name'];
lastName = json['last_name'];
avatar = json['avatar'];
}
}

StateError (Bad state: Cannot emit new states after calling close) in bloc_base.dart

I need your help. Just an hour ago this code worked fine, but now I get the error you see in the question
The bottom line is that when I click on the button, I go to the screen where I have to scan the qr code, but when I go to this very screen, I get an error. Help fix it!
Full screen code posted below -
import 'dart:developer';
import 'package:eco_city/features/presentation/scanner/cubit/scanner_cubit.dart';
import 'package:eco_city/features/presentation/scanner/cubit/scanner_state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:http/http.dart';
// import 'package:mobile_scanner/mobile_scanner.dart';
import 'dart:io';
import '../home/home.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class QRViewExample extends StatefulWidget {
#override
_QRViewExampleState createState() => _QRViewExampleState();
}
class _QRViewExampleState extends State<QRViewExample> {
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
Barcode? result;
QRViewController? controller;
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
#override
void reassemble() {
super.reassemble();
print('первая функция');
if (Platform.isAndroid) {
controller!.pauseCamera();
} else if (Platform.isIOS) {
controller!.resumeCamera();
}
}
getQr(qr) {
if (qr != null) {
RegExp exp = RegExp(r"[^0-9]+");
final stringFormat = qr.code.rawContent.replaceAll(exp, '');
return stringFormat;
}
}
#override
Widget build(BuildContext context) {
return BlocProvider<ScannerCubit>(
create: (context) => ScannerCubit(),
child: BlocBuilder<ScannerCubit, ScannerState>(
builder: (context, state) {
if (state is ScannerNotScan) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
flex: 5,
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
),
),
Expanded(
flex: 1,
child: Center(
child: (result != null)
? Text(
'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}')
: Text('Scan a code'),
),
)
],
),
);
} else if (state is ScannerLoading) {
return Scaffold(
body: Center(child: CircularProgressIndicator()),
);
} else if (state is ScannerLoaded) {
return Home();
} else if (state is ScannerError) {
return Scaffold(
body: Center(child: Text('4')),
);
}
throw StateError('err');
},
),
);
}
void _onQRViewCreated(QRViewController controller) async {
print('последняя функция');
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
if (result != null) {
getNextScreen();
}
});
});
}
void getNextScreen() async {
if (result != null) {
await context.read<ScannerCubit>().scanner(getQr(result!.code));
// log(await getQr(result!.code.toString()));
}
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
}
and my cubit -
import 'dart:convert';
import 'dart:developer';
import 'package:eco_city/features/data/scanner/scanner_models.dart';
import 'package:eco_city/features/presentation/scanner/cubit/scanner_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import '../../config.dart';
class ScannerCubit extends Cubit<ScannerState> {
ScannerCubit() : super(ScannerNotScan());
Future<void> scanner(String qr) async {
emit(ScannerLoading());
final prefs = await SharedPreferences.getInstance();
final token = prefs.getString('token');
final response = await http.post(Uri.parse(ConfigUrl.sendQrCodeScanner),
headers: {
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer $token"
},
body: jsonEncode(<String, dynamic>{
"qr_code": qr,
}));
if(isClosed) return;
if (response.statusCode == 200) {
log(qr);
final responseJson = json.decode(response.body) as Map<String, dynamic>;
emit(ScannerLoaded(scannerModel: ScannerModel.fromJson(responseJson)));
} else {
log(qr);
log(response.statusCode.toString());
log(json.decode(response.body).toString());
emit(ScannerError());
}
}
}
Sometimes my screen is replaced well, but often with an error
you shouldn't place the BlocProvider inside the stateful widget. Like this, the provider becomes re-created on every new build, for example if the scan provides no result.
Try to create an upstream widget (above QRViewExample) and place the provider there.

Hive boxes are deleted when app closes or restart

The problem is that Hive is acting unexpectedly, and when the app closes or I restart it all, the data in the box is cleared.
main.dart:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(statusBarColor: Colors.transparent));
await Firebase.initializeApp();
await Hive.initFlutter();
Hive.registerAdapter(CredentialsModelAdapter());
Hive.registerAdapter(DoctorModelAdapter());
Hive.registerAdapter(DuserModelAdapter());
Hive.registerAdapter(DoctorAppointmentsAdapter());
Hive.registerAdapter(AppointmentStatusesAdapter());
Hive.registerAdapter(AccountTypeAdapter());
Hive.registerAdapter(UserAdapter());
await Hive.openBox<CredentialsModel>("cred");
await Hive.openBox<DuserModel>("doctor");
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
final _appRouter = app_router.AppRouter();
#override
Widget build(BuildContext context) {
return MaterialApp.router(
title: "x",
debugShowCheckedModeBanner: false,
routerDelegate: _appRouter.delegate(),
routeInformationParser: _appRouter.defaultRouteParser(),
);
}
}
Here is where I fetch the data from the api and store it in box:
#override
Future<Either<ApiFailures, dynamic>> signInWithEmailAndPassword(
{required String email, required String password}) async {
late Box<CredentialsModel> credentials;
var result;
try {
final response = await http.get(Uri.parse(
"xxxxxxxx"));
if (response.statusCode == 200) {
result = await json.decode(response.body);
if (result["AZSVR"] == "FAILED") {
return const Left(ApiFailures.authFailed());
} else {
var content = CredentialsModel.fromJson(result);
credentials = Hive.box("cred");
credentials.put('cred', content);
return right(result["api_token"]);
}
}
} on SocketException catch (e) {
return const Left(ApiFailures.noConnection());
} on HttpException {
return const Left(ApiFailures.notfound());
} catch (_) {
return const Left(ApiFailures.notfound());
}
return Right(result["api_token"]);
}
Where I call the box:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vwelfare/application/provider/doctor.repository.provider.dart';
import 'package:vwelfare/domain/models/doctor/duser.dart';
import '../../domain/models/credentials/credentials.dart';
class MyWidget extends HookConsumerWidget {
const MyWidget({super.key});
#override
Widget build(BuildContext context, WidgetRef ref) {
final Box<CredentialsModel> credBox = Hive.box("cred");
final Box<DuserModel> doctorBox = Hive.box("doctor");
final controller = useTextEditingController();
final uid = useState(0);
final cred = useState(const CredentialsModel());
return Scaffold(
body: ValueListenableBuilder(
valueListenable: credBox.listenable(),
builder: (context, Box<CredentialsModel> box, _) {
final cred = box.get("cred");
print(cred!.api_token);
final doctor = ref.watch(getDoctor(cred.api_token!));
return doctor.when(
data: (data) => data.fold(
(l) => ValueListenableBuilder(
valueListenable: doctorBox.listenable(),
builder: (context, Box<DuserModel> box, _) {
final model = box.get("doctor");
final doctor = model!.User;
if (doctor != null) {
return Center(
child: Text("${doctor.address}"),
);
} else {
return const Center(
child: Text("CONTACT US"),
);
}
}),
(r) => Center(child: Text("${r.User!.name}"))),
loading: () => const CircularProgressIndicator(),
error: (error, stackTrace) {
print(error);
return Center(
child: Text("$error hello"),
);
});
},
),
);
}
}
I don't know if I am doing something wrong but I followed the docs as they say:
1- registered the adapter
2- opened the box
3- called it in a widget
What am I doing wrong?

How to have the ability to use both Navigator.push and Navigator.pushNamed flutter

I have added some routes to my flutter app so that when a specific link is pressed a specific page will be opened
This is the source code of the main page
import 'dart:convert';
import 'package:admob_flutter/admob_flutter.dart';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:catcher/catcher.dart';
import 'package:dynamic_theme/dynamic_theme.dart';
import 'package:firebase_admob/firebase_admob.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:videos/c.dart';
import 'package:flutter/foundation.dart';
import 'package:videos/post.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'database/database.dart';
import 'database/database/mobile.dart' as mobile;
import 'src/app_route.dart';
void main() async{
WidgetsFlutterBinding.ensureInitialized();
FirebaseAdMob.instance.initialize(appId: APP_ID);
Admob.initialize(APP_ID);
await AndroidAlarmManager.initialize();
CatcherOptions debugOptions =CatcherOptions(DialogReportMode(), [kIsWeb?ConsoleHandler(): EmailManualHandler(["ahmad.rajab#windowslive.com"])]);
CatcherOptions releaseOptions = CatcherOptions(DialogReportMode(), [
kIsWeb?ToastHandler():EmailManualHandler(["ahmad.rajab#windowslive.com"])
]);
Catcher(MyApp(), debugConfig: debugOptions, releaseConfig: releaseOptions);
}
class MyApp extends StatefulWidget{
#override
State<StatefulWidget> createState()=>MyAppState();
}
class MyAppState extends State<MyApp> {
static Future configureDatabase()async{
/*database = await openDatabase(DATABASE_NAME, version: DATABASE_VERSION,
onCreate: (Database db, int version) async {
await db.execute('create table $WATCHED_VIDEOS ($VIDEO_ID text,$REACHED_SECOND integer default 0,$NOTE text)');
await db.execute('create table $TABLE_FAVORITE_VIDEOS ($VIDEO_TITLE text,$VIDEO_ID text,$VIDEO_DESCRIPTION text,$VIDEO_THUMBURL text)');
await db.execute('create table $CHANNELS ($ID integer ,$NAME text,$LINK text, $PICTURE_LINK text,$VIEWED integer default 0,$GET_NOTIFICATIONS integer default 1,$LAST_VIDEO_TITLE text)');
},
onUpgrade: (db, oldVersion, newVersion)async {
var tableColumns= await db.query('PRAGMA table_info($WATCHED_VIDEOS)');
bool noteColumnExists=false;
for(int c=0;c<tableColumns.length;c++){
if(tableColumns[c]['name'].toString()==NOTE)noteColumnExists=true;
}
if(!noteColumnExists) await db.execute('alter table $WATCHED_VIDEOS add $NOTE text');
},);
*/
}
AppRouterDelegate _routerDelegate = AppRouterDelegate();
AppRouteInformationParser _routeInformationParser =
AppRouteInformationParser();
#override
void initState() {
super.initState();
initialiseNotification();
initialiseTimeZone();
showDailyReminderNotification();
configureDailyNewVideosFitch();
}
void configureDailyNewVideosFitch()async{
await AndroidAlarmManager.periodic(const Duration(days: 1),DAILY_NEW_VIDEOS_FETCH_ALARAM_ID , ()async{
Database d=RepositoryProvider.of<Database>(context);
List<Channel>subscribedChannels=await (d.select($ChannelsTable(d))..where((tbl) => tbl.getNotifications.equals(1))).get();
String channelsIds='';
for(int i=0;i<subscribedChannels.length;i++)channelsIds+=subscribedChannels[i].link+"/";
Map<String,String> map=Map();
map['channels']=channelsIds;
Post p=Post(context,'getVideosFromTime.php',map);
await p.fetchPost();
if(p.connectionSucceed){
dynamic resultJson=json.decode(p.result);
if(resultJson['result']=='success'){
for(int i=0;i<resultJson['data'].length;i++){
dynamic videoJson=resultJson['data'][i];
await flutterLocalNotificationsPlugin.show(videoJson['id'], videoJson['channelName'], videoJson['title'],
NotificationDetails(
android: AndroidNotificationDetails(
APP_NAME,
APP_NAME, NEW_VIDEO_AVAILABLE,
icon: '#mipmap/ic_launcher',
ticker: videoJson['title']
),
),
payload:'/watch?v='+videoJson['videoId']
);
}
}
}
},rescheduleOnReboot: true);
}
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
void showDailyReminderNotification()async{
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(APP_NAME,
APP_NAME, 'dailyReminder'+APP_NAME,
icon: '#mipmap/ic_launcher',
ticker: TIME_TO_LEARN);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.periodicallyShow(DAILY_REMINDER_NOTIFICATION_ID, TIME_TO_LEARN,
TIME_TO_LEARN_DESCRIPTION, RepeatInterval.daily, platformChannelSpecifics,
androidAllowWhileIdle: false);
}
void initialiseTimeZone()async{
tz.initializeTimeZones();
tz.setLocalLocation(tz.getLocation(await FlutterNativeTimezone.getLocalTimezone()));
}
void initialiseNotification()async{
flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
/*onDidReceiveLocalNotification: onDidReceiveLocalNotification*/);
final MacOSInitializationSettings initializationSettingsMacOS =
MacOSInitializationSettings();
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
await flutterLocalNotificationsPlugin.cancel(DAILY_REMINDER_NOTIFICATION_ID);
}
Future selectNotification(String payload) async {
if(payload!=null)Navigator.pushNamed(context, payload);
}
#override
Widget build(BuildContext context) {
return DynamicTheme(
defaultBrightness: Brightness.light,
data: (brightness) => ThemeData(
primarySwatch: PRIMARY_COLOR,
brightness: brightness
),
themedWidgetBuilder: (context, data) {
return RepositoryProvider<Database>(
create:(context)=>mobile.constructDb() ,
child: BlocProvider(
create: (context){
//final db = RepositoryProvider.of<Database>(context);
//return AppBloc(db);
},
child: MaterialApp.router(
//title: 'Books App',
theme: data,
routerDelegate: _routerDelegate,
routeInformationParser: _routeInformationParser,
)
)
);
}
);
}
}
MobileAdTargetingInfo targetingInfo = MobileAdTargetingInfo(
// ignore: deprecated_member_use
gender: MobileAdGender.unknown,
childDirected: true
);
class AdmobAdd extends StatelessWidget{
#override
Widget build(BuildContext context) {
return !PRO?AdmobBanner(
adUnitId: kReleaseMode?BANNER_AD_UNIT_ID:BannerAd.testAdUnitId,
adSize: AdmobBannerSize.BANNER,
):Container();
}
}
InterstitialAd myInterstitial = InterstitialAd(
adUnitId: InterstitialAd.testAdUnitId,
targetingInfo: targetingInfo,
);
this is the source code of the routes configuration file
import 'package:catcher/catcher.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:videos/home.dart';
import 'package:videos/video.dart';
class AppRouteInformationParser extends RouteInformationParser<AppRoutePath> {
#override
Future<AppRoutePath> parseRouteInformation(
RouteInformation routeInformation) async {
final uri = Uri.parse(routeInformation.location);
// Handle '/'
if (uri.pathSegments.length == 0) {
return AppRoutePath.home();
}
// Handle '/watch?v=fsdfsdfsd
if (uri.pathSegments.length == 1) {
if (!uri.pathSegments[0].startsWith('/watch?')) return AppRoutePath.unknown();
if(uri.pathSegments[0].startsWith('/watch?v=')){
var videoId=uri.queryParameters['v'];
return AppRoutePath.video(videoId);
/*var remaining = uri.pathSegments[1];
var id = int.tryParse(remaining);
if (id == null) return AppRoutePath.unknown();
return AppRoutePath.details(id);*/
}
}
// Handle unknown routes
return AppRoutePath.unknown();
}
#override
RouteInformation restoreRouteInformation(AppRoutePath path) {
if (path.isUnknown) {
return RouteInformation(location: '/404');
}
if (path.isHomePage) {
return RouteInformation(location: '/');
}
if(path.isVideoPage){
return RouteInformation(location: '/watch?v=${path.id}');
}
if (path.isDetailsPage) {
return RouteInformation(location: '/book/${path.id}');
}
return null;
}
}
class AppRouterDelegate extends RouterDelegate<AppRoutePath>
with ChangeNotifier, PopNavigatorRouterDelegateMixin<AppRoutePath> {
final GlobalKey<NavigatorState> navigatorKey;
//Book _selectedBook;
bool show404 = false;
String videoId;
/*List<Book> books = [
Book('Stranger in a Strange Land', 'Robert A. Heinlein'),
Book('Foundation', 'Isaac Asimov'),
Book('Fahrenheit 451', 'Ray Bradbury'),
];*/
AppRouterDelegate() : navigatorKey = GlobalKey<NavigatorState>();
AppRoutePath get currentConfiguration {
if (show404) {
return AppRoutePath.unknown();
}
if(videoId!=null) return AppRoutePath.video(videoId);
/*return _selectedBook == null
? AppRoutePath.home()
: AppRoutePath.details(books.indexOf(_selectedBook));*/
return AppRoutePath.home();
}
#override
Widget build(BuildContext context) {
return Navigator(
key: Catcher.navigatorKey,
pages: [
MaterialPage(
key: ValueKey('Home'),
child: MyHomePage()
),
if (show404)
MaterialPage(key: ValueKey('Unknown'), child: UnknownScreen())
else if(videoId!=null) VideoPageRoute(videoId: videoId)
/*else if (_selectedBook != null)
BookDetailsPage(book: _selectedBook)*/
],
onPopPage: (route, result) {
if (!route.didPop(result)) {
return false;
}
// Update the list of pages by setting _selectedBook to null
//_selectedBook = null;
videoId=null;
show404 = false;
notifyListeners();
return true;
},
);
}
#override
Future<void> setNewRoutePath(AppRoutePath path) async {
if (path.isUnknown) {
//_selectedBook = null;
videoId=null;
show404 = true;
return;
}
/*if (path.isDetailsPage) {
if (path.id < 0 || path.id > books.length - 1) {
show404 = true;
return;
}
_selectedBook = books[path.id];
} else {
_selectedBook = null;
}*/
show404 = false;
}
void videoNotFound(){
videoId=null;
show404=true;
notifyListeners();
}
/*void _handleBookTapped(Book book) {
_selectedBook = book;
notifyListeners();
}*/
}
class AppRoutePath {
final String id;
final bool isUnknown;
AppRoutePath.home()
: id = null,
isUnknown = false;
AppRoutePath.details(this.id) : isUnknown = false;
AppRoutePath.video(this.id): isUnknown=false;
AppRoutePath.unknown()
: id = null,
isUnknown = true;
bool get isHomePage => id == null;
bool get isDetailsPage => id != null;
bool get isVideoPage => id!=null;
}
/*class BooksListScreen extends StatelessWidget {
final List<Book> books;
final ValueChanged<Book> onTapped;
BooksListScreen({
#required this.books,
#required this.onTapped,
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView(
children: [
for (var book in books)
ListTile(
title: Text(book.title),
subtitle: Text(book.author),
onTap: () => onTapped(book),
)
],
),
);
}
}
*/
/*class BookDetailsScreen extends StatelessWidget {
final Book book;
BookDetailsScreen({
#required this.book,
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (book != null) ...[
Text(book.title, style: Theme.of(context).textTheme.headline6),
Text(book.author, style: Theme.of(context).textTheme.subtitle1),
],
],
),
),
);
}
}
*/
class UnknownScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text('404!'),
),
);
}
}
The problem is that I have several screens that has no specific url and I do not want to provide them with routes, I want simply to use Navigator.push()
That is working fine, but when pressing the back button or when I use Navigator.pop() the app closes entirely instead of navigating back to the previous page
How can I use Navigator.pushNamed only for named routes and use Navigator.push for other pages without causing the problem to occur
Thanks in advance

Cant get length in listview.builder in Flutter

I'm learning flutter and dart language and trying to apply bloc pattern by rxdart and show data in the page.
Can't get length or display a data in page stream builder and listview.builder because I receive error:
class 'Future<List<User>>' has no instance getter 'length'.
Receiver: Instance of 'Future<List<User>>'
Tried calling: length
My class user.dart
class User {
int id;
String name;
String username;
String email;
User({this.id, this.name, this.username, this.email});
User.fromJson(Map<String, dynamic> parsedJson) {
User(
id: parsedJson['id'],
name: parsedJson['name'],
username: parsedJson['username'],
email: parsedJson['email'],
);
}
}
// user_repo.dart
import 'package:learn_flutter_bloc/bloc_rx_example/User.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
import 'package:learn_flutter_bloc/url.dart';
class UserRepo {
static Future<List<User>> getUsers() async {
final res = await http.get("https://jsonplaceholder.typicode.com/users");
List<User> users = [];
if (res.statusCode == 200) {
var data = jsonDecode(res.body);
for (var user in data) {
users.add(User.fromJson(user));
}
return users;
} else {
throw Exception("Error In Calling APi");
}
}
}
// user_bloc
import 'package:learn_flutter_bloc/bloc_base.dart';
import 'package:learn_flutter_bloc/bloc_rx_example/user_repo.dart';
import 'package:rxdart/subjects.dart';
class UserBloc extends BlocBase {
Subject _usersSubject = BehaviorSubject();
Stream get users => _usersSubject.stream;
getUsers() async {
var usersData = UserRepo.getUsers();
_usersSubject.add(usersData);
}
#override
dispose() {
_usersSubject.close();
}
}
final bloc = UserBloc();
// user_list_app.dart
import 'package:flutter/material.dart';
import 'package:learn_flutter_bloc/bloc_rx_example/user_bloc.dart';
class UserListApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Bloc Rx Example',
theme: ThemeData(
primaryColor: Colors.teal,
),
home: Scaffold(
appBar: AppBar(
title: Text('Bloc Rx Example'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.of(context).pop();
}),
),
body: UserList(),
),
);
}
}
class UserList extends StatefulWidget {
#override
_UserListState createState() => _UserListState();
}
class _UserListState extends State<UserList> {
#override
void dispose() {
bloc.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
bloc.getUsers();
return Padding(
padding: EdgeInsets.all(10.0),
child: StreamBuilder(
stream: bloc.users,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.weekend),
title: Text('${snapshot.data[index].name}'),
);
});
} else if (!snapshot.hasError) {
return Text(snapshot.error.toString());
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
While you are using StreamBuilder in the UI, Your getUsers() is returning Future<List<User>> . Return Stream<<List<User>> from getUsers() .
Fixed I problem was in bloc_user.dart misssing await
Future<List<User>> getUsers() async {
var usersData = UserRepo.getUsers();
print(usersData);
_usersSubject.sink.add(usersData);
}
to
Future<List<User>> getUsers() async {
var usersData = await UserRepo.getUsers();
print(usersData);
_usersSubject.sink.add(usersData);
}