3

I'm quite new to Flutter and to learn "best practice" I loaded up the new skeleton example app.

You get three example items in a list view and when you click on one of them you go to a details view. I want to pass the object so that for every example item there is a custom details view. So I changed the code to the following:

ListTile(
        leading: const FlutterLogo(),
        title: Text(myObject.name),
        onTap: () {
          Navigator.restorablePushNamed(
              context, ObjectDetailView.routeName,
              arguments: myObject);
        },
        trailing: const Icon(Icons.arrow_forward_ios_rounded),

But it shows the error: The arguments object must be serializable via the StandardMessageCodec.

How can I do it? This seems quite complicated for an "example app". Does it make sense to use restorablePushNamed() on a details page? Or should I switch to the "normal" push/pop-Method.

Tim4497
  • 340
  • 3
  • 19
  • Could you provide more information about your object being used as an argument? – Apealed Oct 19 '21 at 19:04
  • 1
    Using `restorablePushNamed` should be a fine implementation, but I suggest taking a look at the [`StandardMessageCodec` class](https://api.flutter.dev/flutter/services/StandardMessageCodec-class.html). So you need a "primative-like" object to be an argument in your route. I recommend converting it as a `Map` if possible, for the sake of the argument. Something along the lines of `myObject.toMap()` should suffice. – Apealed Oct 19 '21 at 19:09

1 Answers1

2

It does makes sense to use restorablePushNamed() or any other restorable push method if you want to preserve the current page and the state of the app when it's killed by the operating system while running in the background (on low memory condition, for example).

It's up to you decide if this is necessary in your app, otherwise, you can just use "normal" push methods without needing to serialize the arguments.

But to use State Restoration, you'll have to convert myObject to a Map or List in order to StandardMessageCodec serialize it, as @Apealed said in the comments.

To convert it to a map. you can do something like this in your class:

Map<String, dynamic> toMap() {
  return {
    "name": this.name,
    "property2": this.property2,
    ...
  };
}

You can check more info about it on documentation: flutter.dev/go/state-restoration-design

Samuel T.
  • 194
  • 3
  • 13
  • hey @Samuel, what happens when `property2` is another object/class? I've applied your solution with a class with properties and it works, but i'm trying to figure out how to solve with nested classes/objects. I also created a `toMap` in the nested class, but it doesn't seems to help. Could you help me out? I'm new in flutter... – awdk Mar 22 '23 at 11:32
  • ok, I found the my problem: I had to serialise correctly an enum value as a string. Other than that, using the nested object.toMap() worked fine. ``` Map toMap() { return { 'item': item.toMap(), }; } ``` and later the `Item` had its own `toMap`: ``` Map toMap() { return { 'id': id, // ... }; } ``` thank you @Samuel for your original answer :) – awdk Mar 22 '23 at 11:54
  • Nice! Good to know that nested objects works fine – Samuel T. Mar 22 '23 at 12:31