In Freezed is it possible to create union cases from already existing freezed dataclasses

1.3k Views Asked by At

I am using the freezed package to create my json parsers and data classes. As of now I am using dartz's package to create Union cases and handle them in Flutter widgets. For example some of my Union classes looks like the following.

Either<ApiFailure,ModelA> apiResult1;
Either<ApiFailure,ModelB> apiResult2;

and I use them in my flutter widget's builder by folding them and returning specific widget for each cases. For example.

return apiResul1.fold<Widget>(
  (left) => ErrorWidget(),
  (right) => SuccessWidget(),
);

I created ApiFailure, ModelA, and ModelB as data classes using the freezed package. I understood freezed comes with a similar Union class support like dartz where we can define union cases. So I tried using them as follows and based on my initial understanding it is not possible to achieve the following using the already existing data classes for eg. ModelA andApiFailure`.

@freezed
abstract class ApiResult1 with _$ApiResult1{
  const factory ApiResult1.modelA() =  ModelA;
  const factory ApiResult1.apiFailure() =  ApiFailure;
}

@freezed
abstract class ApiResult2 with _$ApiResult1{
  const factory ApiResult2.modelB() =  ModelB;
  const factory ApiResult2.apiFailure() =  ApiFailure;
}

Notice that in the above two union classes I am redefining ApiFailure in ApiResult2 which is what I am trying to Avoid.

Question: Is it possible to utilize existing dataclasses to build a union class so that I don't have to make multiple changes just to change the structure of ApiFailure object. Hope my question is clear.

1

There are 1 best solutions below

0
On

Why not use your data classes as parameters?

@freezed
abstract class ApiResult1 with _$ApiResult1 {
  const factory ApiResult1.model(ModelA model) = _ModelA;
  const factory ApiResult1.failure(ApiFailure failure) = _ApiFailure1;
}

@freezed
abstract class ApiResult2 with _$ApiResult2 {
  const factory ApiResult2.model(ModelB model) = _ModelB;
  const factory ApiResult2.failure(ApiFailure failure) = _ApiFailure2;
}

Then you can do

  return apiResult1.when(
    model: (model) => SuccessWidget(),
    failure: (failure) => ErrorWidget(),
  );