Skip to content

Instantly share code, notes, and snippets.

@tatsuyasusukida
Last active October 19, 2022 00:40
Show Gist options
  • Save tatsuyasusukida/520b3e9de3d42421cefa0f803ffd3c99 to your computer and use it in GitHub Desktop.
Save tatsuyasusukida/520b3e9de3d42421cefa0f803ffd3c99 to your computer and use it in GitHub Desktop.
How to access GraphQL API with Ferry in Flutter
# import './pokemon_card_fragment.graphql'
query AllPokemon($limit: Int!, $offset: Int!) {
pokemons(limit: $limit, offset: $offset) {
results {
...PokemonCard
}
}
}
targets:
$default:
builders:
ferry_generator|graphql_builder:
enabled: true
options:
schema: hello_ferry|lib/schema.graphql
ferry_generator|serializer_builder:
enabled: true
options:
schema: hello_ferry|lib/schema.graphql
import 'package:flutter/material.dart';
import 'package:hello_ferry/src/components/pokemon_list.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Pokemon Demo',
home: PokemonListScreen(),
);
}
}
import 'package:flutter/material.dart';
import 'graphql/__generated__/pokemon_card_fragment.data.gql.dart';
class PokemonCard extends StatelessWidget {
final GPokemonCard pokemon;
const PokemonCard({super.key, required this.pokemon});
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
// SizedBox(
// height: 200,
// width: 200,
// child: Image.network(
// pokemon.avatar,
// errorBuilder: (context, error, stacktrace) {
// return Text(
// "error loading image ${pokemon.avatar}: $error");
// },
// ),
// ),
Text(
pokemon.name,
style: Theme.of(context).textTheme.headline6,
),
Text(
'height: ${pokemon.height?.in_meter ?? 0}',
style: Theme.of(context).textTheme.subtitle1,
),
Text(
'weight: ${pokemon.weight?.in_kg ?? 0}',
style: Theme.of(context).textTheme.subtitle1,
)
],
),
),
);
}
}
fragment NestedFragment on Pokemon {
id
name
avatar
}
fragment PokemonCard on Pokemon {
...NestedFragment
height {
in_meter
}
weight {
in_kg
}
}
import 'package:built_collection/built_collection.dart';
import 'package:ferry/ferry.dart';
import 'package:ferry_flutter/ferry_flutter.dart';
import 'package:flutter/material.dart';
import 'package:gql_http_link/gql_http_link.dart';
// import 'package:hello_ferry/__generated__/schema.schema.gql.dart';
import 'package:hello_ferry/src/components/pokemon_card.dart';
import 'graphql/__generated__/all_pokemon.data.gql.dart';
import 'graphql/__generated__/all_pokemon.req.gql.dart';
import 'graphql/__generated__/all_pokemon.var.gql.dart';
class PokemonListScreen extends StatelessWidget {
const PokemonListScreen({super.key});
@override
Widget build(BuildContext context) {
final link = HttpLink("https://pokeapi.dev");
final cache = Cache();
// final cache = Cache(possibleTypes: possibleTypesMap);
final client = Client(link: link, cache: cache);
return Scaffold(
appBar: AppBar(
title: const Text('All Pokemon'),
),
body: Operation<GAllPokemonData, GAllPokemonVars>(
client: client,
operationRequest: GAllPokemonReq(
(b) => b
..vars.limit = 50
..vars.offset = 0,
),
builder: (context, response, error) {
if (response!.loading) {
return const Center(child: CircularProgressIndicator());
}
final pokemons = response.data?.pokemons?.results ?? BuiltList();
return ListView.builder(
itemCount: pokemons.length,
itemBuilder: (context, index) => PokemonCard(
pokemon: pokemons[index],
),
);
},
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment