artemis icon indicating copy to clipboard operation
artemis copied to clipboard

Add "freezed" feature to codegen

Open WDtms opened this issue 3 years ago • 2 comments

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,
)

WDtms avatar Jan 28 '22 06:01 WDtms

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.

opsb avatar Feb 25 '22 08:02 opsb

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);
}

mdrideout avatar Apr 14 '22 23:04 mdrideout