Expected a value of type 'String', but got one of type 'Null' . This is for an eCommerce app

Issue

I got this error in main.dart but i dont think anything is wrong in it.

Main.dart:

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          
          create:
              (ctx) => Products(),
        ), 
        ChangeNotifierProvider(
          create: (ctx) => Cart(),
        ),
        ChangeNotifierProvider(
          create: (ctx) =>
              Orders(), 
        ),
      ],
      child: MaterialApp(
        title: 'MyShop',
        theme: ThemeData(
          primarySwatch: Colors.purple,
          accentColor: Colors.red,
          fontFamily: 'Lato',
        ),
        home: ProductsOverviewScreen(),
        routes: {
          ProductDetailsScreen.routeName: (ctx) => ProductDetailsScreen(),
          CartScreen.routeName: (ctx) => CartScreen(),
          OrdersScreen.routeName: (ctx) => OrdersScreen(),
          UserProductsScreen.routeName: (ctx) => UserProductsScreen(),
          EditProductScreen.routeName: (ctx) => EditProductScreen(),
        },
      ),
    );
  }
}

I do think it is in Edit Product Screen as when I click add product the error shows up.It was working fine before so add button does not has any issue:

Edit Product Screen:

class EditProductScreen extends StatefulWidget {
  static const routeName = '/edit-product';
 

  @override
  _EditProductScreenState createState() => _EditProductScreenState();
}

class _EditProductScreenState extends State<EditProductScreen> {
  final _priceFocusNode = FocusNode(); //
  final _descriptionFocusNode = FocusNode();

  final _imageuRL = TextEditingController();
  final _imageUrlFocusNode = FocusNode();
  var _editedProduct =
      Product(description: '', id: '', imageUrl: '', price: 0, title: '');
  var isInit = true;
  var _initValues = {
    'title': '',
    'description': '',
    'price': '',
    'imageURL': '',
  };
  final _form = GlobalKey<
      FormState>(); 

  @override
  void initState() {
    _imageUrlFocusNode.addListener(
        _updateImageUrl); 

    super.initState();
  }

  @override
  void didChangeDependencies() {
    if (isInit) {
      final productID = ModalRoute.of(context)!.settings.arguments as String;
      if (productID != null) {
        _editedProduct =
            Provider.of<Products>(context, listen: false).findById(productID);
        _initValues = {
          
          'title': _editedProduct.title,
          'description': _editedProduct.description,
          'price': _editedProduct.price.toString(),

          // 'imageUrl': _editedProduct.imageUrl,
        };
        _imageuRL.text = _editedProduct.imageUrl;
      }
    }
    isInit = false;

    super.didChangeDependencies();
  }

  @override
  void dispose() {
    //should be used with the focusnodes to avoid memory leak

    _imageUrlFocusNode.removeListener(_updateImageUrl);
    _priceFocusNode.dispose();
    _descriptionFocusNode.dispose();
    _imageuRL.dispose();
    _imageUrlFocusNode.dispose();

    super.dispose();
  }

  void _updateImageUrl() {
    if (!_imageUrlFocusNode.hasFocus) {
      setState(() {});
    }
  }

  void _saveForm() {
    final isValid =
        _form.currentState!.validate(); 
    if (!isValid) {
      return;
    }
    _form.currentState!.save(); //this will save the form  ;
    if (_editedProduct.id != '') {
      Provider.of<Products>(context, listen: false)
          .updateProduct(_editedProduct.id, _editedProduct);
    } else
      Provider.of<Products>(context, listen: false).addProduct(
          _editedProduct);
    Navigator.of(context).pop();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Edit Title'), actions: [
        IconButton(onPressed: _saveForm, icon: Icon(Icons.save_alt))
      ]),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _form, 

          child: ListView(
            children: [
              TextFormField(
                initialValue: _initValues['title'],
                decoration: InputDecoration(
                  labelText: 'Title',
                ),
                textInputAction: TextInputAction.next,
                onFieldSubmitted: (_) {
                  FocusScope.of(context).requestFocus(
                      _priceFocusNode); 
                },
                validator: (value) {
                  if (value!.isEmpty) {
                   
                    return 'Please put in a value';
                  }
                  return null;
                },
                onSaved: (value) {
                  _editedProduct = Product(
                      description: _editedProduct.description,
                      id: _editedProduct.id,
                      imageUrl: _editedProduct.imageUrl,
                      price: _editedProduct.price,
                      isFavourite: _editedProduct.isFavourite,
                      title: value
                          .toString()); 
                },
              ),
              TextFormField(
                initialValue: _initValues['price'],
                decoration: InputDecoration(
                  labelText: 'Price',
                ),
                textInputAction: TextInputAction.next,
                keyboardType:
                    TextInputType.number, 
                focusNode: _priceFocusNode,
                validator: (value) {
                  if (value!.isEmpty) {
                    
                    return 'Please put in a value';
                  }
                  if (double.tryParse(value) == null) {
                    return "Please enter a valid number";
                  }
                  if (double.parse(value) <= 0) {
                    return "A number greater than 0";
                  }
                  return null;
                },

                onFieldSubmitted: (_) {
                  FocusScope.of(context).requestFocus(
                      _descriptionFocusNode); 
                },
                onSaved: (value) {
                  _editedProduct = Product(
                      description: _editedProduct.description,
                      id: _editedProduct.id,
                      imageUrl: _editedProduct.imageUrl,
                      price: double.parse(value.toString()),
                      isFavourite: _editedProduct.isFavourite,
                      title: _editedProduct
                          .title);
                },
              ),
              TextFormField(
                initialValue: _initValues['description'],
                decoration: InputDecoration(
                  labelText: 'Description',
                ),
                maxLines:
                    3, 
                keyboardType: TextInputType.multiline,
                focusNode: _descriptionFocusNode,
                onSaved: (value) {
                  _editedProduct = Product(
                      description: value.toString(),
                      id: _editedProduct.id,
                      imageUrl: _editedProduct.imageUrl,
                      price: _editedProduct.price,
                      isFavourite: _editedProduct.isFavourite,
                      title: _editedProduct
                          .title); 
                },
                validator: (value) {
                  if (value!.isEmpty) {
                    
                    return 'Please put in a value';
                  }
                  if (value.length < 10) {
                    return 'should be atleast 10 char long';
                  }
                  return null;
                },
              ),
              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: _imageuRL.text.isEmpty
                        ? Text('Enter a Url')
                        : FittedBox(
                            child: Image.network(_imageuRL.text),
                            fit: BoxFit.cover,
                          ),
                  ),
                  Expanded(
                    child: TextFormField(
                      
                      decoration: InputDecoration(labelText: 'Image Url'),
                      keyboardType: TextInputType.url,
                      textInputAction: TextInputAction.done,

                      focusNode: _imageUrlFocusNode,
                      onFieldSubmitted: (_) {
                        _saveForm();
                      },
                      onSaved: (value) {
                        _editedProduct = Product(
                            description: _editedProduct.description,
                            id: _editedProduct.id,
                            imageUrl: value.toString(),
                            price: _editedProduct.price,
                            isFavourite: _editedProduct.isFavourite,
                            title: _editedProduct
                                .title); 
                      },
                      controller:
                          _imageuRL,
                      
                    ),
                  ),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

Thanks in advance !! As I am new to flutter so I did not understand how to solve it.

Solution

I am not absoluteley sure what the problem is, but if I had to guess, i’d say this line:

      final productID = ModalRoute.of(context)!.settings.arguments as String;

is the most likely one to be the culprit, if that is the case, hopefully this specific error can be fixed by changing the line as follows:

      final productID = ModalRoute.of(context)!.settings.arguments as String?;

So basically I just added a question mark (?) after String, to let dart know that the value might be null

As I said, I am not sure it will solve your issue, but it hopefully will, if it doesn’t it might be helpful for you to show on what line the error occurs?

Answered By – h8moss

Answer Checked By – Marilyn (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *