I have to add new product as well as edit existing product in one screen . so I have Used didchangedependencies method by assigning the initial values to update a screen something gone wrong in my code.please help me out. so the error is
Error is showing here:
@override
void didChangeDependencies() {
if (_isinit) {
final productId = ModalRoute.of(context)!.settings.arguments as String;
// ignore: unnecessary_null_comparison
if (productId != null) {
_editedproduct =
Provider.of<Products>(context, listen: false).FindByID(productId);
_imageUrlController.text = _editedproduct.imageUrl;
_initValues = {
'title': _editedproduct.title,
'description': _editedproduct.description,
'Price': _editedproduct.price.toString(),
// 'imageUrl': _editedproduct.imageUrl,
'imageUrl': '',
};
}
}
_isinit = false;
super.didChangeDependencies();
}
In did change dependencies method I have tried to get the arguments i.e product ID from one page but it showing null.
this is screenshot where i have pushed to edit screen product page with arguments which I was tried to fetch this arguments.
and this is for pushing to adding product page
import 'dart:html';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shoppingapp/Providers/Product.dart';
import 'package:shoppingapp/Providers/Products.dart';
class EditProductScreen extends StatefulWidget {
static const routeName = '/edit-products';
@override
_EditProductScreenState createState() => _EditProductScreenState();
}
class _EditProductScreenState extends State<EditProductScreen> {
final _priceFocusNode = FocusNode();
final _descriptionFocusNode = FocusNode();
final _imageUrlController = TextEditingController();
final _imageUrlFocusNode = FocusNode();
final _form = GlobalKey<FormState>();
var _editedproduct =
Product(id: '', title: '', description: '', price: 0, imageUrl: '');
var _isinit = true;
var _initValues = {
'title': '',
'description': '',
'price': '',
'imageUrl': '',
};
@override
void initState() {
_imageUrlFocusNode.addListener(_updateImageUrl);
super.initState();
}
@override
void didChangeDependencies() {
if (_isinit) {
final productId = ModalRoute.of(context)!.settings.arguments as String;
// ignore: unnecessary_null_comparison
if (productId != null) {
_editedproduct =
Provider.of<Products>(context, listen: false).FindByID(productId);
_imageUrlController.text = _editedproduct.imageUrl;
_initValues = {
'title': _editedproduct.title,
'description': _editedproduct.description,
'Price': _editedproduct.price.toString(),
// 'imageUrl': _editedproduct.imageUrl,
'imageUrl': '',
};
}
}
_isinit = false;
super.didChangeDependencies();
}
@override
void dispose() {
_imageUrlFocusNode.removeListener(_updateImageUrl);
_priceFocusNode.dispose();
_descriptionFocusNode.dispose();
_imageUrlFocusNode.dispose();
super.dispose();
}
void _updateImageUrl() {
if (!_imageUrlFocusNode.hasFocus) {
setState(() {});
}
}
void _saveForm() {
final isValid = _form.currentState!.validate();
if (isValid) {
return;
}
_form.currentState!.save();
if (_editedproduct.id != null) {
Provider.of<Products>(context, listen: false)
.updateProducts(_editedproduct.id, _editedproduct);
} else {
Provider.of<Products>(context, listen: false).addProducts(_editedproduct);
}
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Product'),
actions: [
IconButton(
icon: Icon(Icons.save),
onPressed: _saveForm,
),
],
),
body: Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _form,
child: ListView(
children: [
TextFormField(
decoration: InputDecoration(
labelText: 'Title',
),
initialValue: _initValues['title'],
textInputAction: TextInputAction.next,
validator: (value) {
if (value!.isEmpty) {
return 'Please provide a value.';
}
return null;
},
onFieldSubmitted: (_) {
FocusScope.of(context).requestFocus(_priceFocusNode);
},
onSaved: (value) {
_editedproduct = Product(
title: value as String,
price: _editedproduct.price,
description: _editedproduct.description,
imageUrl: _editedproduct.imageUrl,
id: _editedproduct.id,
isFavourite: _editedproduct.isFavourite);
},
),
TextFormField(
initialValue: _initValues['price'],
decoration: InputDecoration(
labelText: 'Price',
),
textInputAction: TextInputAction.next,
keyboardType: TextInputType.number,
focusNode: _priceFocusNode,
validator: (value) {
if (value!.isEmpty) {
return 'Please enter a price ';
}
if (double.tryParse(value) == null) {
return 'Please Enter a Valid Number';
}
if (double.parse(value) <= 0) {
return 'Please Enter the number greather no than zero';
}
},
onSaved: (value) {
_editedproduct = Product(
title: _editedproduct.title,
price: double.parse(value!),
description: _editedproduct.description,
imageUrl: _editedproduct.imageUrl,
id: _editedproduct.id,
isFavourite: _editedproduct.isFavourite);
},
),
TextFormField(
decoration: InputDecoration(
labelText: 'Description',
),
initialValue: _initValues['description'],
maxLines: 3,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.multiline,
focusNode: _descriptionFocusNode,
validator: (value) {
if (value!.isEmpty) {
return 'Please enter a description ';
}
if (value.length < 10) {
return 'Should be at least 10 characters long.';
}
return null;
},
onSaved: (value) {
_editedproduct = Product(
title: _editedproduct.title,
price: _editedproduct.price,
description: value as String,
imageUrl: _editedproduct.imageUrl,
id: _editedproduct.id,
isFavourite: _editedproduct.isFavourite);
},
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(top: 8, right: 10),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.grey)),
child: _imageUrlController.text.isEmpty
? Text('Enter a URL')
: FittedBox(
child: Image.network(
_imageUrlController.text,
fit: BoxFit.cover,
),
),
),
Expanded(
child: TextFormField(
decoration: InputDecoration(labelText: 'Image URl'),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
controller: _imageUrlController,
focusNode: _imageUrlFocusNode,
validator: (value) {
if (value!.isEmpty) {
return 'Please enter a URL ';
}
if (!value.startsWith('http') &&
!value.startsWith('https')) {
return 'Please Enter a valid URL';
}
if (!value.endsWith('.png') &&
!value.endsWith('.jpg') &&
!value.endsWith('.jpeg')) {
return 'Please enter a valid image URL';
}
return null;
},
onFieldSubmitted: (_) {
_saveForm();
},
onSaved: (value) {
_editedproduct = Product(
title: _editedproduct.title,
price: _editedproduct.price,
description: _editedproduct.description,
imageUrl: value as String,
id: _editedproduct.id,
isFavourite: _editedproduct.isFavourite);
},
),
),
],
),
],
),
),
),
);
}
}
While Null-Safety is implemented, most tutorials were made before it so in your case where you are trying to check if the ModalRoute
returns you a null
value or not and do stuff depending on that, good old if(productId == null)
won't work now.
Instead you can do this:
final productId = ModalRoute.of(context)!.settings.arguments == null ? "NULL":ModalRoute.of(context)!.settings.arguments as String;
if(productId != "NULL"){
//Do stuff here
}
If ModalRoute
gives you null
, you assign the string "NULL" to your variable productId
else you just assign whatever value it returned.
Then you can simply check if the value of productId
is NULL
and proceed accordingly.