comigor/artemis

Add "freezed" feature to codegen

WDtms opened this issue · 2 comments

WDtms commented

Before reporting a bug, please test the beta branch!

Bug description

For now it's pretty hard to use generated classes from "union" type;

For example now, to identify object and use it's field i need to use this construction:

query xxx {
   sometype: {
      ...on X {
         onlyXField
      }
      ...on Y {
         onlyYField
      }
      ...on Z {
         onlyZField
      }
   }
}
if (parsedObject is X) {
   return x.onlyXField;
}
if (parsedObject is Y) {
   return y.onlyYField;
}
if (parsedObject is Z) {
   return z.onlyZField;
}

// unsupported type
return error;

and if i use mixin (fragments inside queries), then i'd have to:

if (parsedObject is X) {
   return (x as XMixin).onlyXField;
}
if (parsedObject is Y) {
   return (y as XMixin).onlyYField;
}
if (parsedObject is Z) {
   return (z as XMixin).onlyZField;
}

// unsupported type
return error;

with "freezed" it would be something like this:

x.map(
   X: (it) => it.onlyXField,
   Y: (it) => it.onlyYField,
   Z: (it) => it.onlyZField,
)
opsb commented

Just came here to request the exact same thing then saw it top of the list. On our project we use unions to model the possible error results from a mutation or query so we pretty much have a union on every single operation. We use freezed for the rest of the app so currently we map the result types into a freezed union as soon as we get the result back. It's a ton of boiler plate though so having this in the generator would have a big impact on ergonomics.

This is a request I have as well. I'm using the Riverpod / Freezed architecture and this is my query / state example.

query GetMode($model: String!, $serial: String!, $language: String!) {
    getMode(model: $model , serial: $serial, language: $language) {
        ... on ModeResponse {
            enable
            modified_at
        }
        ... on Failure {
            failure
            detail
        }
    }
}
@freezed
class ModeState with _$ModeState {
  const factory ModeState({
    GetMode$Query$GetMode$Failure? failure,
    GetMode$Query$GetMode$ModeResponse? data,
    @Default(false) bool loading,
  }) = _ModeState;

  const ModeState._();
}

And I'm conditionally setting state via StateNotifier based on the type response. Would be sweet if this could be automatic somehow. Not sure how that would work. Example:

// Copy result to state (UNION CONDITIONAL STATE)
final resultData = result.data?.getMode;
if (resultData is GetMode$Query$GetMode$Failure) {
  state = state.copyWith(failure: resultData, data: null);
} else if (resultData is GetMode$Query$GetMode$ModeResponse) {
  state = state.copyWith(failure: null, data: resultData);
} else {
  state = state.copyWith(failure: null, data: null);
}