需要一个 'String' 类型的值,但得到一个 'Null' 类型的值。这是一个电子商务应用程序

Posted

技术标签:

【中文标题】需要一个 \'String\' 类型的值,但得到一个 \'Null\' 类型的值。这是一个电子商务应用程序【英文标题】:Expected a value of type 'String', but got one of type 'Null' . This is for an eCommerce app需要一个 'String' 类型的值,但得到一个 'Null' 类型的值。这是一个电子商务应用程序 【发布时间】:2022-01-10 09:15:30 【问题描述】:

我在 main.dart 中遇到了这个错误,但我认为它没有任何问题。

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(),
        ,
      ),
    );
  

我确实认为它在编辑产品屏幕中,因为当我单击添加产品时出现错误。之前它工作正常,所以添加按钮没有任何问题:

编辑产品屏幕:

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,
                      
                    ),
                  ),
                ],
              )
            ],
          ),
        ),
      ),
    );
  

提前致谢!!由于我是新手,所以我不明白如何解决它。

【问题讨论】:

【参考方案1】:

我不确定问题是什么,但如果我不得不猜测,我会说这行:

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

最有可能是罪魁祸首,如果是这种情况,希望可以通过如下更改该行来修复此特定错误:

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

所以基本上我只是在String之后添加了一个问号(?),让dart知道该值可能是null

正如我所说,我不确定它是否会解决您的问题,但希望它会解决您的问题,如果没有的话,显示错误发生在哪一行可能会对您有所帮助?

【讨论】:

谢谢!有效。我不知道这个,所以也谢谢你教这个!! 很高兴它对您有所帮助^^您介意将我的答案标记为已接受,以便我得到一些分数:)吗?

以上是关于需要一个 'String' 类型的值,但得到一个 'Null' 类型的值。这是一个电子商务应用程序的主要内容,如果未能解决你的问题,请参考以下文章

需要一个“String”类型的值,但得到一个“Null”类型的值

如何修复 Flutter 需要一个“Map<String, dynamic>”类型的值,但得到一个“List<dynamic>”类型的值

需要一个“int”类型的值,但得到了 list<Map<string, dynamic>> 类型之一

错误:需要一个“String”类型的值,但在新的 note.Note.fromJson 中得到一个“Null”类型的值

需要一个“Widget”类型的值,但得到一个“Null”类型的值,颤动

Flutter 'showDatePicker' 抛出异常:错误:预期值为 'String' 类型,但得到类型为 'Null' 的值之一