sling_gql_hooks 1.0.0 copy "sling_gql_hooks: ^1.0.0" to clipboard
sling_gql_hooks: ^1.0.0 copied to clipboard

flutter_hooks adapter for sling_gql: useSlingQuery, useSlingMutation and useSlingSubscription, the QueryBuilder / MutationBuilder / SubscriptionBuilder of a HookWidget.

sling_gql_hooks #

flutter_hooks adapter for sling_gql: useSlingQuery, useSlingMutation and useSlingSubscription are QueryBuilder, MutationBuilder and SubscriptionBuilder for a HookWidget. Same machinery (one QueryScope per widget, per-frame batching, per-field rebuilds, sticky errors, fetch policies), no builder nesting.

Docs: https://tpucci.github.io/sling_gql/guides/hooks/ · Source: https://github.com/tpucci/sling_gql

flutter pub add sling_gql sling_gql_hooks flutter_hooks

useSlingQuery #

class LaunchTile extends HookWidget {
  const LaunchTile({super.key});

  @override
  Widget build(BuildContext context) {
    final (launch, state) = useSlingQuery(
      (Query q) => q.latestLaunch?..name..rocket?.name,
    );
    if (state.error != null) return RetryTile(onRetry: state.refetch);
    return ListTile(
      title: Text(launch?.name ?? '…'),
      subtitle: Text(launch?.rocket?.name ?? '…'),
    );
  }
}

The selector is what QueryBuilder's builder is: every field it reads is recorded, fetched in the frame's batched request and becomes a dependency of the widget. It returns whatever the build needs — an accessor (a cascade reads fields and returns the object) or a record of values. Read in the selector everything the build needs: its reads decide state.hasMissingData, maxAge staleness and what cacheAndNetwork refetches. Accessors it returns stay bound to the widget's scope, so reading more fields through them later still fetches them (like a QueryBuilder's children), but outside that bookkeeping.

fetchPolicy:, maxAge:, debugLabel: and scheduler: are QueryBuilder's. The state is sling_gql's QueryState (isLoading, hasMissingData, isSkeleton, isStale, error, refetch, revalidate).

useSlingMutation #

final (mutate, state) = useSlingMutation<Mutation>();
// …
onPressed: state.isLoading
    ? null
    : () => mutate(
          (m) => m.toggleFavorite(launchId: id)?.favorite,
          optimistic: () => launch.favorite = !favorite,
        ),

mutate resolves to the body's value computed from the cache, or null on failure (never throws; the exception is on state.error). state is sling_gql's MutationState for the latest call. The root comes from the SlingScope's schema: unless root: is given.

useSlingSubscription #

final (s, state) = useSlingSubscription<Subscription>(
  (s) => s.launchStatusChanged?..status..name,
  onEvent: (s) => showSnack(s.launchStatusChanged?.name),
);

Opens at the end of the first frame, closes when the widget is disposed; each event is normalized into the cache (queries showing the same entities rebuild) and rebuilds this widget. retryAfter:, root: and debugLabel: are SubscriptionBuilder's.

Testing #

Hooks run on the same client as the builders, so sling_gql_test's MockGraphQLServer and tester.pumpUntilSettled(client) work unchanged.

Versioning #

From 1.0 sling_gql_hooks follows semantic versioning and shares its major version with sling_gql; the hooks keep the semantics of the builders of the same sling_gql major. A new major of flutter_hooks is a major here. Deprecated APIs keep working for at least one minor release and are removed only in the next major. Full policy: Versioning & deprecation; coming from 0.x: Upgrading to 1.0. Security issues: SECURITY.md.

0
likes
160
points
202
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

flutter_hooks adapter for sling_gql: useSlingQuery, useSlingMutation and useSlingSubscription, the QueryBuilder / MutationBuilder / SubscriptionBuilder of a HookWidget.

Homepage
Repository (GitHub)
View/report issues

Topics

#graphql #hooks #flutter-hooks

License

MIT (license)

Dependencies

flutter, flutter_hooks, sling_gql

More

Packages that depend on sling_gql_hooks