Home > Enterprise >  Flutter. type 'Null' is not a subtype of type 'String' in type cast
Flutter. type 'Null' is not a subtype of type 'String' in type cast

Time:12-09

════════ Exception caught by widgets library ═══════════════════════════════════ The following _CastError was thrown building Builder: type 'Null' is not a subtype of type 'String' in type cast

The relevant error-causing widget was MaterialAppenter image description here

My code is attached. It's about Maxwell Udemy Course. Shop APP module. There is an error when I press on Add button in edit_product_screen. He record the course in 2019. I am facing this error. I can't find out the error. Anyone, please Solve the error.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/product.dart';
import '../providers/products.dart';

class EditProductScreen extends StatefulWidget {
  static const routeName = '/edit-product';
  const EditProductScreen({super.key});

  @override
  State<EditProductScreen> createState() => _EditProductScreenState();
}

class _EditProductScreenState extends State<EditProductScreen> {
  final priceFocus = FocusNode();
  final imageControl = TextEditingController();
  final form = GlobalKey<FormState>();
  var isInit = true;
  var initValues = {
    'title': '',
    'description': '',
    'price': '',
    'imageUrl': ''
  };
  var editProduct =
      Product(id: '', title: '', desc: '', imageUrl: '', price: 0.0);

  @override
  void dispose() {
    priceFocus.dispose();
    imageControl.dispose();
    super.dispose();
  }

  @override
  void didChangeDependencies() {
    if (isInit) {
      final productid = ModalRoute.of(context)!.settings.arguments as String;
      if (productid != null) {
        editProduct =
            Provider.of<Products>(context, listen: false).findById(productid);
        initValues = {
          'title': editProduct.title,
          'description': editProduct.desc,
          'price': editProduct.price.toString(),
          'imageUrl': '',
        };
        imageControl.text = editProduct.imageUrl;
      }
    }
    isInit = false;
    super.didChangeDependencies();
  }

  void formSave() {
    final valid = form.currentState!.validate();
    if (!valid) {
      return;
    }
    form.currentState!.save();
    if (editProduct.id != null) {
      Provider.of<Products>(context, listen: false)
          .updateProduct(editProduct.id, editProduct);
    } else {
      Provider.of<Products>(context, listen: false).addProduct(editProduct);
    }
    Navigator.of(context).pop();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Edit Product'),
        actions: [
          IconButton(onPressed: formSave, icon: const Icon(Icons.save))
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
            key: form,
            child: ListView(
              children: [
                TextFormField(
                  initialValue: initValues['title'],
                  decoration: const InputDecoration(labelText: 'Title'),
                  textInputAction: TextInputAction.next,
                  onFieldSubmitted: (_) {
                    FocusScope.of(context).requestFocus(priceFocus);
                  },
                  onSaved: (newValue) {
                    editProduct = Product(
                      id: editProduct.id,
                      title: newValue as String,
                      desc: editProduct.desc,
                      imageUrl: editProduct.imageUrl,
                      price: editProduct.price,
                      isFavorite: editProduct.isFavorite,
                    );
                  },
                  validator: (value) {
                    if (value!.isEmpty) {
                      return 'Enter Title';
                    }
                    return null;
                  },
                ),
                TextFormField(
                  initialValue: initValues['price'],
                  decoration: const InputDecoration(labelText: 'Price'),
                  textInputAction: TextInputAction.next,
                  keyboardType: TextInputType.number,
                  focusNode: priceFocus,
                  onSaved: (newValue) {
                    editProduct = Product(
                      id: editProduct.id,
                      title: editProduct.title,
                      desc: editProduct.desc,
                      imageUrl: editProduct.imageUrl,
                      price: double.parse(newValue as String),
                      isFavorite: editProduct.isFavorite,
                    );
                  },
                ),
                TextFormField(
                  initialValue: initValues['description'],
                  decoration: const InputDecoration(labelText: 'Description'),
                  textInputAction: TextInputAction.next,
                  maxLines: 3,
                  keyboardType: TextInputType.multiline,
                  onSaved: (newValue) {
                    editProduct = Product(
                      id: editProduct.id,
                      title: editProduct.title,
                      desc: newValue as String,
                      imageUrl: editProduct.imageUrl,
                      price: editProduct.price,
                      isFavorite: editProduct.isFavorite,
                    );
                  },
                ),
                Row(
                  children: [
                    Container(
                      height: 100,
                      width: 100,
                      margin: const EdgeInsets.only(top: 8, right: 10),
                      decoration: BoxDecoration(
                          border: Border.all(width: 1, color: Colors.grey)),
                      child: imageControl.text.isEmpty
                          ? const Center(child: Text('Enter Url'))
                          : FittedBox(
                              child: Image.network(
                                imageControl.text,
                                fit: BoxFit.cover,
                              ),
                            ),
                    ),
                    Expanded(
                      child: TextFormField(
                        decoration:
                            const InputDecoration(labelText: 'Image Url'),
                        textInputAction: TextInputAction.done,
                        keyboardType: TextInputType.url,
                        controller: imageControl,
                        onFieldSubmitted: (_) {
                          formSave();
                        },
                        onSaved: (newValue) {
                          editProduct = Product(
                            id: editProduct.id,
                            title: editProduct.title,
                            desc: editProduct.desc,
                            imageUrl: newValue as String,
                            price: editProduct.price,
                            isFavorite: editProduct.isFavorite,
                          );
                        },
                      ),
                    ),
                  ],
                ),
              ],
            )),
      ),
    );
  }
}

CodePudding user response:

Try to check in imageControl.text = editProduct.imageUrl; editProduct.imageUrl should not be null

CodePudding user response:

In your didChangeDependencies method you are instantiating a variable called productId and you are getting a value from ModalRoute.of(context).!.settings.arguments and casting as a String, but this value can be null, that is why you check if it`s null right after that line.

@override
  void didChangeDependencies() {
    if (isInit) {
      final productid = ModalRoute.of(context)!.settings.arguments as String;
      if (productid != null) {
        editProduct =
            Provider.of<Products>(context, listen: false).findById(productid);
        initValues = {
          'title': editProduct.title,
          'description': editProduct.desc,
          'price': editProduct.price.toString(),
          'imageUrl': '',
        };
        imageControl.text = editProduct.imageUrl;
      }
    }
    isInit = false;
    super.didChangeDependencies();
  }

So you can just cast to a nullable string and I think your problem is solved

final productid = ModalRoute.of(context)!.settings.arguments as String?;
  • Related