Flutter: Retrieving top-level state from child returns null

TDLR: imports file only using

import 'package:myApp/path/myFile.dart';

Never with

import './myFile.dart';

This is due to how dart resolves imports.

You may have a single source file, but during builds, there is some kind of duplicates.

Let’s say you’re working on ‘myApp’. To import a file, you could do both :

  • import 'relativePath/myFile.dart'
  • import 'package:myApp/path2/myFile.dart'

You’d think that they point to the same file right?
But no. One of them will point to the original source. While the other one will point to a temporary file used for the build.

The problem comes when you start to mix both solutions. Because for the compiler, these two files are different. Which means that IApp imported from package:myApp/IApp is not equal to the same IApp imported from relativePath/myApp/IApp

In your case, you inserted in your widget tree an IApp from pakage:path but your IApp.of(context) use IAppState resolved locally.
They both have a different runtimeType. Therefore const TypeMatcher<IAppState>() won’t match. And your function will return null.


There’s an extremely easy way to test this behavior.
Create a test.dart file containing only

class Test {
}

then in your main.dart add the following imports :

import 'package:myApp/test.dart' as Absolute;
import './test.dart' as Relative;

You can finally test this by doing :

new Relative.Test().runtimeType == new Absolute.Test().runtimeType

Spoiler: the result is false

Leave a Comment