Flutter BlocProvider "The parameter 'key' can't have a value of 'null' because of its type, but the implicit default value is 'null'"

Viewed 209

I have previously working code for over a year, but have recently been forced to upgrade underlying flutter components and am now getting new errors. Previous code:

import 'package:flutter/material.dart';

Type _typeOf<T>() => T;

abstract class BlocBase {
  void dispose();
}

class BlocProvider<T extends BlocBase> extends StatefulWidget {
  BlocProvider({
    Key key,
    @required this.child,
    @required this.bloc,
  }) : super(key: key);

  final Widget child;
  final T bloc;

  @override
  _BlocProviderState<T> createState() => _BlocProviderState<T>();

  static T of<T extends BlocBase>(BuildContext context) {
    final type = _typeOf<_BlocProviderInherited<T>>();
    _BlocProviderInherited<T> provider =
        context.ancestorInheritedElementForWidgetOfExactType(type)?.widget;
    return provider?.bloc;
  }
}

class _BlocProviderState<T extends BlocBase> extends State<BlocProvider<T>> {
  @override
  void dispose() {
    widget.bloc?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new _BlocProviderInherited<T>(
      bloc: widget.bloc,
      child: widget.child,
    );
  }
}

class _BlocProviderInherited<T> extends InheritedWidget {
  _BlocProviderInherited({
    Key key,
    @required Widget child,
    @required this.bloc,
  }) : super(key: key, child: child);

  final T bloc;

  @override
  bool updateShouldNotify(_BlocProviderInherited oldWidget) => false;
}

I am getting several errors here now, initially at these three lines:

Key key,
@required this.child,
@required this.bloc,

Which all state the same error:

The parameter can't have a value of 'null' because of its type, but the implicit default value is 'null'.

I am not really sure what this wants from me. Does anyone have any idea?

Edit:

Additional code issue for anyone reading this later, as discussed with Mohan below.

static T of<T extends BlocBase>(BuildContext context) {
  final type = _typeOf<_BlocProviderInherited<T>>();
  _BlocProviderInherited<T> provider =
      context.ancestorInheritedElementForWidgetOfExactType(type)?.widget;
  return provider?.bloc;
}

It has an issue with this line:

context.ancestorInheritedElementForWidgetOfExactType(type)?.widget;

And suggests I replace it with: "getElementForInheritedWidgetOfExactType" but then if I do this, it gets upset saying:

A value of type 'InheritedWidget?' can't be assigned to a variable of type '_BlocProviderInherited<T>'.
Try changing the type of the variable, or casting the right-hand type to '_BlocProviderInherited<T>'.

And also has an issue with this line:

return provider?.bloc;

Suggesting I can make the return type nullable by changing the first line to this:

static T? of<T extends BlocBase>(BuildContext context) {

So just adding that question mark in there... which it seems happy with but I am not sure if this is correct.

1 Answers

After flutter 2.0 (Null safety), You need to either pass non-null values or specify that parameter is nullable,

here in your case, you need to mention key as nullable

Key? key, // add '?' here, which tells it can be nullable.

Also after 2.0 you dont need to add @ to required it can be

required
Related