NoSuchMethodEror: tried to call a non-function, such as null:

Issue

I have this code which works well on android emulator but gives error on web.

import 'package:parivaar/components/screens/home/Home.dart';

typedef T Constructor<T>();

final Map<String, Constructor<Object>> _constructors =
    <String, Constructor<Object>>{};

void register<T>(Constructor<T> constructor) {
  _constructors[T.toString()] = constructor;
}

class ClassBuilder {
  static void registerClasses() {
    register<Home>(() => Home());
  }

  static dynamic fromString(String type) {
    return _constructors[type]();
  }
}

And i am calling that function as follows:

class _MyHomePageState extends State {
KFDrawerController _drawerController;

  @override
  void initState() {
    super.initState();
    _drawerController = KFDrawerController(
      initialPage: ClassBuilder.fromString('Home'),
.
..
...
....

Solution

You are probably assuming that T.toString() returns the source name of the type as a string. Nobody ever promised that.
It works on native, but on the web you often optimize for size and "minification" turns all the long names into shorter names. With that, the name of the type Home is no longer the string "Home".

I generally do not recommend depending on the string representation of types (or Type objects for that matter).

Consider changing register and fromString to:

void register<T>(Constructor<T> constructor) {
  _constructors[T] = constructor;
}

and

  static T fromType<T>() => _constructors[T]();

That relies on Type object equality, which is a well-defined operation.
Not perfect, but still better than going through strings.

If you need to create the objects dynamically from strings, where you don’t know the type, then I’d instead require you to provide the key string on registration, changing register to:

void register<T>(String key, Constructor<T> constructor) {
  _constructors[key] = constructor;
}

and register types like:

static void registerClasses() {
  register<Home>("Home", () => Home());
}

Answered By – lrn

Answer Checked By – Timothy Miller (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.