Home > Software engineering >  Using Provider in Parent and Child cause Null check operator used on a null value Error
Using Provider in Parent and Child cause Null check operator used on a null value Error

Time:10-10

I get the following error when I use a Provider in my ProductsScreen.dart.

Null check operator used on a null value

The relevant error-causing widget was:
  ProductsScreen

My ProductsScreen contains another Widget called ProductsList which uses another Provider.

The error only occurs when I am use Provider in both my parent 'ProductsScreen' and child 'ProductsList'.

When I am using Provider in my other screens that don't contain children that uses Provider, it works fine

May I know what is the reason for such an error? What should I do to use 2 Providers - one in the parent and one in the child widget? or is that not possible? Thanks

Below are snippets of my code...

ProductsScreen

class _ProductsScreenState extends State<ProductsScreen> {
  @override
  Widget build(BuildContext context) {
    model.User user = Provider.of<UserProvider>(context).getUser;

    return Stack(
      children: const [
        // Text(user.email),
        SizedBox(
          height: 20,
        ),
        ProductsList()
      ],
    );
  }
}

ProductsList

class ProductsList extends StatelessWidget {
  const ProductsList({super.key});

  @override
  Widget build(BuildContext context) {
    final productsData = Provider.of<Products>(context);
    print(productsData);
    final products = productsData.items;

    return Center(
      child: ListView.builder(
        itemCount: products.length,
        // 198 Nested Models & Providers
        itemBuilder: (context, index) => ChangeNotifierProvider.value(
            value: products[index], child: const ProductItem()),
        //value: products[index], child: ProductItem(id: products[index].id)),
      ),
    );
  }
}

UserProvider

class UserProvider with ChangeNotifier {
  User? _user;
  final AuthMethods _authMethods = AuthMethods();

  User get getUser => _user!;

  Future<void> refreshUser() async {
    User user = await _authMethods.getUserDetails();
    _user = user;
    notifyListeners();
  }
}

About (Working Fine)

class About extends StatelessWidget {
  static const routeName = '/about';

  const About({super.key});

  @override
  Widget build(BuildContext context) {
    model.User user = Provider.of<UserProvider>(context).getUser;
    return Center(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(user.email),
        const Text('Yup'),
      ],
    ));
  }
}

Products Provider

import 'package:flutter/material.dart';

import './product.dart';

class Products with ChangeNotifier {
  final List<Product> _items = [
    Product(id: '1', price: 10, isFavorite: false),
    Product(id: '2', price: 20, isFavorite: false),
    Product(id: '3', price: 50, isFavorite: true)
  ];

  List<Product> get items {
    return [..._items];
  }

  void addProduct() {
    // _items.add(value);
    notifyListeners();
  }
}

Main.dart (Snippet)

return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => UserProvider(),
        ),
        ChangeNotifierProvider(
          create: (_) => Products(),
        ),
      ],

CodePudding user response:

Are you sure of these lines :

final productsData = Provider.of<Products>(context);
print(productsData);
final products = productsData.items;

Do Products have items ?? Or you need to call some function to fill the items list with data

CodePudding user response:

You need to use MultiProvider and wrap the stack in ProductsScreen with it

return MultiProvider(
      providers: [..],
      child: Stack());

CodePudding user response:

If the method getUser returns null, then this line will originate that error because you are using Null check operator ! on Null value:

// class UserProvider
User get getUser => _user!;

You must be sure null never happens or you could change this to:

User? get getUser => _user;

And update:

// class About
model.User? user = Provider.of<UserProvider>(context).getUser;
  • Related