Subtle Flutter mistake I made today

and how you can avoid it

These days I'm busy creating AppFeedback in Flutter web. The experience has been frictionless.

One of the subtle mistakes I made was, while binding to button onPressed handler.

Normally it looks like this.

IconButton( onPressed: () { print("tag** pressed"); } )

Now when the handler gets too heavy, naturally you want to move that to a function. A contrived version of it looks like this:

_handleTagButtonPressed(){ print("tag** pressed"); }

With this, the mistake I made was to do the following:

IconButton( onPressed: _handleTagButtonPressed() )

Can you guess what the problem is and what it does?

The _handleTagButtonPressed() gets executed when the widget builds. This is because onPressed expects to be bound to a lambda, but what I've provided is a function, and Dart will execute that function at widget build time (runtime) and assign the value returned. Since _handleTagButtonPressed() is returning null, the button gets disabled (as it should be).

How to correct this:

IconButton( onPressed: _handleTagButtonPressed )

Notice the lack of () at the end of _handleTagButtonPressed. This makes the method (which is a lambda) bind to onPressed at the compile time. If you want to be pedantic, the _handleTagButtonPressed should be declared to return void. When a return value is not specified, it assumed to be dynamic unlike other C based programming languages.