25

I have this constructor in my class. Now when it's like this, I get

The type parameter icon is annotated with @required
but only named parameters without default value can be annotated with it.

-

const Category(
    @required this.name,
    @required this.icon,
    @required this.color
  ) : assert(name != null),
      assert(icon != null),
      assert(color != null);

And when calling the constructor like this:

        Category(name: _categoryName, icon: _categoryIcon, color: _categoryColor),

It's an error.

All of this goes away when I surround my constructor arguments with {}.

What does this mean?

MAA
  • 1,294
  • 3
  • 18
  • 34

3 Answers3

39

{} are missing to make them named parameters

const Category({
    @required this.name,
    @required this.icon,
    @required this.color
  }) : assert(name != null),
      assert(icon != null),
      assert(color != null);

or just remove @required

Without {} they are positional parameters which are required anyway.

Category('foo', someIcon, Colors.white)

vs

Category(name: 'foo', icon: someIcon, color: Colors.white)

[] makes them optional positional parameters.

Positional (non-optional) need to be declared first, optional parameters come at the end.

Optional positional and optional named parameters can not be used together.

Optional parameters (positional and named) can have default values

this.name = 'foo'

Default values need to be compile-time constants.

lrn
  • 64,680
  • 7
  • 105
  • 121
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • So does named parameters mean that I must be call them with the names? Also my understanding of the required decorator is that it makes not passing the parameter an error, which seems like a no brainer to me and I like defensively forcing myself to adhere to stuff. Is my understanding correct? – MAA May 19 '18 at 18:52
  • See my updated answer – Günter Zöchbauer May 19 '18 at 18:53
8

You have used named optional arguemnts but your constructor accept postional optional parameter.

named optional parameter {}:

  1. Use to omit/avoid arguments and for readability.
  2. argument position doesnt matter since refer using name.
  3. Since you can avoid the argument, to denote that this argument is required use @required. Most of the time this annotation use to say this is cannot avoid(like a notice).

const Category({
    @required this.name,
    @required this.icon,
    @required this.color
  }) : assert(name != null),
      assert(icon != null),
      assert(color != null);

//Category(name: _categoryName, icon: _categoryIcon, color: _categoryColor),

positional optional parameter []:

  1. Also use to avoid or omit args.
  2. Cannot mention name because of that no readability(as a example for boolean params).
  3. Argument position matters.
  4. No need of @required because we must provide args.

const Category(
    this.name,
    this.icon,
    this.color
  ) : assert(name != null),
      assert(icon != null),
      assert(color != null);

//Category(_categoryName, _categoryIcon, _categoryColor),

Read more from this SO answer.

Blasanka
  • 21,001
  • 12
  • 102
  • 104
1

@required is a hint that some value should be passed as an argument to this parameter, even if it's just the default.

This hint only makes sense when used with optional parameters, such as when you surround the parameters with braces, because otherwise arguments are mandatory anyways (like what you would be used to in e.g. java.

Naming is a bit unfortunate here but named parameters in dart also mean they're optional, you can call a function without any of them.

Edman
  • 5,335
  • 29
  • 32
  • I'd be lying if I said I understood this :). Why named parameters are optional at the same time. I thought I was past the point when arguments were confusing, but then Dart comes along :). Thank your for your answer Edman. – MAA May 19 '18 at 19:04
  • They are (always) optional because *named* and *positional* parameters are two available syntaxes for defining **optional** parameters. While **required** parameters are always just positional **and** listed first. [From *Functions* docs](https://www.dartlang.org/guides/language/language-tour#functions): `The required parameters are listed first, followed by any optional parameters. Named optional parameters can also be marked as @required.` – Kamafeather Sep 03 '18 at 13:25