dropbear-software / todart

Example full stack Dart research project of a very over engineered Todo list application
MIT License
0 stars 1 forks source link

Consider using Streams to handle things like user action events. #25

Open mark-dropbear opened 3 years ago

mark-dropbear commented 3 years ago

As an example when you take a look at the ProjectsListView widget you will find code like this:

Widget _showProjects(BuildContext context, List<Project> projects) {
    return ListView.builder(
      itemCount: projects.length,
      itemBuilder: (BuildContext context, int index) {
        return GestureDetector(
          onTap: () {
            GoRouter.of(context).go('/project/${projects[index].resourceName}');
          },
          child: Padding(
            padding: EdgeInsets.only(top: index == 0 ? 12 : 0, bottom: 12),
            child: _projectCard(context, project: projects[index]),
          ),
        );
      },
    );
  }

Which says when a user taps on this widget, send them to this new route.

This forces my widget to take a dependency on the go_router package which seems like a lot. I'm not sure what the correct Flutter way would normally be to handle this but in other frameworks I have played around with like Lit the recommended approach here would be to make use of the browsers native event model and just fire an event that says something like the user clicked this particular widget which would bubble up the tree and another class would be responsible for saying listen for this particular kind of event and whenever you receive one then do this particular bit of logic (i.e. send them to the new page)

So now in that scenario the widget would not have this unnecessary dependency on the router any more. It would just take in a ListProjectsResponse (independently of how that was gotten i.e. so no networking concerns to worry about) and is just responsible for firing events.

My quick bit of Googling suggests some things here might be helpful like Streams and I even got the impression that this was literally the foundation that a bunch of state management solutions were built on top of like Bloc and possibly even Riverpod?

Anyways, take a look at what is out there that would make this possible and figure out a way to remove this dependency if possible.

RandalSchwartz commented 3 years ago

You can certainly use a StreamProvider as an event bus. Widgets that manage the current page can ref.watch the StreamProvider to be updated. Code that wants to change the current page can access theProvider.stream.add to publish an event.

Edit: not quite right, but I know there's a way. I'm going back to sleep now. :)