I’ve been using the new pattern matching from Dart 3 a lot since the release, and I want to share how much better the experience of writing Dart became for me. I completely replaced Freezed with Dart sealed classes, and they’re joyful to use too!

I love Dart!

  • mykl@lemmy.world
    link
    fedilink
    English
    arrow-up
    1
    ·
    1 year ago

    I completely replaced Freezed with Dart sealed classes

    Ooh is that a genuine option? Like if you were to model the same situation as in the Before/After example on their homepage, what would your code look like?

    • Problematic Consumer@lemmy.world
      link
      fedilink
      English
      arrow-up
      2
      ·
      1 year ago

      I have the same question. Using Dart native solutions and reducing code gen is definitely preferred but freezed isn’t easy to replace

      • fperson@lemmy.worldOPM
        link
        fedilink
        English
        arrow-up
        2
        ·
        1 year ago

        Replied above for a better comment hierarchy. Feel free to comment there if you have any questions/thoughts!

    • fperson@lemmy.worldOPM
      link
      fedilink
      English
      arrow-up
      1
      ·
      1 year ago

      Since there are too many examples on the freezed README and the one at the top isn’t a good use case to begin with (I like to keep my data models (DTOs) separate from entities, and DTOs are good enough with plain json_serializable), I’ll provide an example from one of the projects I’m currently working on. It is still more verbose than it would usually be with freezed, however, I’m pretty fine with that. Also, it’s worth noting that whenever I need a copyWith, I still use codegen with copy_with_extension. It has a nicer copyWith API and only handles that instead of a bunch of other stuff I don’t necessarily need.

      part of 'simply_browser_bloc.dart';
      
      sealed class SimplyBrowserState with EquatableMixin {
        const SimplyBrowserState();
      }
      
      class SimplyBrowserInitial extends SimplyBrowserState {
        const SimplyBrowserInitial();
      
        @override
        List<Object?> get props => const [];
      }
      
      class SimplyBrowserLoading extends SimplyBrowserState {
        const SimplyBrowserLoading({this.loadedSimplies});
      
        final List<Simply>? loadedSimplies;
      
        @override
        List<Object?> get props => const [];
      }
      
      class SimplyBrowserFailed extends SimplyBrowserState {
        const SimplyBrowserFailed(this.failure);
      
        final ApiFailure failure;
      
        @override
        List<Object?> get props => [failure];
      }
      
      class SimplyBrowserLoaded extends SimplyBrowserState {
        const SimplyBrowserLoaded({
          required this.canLoadMore,
          required this.simplies,
        });
      
        final bool canLoadMore;
        final List<Simply> simplies;
      
        @override
        List<Object?> get props => [simplies];
      }
      

      And then using the sealed class itself becomes super-nice, like the following snippet (only wrapped in a function to state clearly where the variable is coming from):

        List<Simply>? getSimplies(SimplyBrowserState state) {
          return switch (state) {
            SimplyBrowserLoading(:final loadedSimplies) => loadedSimplies,
            SimplyBrowserLoaded(:final simplies) => simplies,
            _ => null,
          };
        }
      
      • mykl@lemmy.world
        link
        fedilink
        English
        arrow-up
        1
        ·
        1 year ago

        Thanks, so not quite as concise as using freezed, but using plain old Dart is a very nice benefit.