I Used late Instead of late final, and It Broke My App Later!
Md. Al-Amin

Md. Al-Amin @alaminkarno

About: Experienced Android Developer with a demonstrated history of working for the IT industry. Skilled in JAVA, Dart, Flutter, and Teamwork.

Location:
Dhaka, Bangladesh
Joined:
Oct 25, 2022

I Used late Instead of late final, and It Broke My App Later!

Publish Date: Jul 1
0 0

It was 1:30 AM. I was staring at the screen, wondering “Why is this value changing?

I didn’t write code to change it. I was sure. But somehow… it did.

That’s when I realized
I used late.
But I should’ve used late final.


The Context: A Simple User Controller

Let me explain.

I had a controller that fetched user data from the server when the app started. Here’s what it looked like:

class UserController {
  late User user;

  Future<void> loadUser() async {
    user = await userService.getCurrentUser();
  }
}

Enter fullscreen mode Exit fullscreen mode

So far, so good.

Now in the rest of the app, I used userController.user.name, userController.user.email, etc. confidently assuming this value would stay the same.

But I made one tiny mistake:
I used late instead of late final.


The Bug: Value Got Replaced Silently

After a few days, a new developer joined and added a “Refresh Profile” button that called loadUser() again.

So, what happened?

The user variable got replaced with new data, and in some parts of the app things started breaking subtly:

  • Analytics logs had inconsistent user IDs.
  • Cache was overwritten.
  • Some values were missing.

It wasn’t a big crash just small, silent chaos.
And it took me hours to figure out why.


The Root Cause: late is Not Read-only

When we write:

late User user;
Enter fullscreen mode Exit fullscreen mode

We’re saying:

“I will assign this later, but I can assign it again too.”
So, this is valid Dart code:

late String name;
name = 'Alamin';
name = 'Karno'; // ✅ No error!
Enter fullscreen mode Exit fullscreen mode

But I didn’t want that.
In my case, the user should be assigned once and then locked.


The Fix: late final

I updated my code to:

class UserController {
  late final User user;

  Future<void> loadUser() async {
    user = await userService.getCurrentUser();
  }
}
Enter fullscreen mode Exit fullscreen mode

Now if someone tries this:

user = anotherUser; // ❌ BOOM! Compilation error!
Enter fullscreen mode Exit fullscreen mode

Dart says:

“Nope. This is final. You already assigned it once.”

And I sleep peacefully now.


Real Flutter Example

Imagine you’re building a screen that depends on one-time loaded data like this:

class ProductController {
  late final Product product;

  Future<void> fetchProduct() async {
    product = await api.getProduct();
  }
}
Enter fullscreen mode Exit fullscreen mode

In your widget:

Text(productController.product.name)
Enter fullscreen mode Exit fullscreen mode

If you mistakenly used late, someone could reassign it later and the UI would update with incorrect info or worse, inconsistent app behavior.


A Quick Comparison

  • `var - Regular values that can change
  • final - Fixed values known immediately
  • late - Delayed but changeable (risky!)
  • late final - Delayed and locked after 1st set

When to Use late final

Use late final when:

  • The value will be set later (e.g., async calls, initState, etc.)
  • It must not change again.
  • You want to protect your variable from accidental reassignment.

Friendly Advice

If you ever write this:

late SomeType something;

Ask yourself:

“Will this value change after it’s set?”

If the answer is ❌ No
Just write:

late final SomeType something;

It’s safer. Cleaner. And future you will thank you.


Final Words

We don’t always break our app with big mistakes.
Sometimes, it’s just one small word:

late instead of late final.

From that day on, I started using late final in almost all of my controllers, models, and services unless I really needed to change the value later (which is rare).

So yeah, don’t ignore this little trick. It might just save your next release.

Comments 0 total

    Add comment