dwyl / app

Clear your mind. Organise your life. Ignore distractions. Focus on what matters.
http://dwyl.github.io/app/
143 stars 22 forks source link

Question: Adding Bloc #320

Closed LuchoTurtle closed 10 months ago

LuchoTurtle commented 1 year ago

Integrating Bloc has been previously discussed/recommended in previous standups and discussions. As the development of the app continues, I think integrating this ASAP makes increasingly more sense so as to not incur technical debt in the future.

Using Bloc as a state manager has its advantages, even with testability. Comparing it with Riverpod and Provider. The community seems to lean on the side of using Bloc. Although it may be more verbose (which can be countered with "being more readable), it's opinionated, which may be seen as "bad" or "too restrictive" for some, but I believe it's great for someone that is starting and it's essentially following guidelines from more experienced developers.

I've done Riverpod in https://github.com/dwyl/flutter-todo-list-tutorial. I've done Provider in https://github.com/dwyl/flutter-stopwatch-tutorial. I feel like we should tick the box with Bloc on this one.

The issue of persistence was inclusively discussed today. By adding Block, we can easily integrate this feature with HydrateBloc.

@nelsonic @SimonLab any opinions?

SimonLab commented 1 year ago

I'm happy to try Bloc. I haven't really use it before so you have more experience with it @LuchoTurtle and I trust your judgment on this for state management, especially if it's easier to use than other tools

LuchoTurtle commented 1 year ago

It's not necessarily easier, but opinionated. The project would follow the Bloc structure and it may help us along the line as we add more features to the app. Again, I've never used Bloc either but has been highly recommended by a friend that has worked/works with Flutter professionally. πŸ‘

nelsonic commented 1 year ago

@LuchoTurtle thank you very much for proactively opening this issue. πŸ‘Œ We definitely need to figure out what we are doing to store data on the device. πŸ’­ It's good to get recommendations from people using Bloc. πŸ‘ Bloc was covered in the Flutter TDD lessons we all followed a couple of years ago: https://github.com/dwyl/learn-flutter/issues/15 so both @SimonLab and I have some basic experience; it's obvs more advanced/polished now.

I've since taken T4h to do a reasonable deep dive into Bloc πŸ§‘β€πŸ’» βŒ› and I'm not against it. I watched a few videos on YT, e.g:

Bloc Library: Basics & Beyond - Felix Angelov: https://youtu.be/knMvKPKBzGE bloc-library

image

I'm not convinced we need "State Management" in our App. Dart and Flutter are inherently declarative and our use-case is pretty simple. We need to be very clear what we are building to avoid over-complicating things. Our App needs to save data on the device and sync it to the server when online using REST and WebSockets. Do we need Bloc to achieve that? πŸ’­ What is Bloc going to give us that will help our App have excellent UX?

Each new element (dependency) we add to our stack increases the onboarding time and learning curve for people to contribute to our App and incurs maintenance effort over time from the core team. This costs time == money so we need to have a compelling reason for it.

This website does not tell me very much: https://bloclibrary.dev

image image image

Examples:

image

For future reference, when proposing a particular technology / tool / library to your team, try to:

a) Describe the use-case that we have and what problems you have already faced. b) List the pros/cons of the proposed solution in as much detail as you can;

"My buddy uses it..." is good but not enough to make a €100k decision. c) Show some sample code e.g: https://bloclibrary.dev/#/fluttercountertutorial

This is described in: Technology Stack -> How to Propose NEW Tech/Tools?

The Bloc counter tutorial is way over-complicated. ⏳ There isn't an immediately obvious reason why a Counter would need a BlocObserver ... πŸ€·β€β™‚οΈ I get that this is meant to be a basic example to intro people to the topic, but it fails horribly to explain the need for "State Management". It ends up transforming the basic Flutter Counter into a monster. πŸ‘Ή

When I read the comments on the Reddit thread Lucho shared: https://www.reddit.com/r/FlutterDev/comments/wmh2oh/eli5_bloc_compared_to_providerriverpod/

flutter-bloc-reddit flutter-bloc-stockholm-syndrome

This feels like Stockhom Syndrome: https://en.wikipedia.org/wiki/Stockholm_syndrome The person is post-facto rationalising their "love" for bloc ... πŸ’­ I love my prison cell. It has 3 lovely walls and one with bars. I love bars. They make me feel safe. ❀️

Happy to use it if we have a compelling reason for it in our roadmap.

@LuchoTurtle please see: https://github.com/dwyl/flutter-bloc-tutorial/issues/1 πŸ™

nelsonic commented 1 year ago

@LuchoTurtle now that you've done a decent amount of learning Bloc: https://github.com/dwyl/flutter-bloc-tutorial How confident are you that it's a "good" choice for our App?

LuchoTurtle commented 1 year ago

To be honest, after fidgeting with Bloc, it made me even more undecided πŸ˜…

We've been comparing Riverpod and Bloc and, although they're usually bundled together in the same conversation, while I was implementing projects with both packages, I feel like they are compatible with each other and not strictly a "one or the other" choice.

Bloc is definitely a compact and opinionated state management library (that has blocs and cubits to store data)` which has its own **dependency injection "Provider-like" package.

Riverpod is mainly a dependency-injection library that has the StateNotifier class that can/is used in state management scenarios.

Dev experience

Bloc has much more boilerplate code. This might be good as everything is explicit and can be more discernible to what's going on when someone is onboarding. On the other hand, Riverpod can be used and edited with only ref.watch and ref.read, making it much less "boilerplatey" and simpler to write. So, for teams, Bloc makes sense because it forces devs to separate logic from the the UI. Riverpod is just simpler but make some ponder if it can scale properly? Is it more prone to spaghetti code in the future? I'm not entirely sure because I haven't used it on that scale.

Testing

Testing with both frameworks was easy.

With Riverpod, by default, every provider object can be overridden in testing scenarios. Since Riverpod is mainly a dependency-injection library, this is all you really need to have testing work properly.

On the other hand, Bloc offers its own bloc_test package for all the testing needs. Because when we use Bloc we separate services (e.g. RepositoryService), they can easily be mocked because they are part of the cubits/blocs which, in turn, can easily be tested with the aforementioned library.

Persisting state

This is where Bloc elevates itself when compared with Riverpod. The latter doesn't have any "official" way of persisting app state/provider objects. It does have some third-party plugins https://pub.dev/packages/riverpod_persistent_state, but unfortunately they're not actively maintained.

On the other hand, Bloc has the package hydrated_bloc, which allows for a persistent state across sessions.

A few notes

Granted, we've used Blocs in this project, when we could have used Cubits, which makes it easier to write and has less boilerplate too.

To be honest, I don't know the long-term effects of using either Riverpod or Bloc. We'll probably do fine with either one because the use case doesn't entail a complex state system. The former is simpler to write, while the latter is more "complete" and can be a better choice long-term-wise for teams developing the same project.

Perhaps Bloc should be chosen because it has an easier way of persisting state, which is something we definitively want.

But that's just my opinion! πŸ˜ƒ

nelsonic commented 1 year ago

@SimonLab if you've had a chance to read the https://github.com/dwyl/flutter-bloc-tutorial what are your thoughts on this?

nelsonic commented 11 months ago

@LuchoTurtle if you had to make a executive decision on this, would you adopt Bloc into the stack? πŸ’­ We need to make a call and move on ASAP. πŸ™

LuchoTurtle commented 11 months ago

I think so. I've detailed kind of the pros and cons before but, at least for this project's requirements, it makes more sense to go with Bloc because of the use of web sockets.

Mapping works well with web sockets because they have state (initial, connected, connecting, disconnected) that is caused by events (opened, closed, error), which are distinct from the states. BLoCs can be mapped to all of this without losing information, which is something that is useful to us.

nelsonic commented 11 months ago

@LuchoTurtle ok. Thanks. this is a more "I know what I'm doing" answer. πŸŽ‰ Given our set of requirements, Bloc appears to be a reasonable choice. My final question is: how much of a maintenance burden do we incur? Specifically how often have breaking/major changes been made that would require T1d worth of time? πŸ§‘β€πŸ’» ⏳ πŸ’Έ πŸ”₯ https://bloclibrary.dev/#/migration Considering they are going on V9 now, how often are major changes required? πŸ€·β€β™‚οΈ I cannot stand a "moving target" framework/platform. πŸ€¦β€β™‚οΈ

LuchoTurtle commented 11 months ago

bloc 8.0.0 was released less than 2 years ago.

image

They haven't yet released v9 (the v9 on the migration guide is related to the hydrated_bloc, which still, is something we'll eventually use). This should give you a fair timeframe of when breaking changes occur and we ought to migrate from one version to another.

Though @freitzzz could also give his opinion on this since he's been working with bloc for more time than I and surely has gone through a migration period at some point in his remarkable career.

freitzzz commented 11 months ago

bloc 8.0.0 was released less than 2 years ago.

image

They haven't yet released v9 (the v9 on the migration guide is related to the hydrated_bloc, which still, is something we'll eventually use). This should give you a fair timeframe of when breaking changes occur and we ought to migrate from one version to another.

Though @freitzzz could also give his opinion on this since he's been working with bloc for more time than I and surely has gone through a migration period at some point in his remarkable career.

Thanks for tagging me @LuchoTurtle :)

First of all, bloc library in my opinion should be the standard way to achieve state management in Flutter. The dev experience is just so awesome, because it just feels natural with the language constructors and style. I've never had issues with migrations, and just like @LuchoTurtle said, they are only going to reintroduce an API for HydratedBloc (cached blocs).

nelsonic commented 11 months ago

@freitzzz thanks for chiming in with your expert insight. ❀️

Please let us know if you’re available for hourly consulting, e.g: to review a couple of our Flutter PRs and help us ship this to the App/Play Store. πŸ™

freitzzz commented 11 months ago

@freitzzz thanks for chiming in with your expert insight. ❀️

Please let us know if you’re available for hourly consulting, e.g: to review a couple of our Flutter PRs and help us ship this to the App/Play Store. πŸ™

Sure! Could we chat via email or other channel, so I can know where to fit in?

freitzzz commented 11 months ago

@freitzzz thanks for chiming in with your expert insight. ❀️ Please let us know if you’re available for hourly consulting, e.g: to review a couple of our Flutter PRs and help us ship this to the App/Play Store. πŸ™

Sure! Could we chat via email or other channel, so I can know where to fit in?

@nelsonic sorry for the late reply, can I contact you via redacted?

nelsonic commented 11 months ago

@freitzzz you can always contact me via #{firstname}@#{githuborgname}.com" πŸ“§ but if you have Signal that's what I reply to fastest. πŸ’¬ (too much spam email means I only check it once a day...) ⏳

nelsonic commented 11 months ago

GOTO: https://github.com/dwyl/app/issues/337

nelsonic commented 11 months ago

PR: https://github.com/dwyl/app/pull/338

LuchoTurtle commented 10 months ago

Closing this issue as it's been discussed and #338 has already been merged πŸ‘Œ