TSR
TSR

Reputation: 20647

Dart assert if not null in constructor

How to assert if a parameter is not null in a Dart constructor?

const CardStackCarousel({
    Key key,
    this.itemBuilder,
    this.itemCount,
    int backgroundItemCount,
    this.controller,
    this.offsetAboveBackcards: 10.0,
    this.minScale: 0.8,
    this.verticalAxis: false,
  })  : backgroundItemCount = backgroundItemCount == null ? itemCount - 1 : backgroundItemCount,
        assert(backgroundItemCount < itemCount, 'background item must be less than itemCount'),
        super(key: key);

With the code above, I am getting a error:

The method '<' was called on null.
Receiver: null

When the user does not specify the backgroundItemCount property. So my idea is maybe we should only assert if this property is not null. But I can't figure out how to do that

Upvotes: 2

Views: 5811

Answers (1)

Guilherme Matuella
Guilherme Matuella

Reputation: 2273

This is because you're not asserting a CardStackCarousel property - that probably have a backgroundItemCount as well - , you're asserting the argument that you're receiving through the constructor, which, by your logic, could be null.

When you call:

backgroundItemCount = backgroundItemCount == null ? itemCount - 1 : backgroundItemCount

You're not assigning a new value to the input received, you're probably saving it to a local property. What you're actually doing in the line above is:

this.backgroundItemCount = backgroundItemCount == null ? itemCount - 1 : backgroundItemCount

Which is why the assert fails, because it doesn't check the this.backgroundItemCount, it checks the properties received through the constructor, the backgroundItemCount.

I will cite a phrase from Dart official documentation:

Warning: The right-hand side of an initializer does not have access to this.

...

During development, you can validate inputs by using assert in the initializer list.

Which explains why you can't check this, because it's still "static" validating your inputs - at the moment of the right-side evaluation, it doesn't have the instance yet.


If you still need to make sure that the backgroundItemCount < itemCount, you should simply assert(backgroundItemCount == null || backgroundItemCount < itemCount, 'If background item is supplied, it must be less than itemCount').

Like so:

const CardStackCarousel({
    Key key,
    this.itemBuilder,
    this.itemCount,
    int backgroundItemCount,
    this.controller,
    this.offsetAboveBackcards: 10.0,
    this.minScale: 0.8,
    this.verticalAxis: false,
  })  : backgroundItemCount = backgroundItemCount == null ? itemCount - 1 : backgroundItemCount,
        assert(backgroundItemCount == null || backgroundItemCount < itemCount, 'If background item is supplied, it must be less than itemCount'),
        super(key: key);

Upvotes: 5

Related Questions