hi guys im a newbie in flutter and i have this worker app with the basic crud operations, and i want to use the same screen for adding or updating a contact but i run into an error
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
return GestureDetector(
onTap: () {
Navigator.of(context)
.pushNamed('/Add-contact-screen', arguments: data);
},
child: ListTile(
title: Text(data['name']),
),
);
}).toList(),
);
this is my contacts list screen where on tap on a contact i navigate to the add contact screen with the arguments the contact object containing all the contact data like name, email, number etc. so that the form can be populated with the data, and this is how i receive those arguments in the add contact screen
import 'package:flutter/material.dart';
import '../../services/firestore_service.dart';
import '../../models/contacts/contact.dart';
import '../../utils/helper_widgets.dart';
class AddContactScreen extends StatefulWidget {
AddContactScreen({Key? key}) : super(key: key);
static const routeName = '/Add-contact-screen';
@override
State<AddContactScreen> createState() => _AddContactScreenState();
}
class _AddContactScreenState extends State<AddContactScreen> {
String category = 'Intern';
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final db = FirebaseFirestore.instance;
final firestoreService = FirestoreService();
var editMode = true;
@override
Widget build(BuildContext context) {
final routeArgs = ModalRoute.of(context)?.settings?.arguments as Map<dynamic, dynamic>;
return Scaffold(
appBar: AppBar(
title: editMode ? const Text('New Contact') : const Text('Edit'),
),
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: [
addVerticalSpace(10),
DropdownButton(
value: category,
icon: const Icon(Icons.keyboard_arrow_down),
items: dropdownItems,
onChanged: (String? newValue) {
setState(() {
category = newValue!;
});
},
),
TextFormField(
initialValue: routeArgs['name'],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
},
child: const Text('Save'),
),
TextButton(
onPressed: () {
},
child: const Text('Edit'))
],
)
],
),
),
),
);
}
}
now this works fine the input field is populated with the value im getting from
ModalRoute.of(context)?.settings?.arguments as Map<dynamic, dynamic>;
and the contact is ready to be updated, however when i click the add button to the contacts screen to open the add contact screen to add a brand new contact i get this error message type 'Null' is not a subtype of type 'Map<dynamic, dynamic>' in type cast
clicking in the floating button or tapping the contact name navigates to the same page but doing with the button crashes the app i believe it has to be something about the arguments
CodePudding user response:
as Map<dynamic, dynamic>
making it non-nullable. You can do
final routeArgs =
ModalRoute.of(context)?.settings.arguments as Map<dynamic, dynamic>?;
Now you can do a null check before using routeArgs
and those who accept null, you can do
initialValue: routeArgs?['name'],