Вы можете скопировать и запустить полный код ниже
В pubspec.yaml
, используйте any
для graphql_flutter
graphql_flutter: any
http: any
некоторый учебный код, который необходимо изменить для graphql_flutter 3.0
, например как изменить result.hasError
на result.hasException
рабочая демоверсия

полный код
import 'package:flutter/material.dart';
import "package:graphql_flutter/graphql_flutter.dart";
class GraphQLConfiguration {
static HttpLink httpLink = HttpLink(
uri: "https://examplegraphql.herokuapp.com/graphql",
);
ValueNotifier<GraphQLClient> client = ValueNotifier(
GraphQLClient(
link: httpLink,
cache: OptimisticCache(dataIdFromObject: typenameDataIdFromObject),
),
);
GraphQLClient clientToQuery() {
return GraphQLClient(
cache: OptimisticCache(dataIdFromObject: typenameDataIdFromObject),
link: httpLink,
);
}
}
GraphQLConfiguration graphQLConfiguration = GraphQLConfiguration();
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(
GraphQLProvider(
client: graphQLConfiguration.client,
child: CacheProvider(child: MyApp()),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Example',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Principal(),
);
}
}
class Person {
Person(this.id, this.name, this.lastName, this.age);
final String id;
final String name;
final String lastName;
final int age;
getId() => this.id;
getName() => this.name;
getLastName() => this.lastName;
getAge() => this.age;
}
class QueryMutation {
String addPerson(String id, String name, String lastName, int age) {
return """
mutation{
addPerson(id: "$id", name: "$name", lastName: "$lastName", age: $age){
id
name
lastName
age
}
}
""";
}
String getAll() {
return """
{
persons{
id
name
lastName
age
}
}
""";
}
String deletePerson(id) {
return """
mutation{
deletePerson(id: "$id"){
id
}
}
""";
}
String editPerson(String id, String name, String lastName, int age) {
return """
mutation{
editPerson(id: "$id", name: "$name", lastName: "$lastName", age: $age){
name
lastName
}
}
""";
}
}
class AlertDialogWindow extends StatefulWidget {
final Person person;
final bool isAdd;
AlertDialogWindow({Key key, this.person, this.isAdd}) : super(key: key);
@override
State<StatefulWidget> createState() =>
_AlertDialogWindow(this.person, this.isAdd);
}
class _AlertDialogWindow extends State<AlertDialogWindow> {
TextEditingController txtId = TextEditingController();
TextEditingController txtName = TextEditingController();
TextEditingController txtLastName = TextEditingController();
TextEditingController txtAge = TextEditingController();
GraphQLConfiguration graphQLConfiguration = GraphQLConfiguration();
QueryMutation addMutation = QueryMutation();
final Person person;
final bool isAdd;
_AlertDialogWindow(this.person, this.isAdd);
@override
void initState() {
super.initState();
if (!this.isAdd) {
txtId.text = person.getId();
txtName.text = person.getName();
txtLastName.text = person.getLastName();
txtAge.text = person.getAge().toString();
}
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return AlertDialog(
title: Text(this.isAdd ? "Add" : "Edit or Delete"),
content: Container(
child: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width,
),
child: Stack(
children: <Widget>[
Container(
child: TextField(
maxLength: 5,
controller: txtId,
enabled: this.isAdd,
decoration: InputDecoration(
icon: Icon(Icons.perm_identity),
labelText: "ID",
),
),
),
Container(
padding: EdgeInsets.only(top: 80.0),
child: TextField(
maxLength: 40,
controller: txtName,
decoration: InputDecoration(
icon: Icon(Icons.text_format),
labelText: "Name",
),
),
),
Container(
padding: EdgeInsets.only(top: 160.0),
child: TextField(
maxLength: 40,
controller: txtLastName,
decoration: InputDecoration(
icon: Icon(Icons.text_rotate_vertical),
labelText: "Last name",
),
),
),
Container(
padding: EdgeInsets.only(top: 240.0),
child: TextField(
maxLength: 2,
controller: txtAge,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: "Age", icon: Icon(Icons.calendar_today)),
),
),
],
),
),
),
),
actions: <Widget>[
FlatButton(
child: Text("Close"),
onPressed: () => Navigator.of(context).pop(),
),
!this.isAdd
? FlatButton(
child: Text("Delete"),
onPressed: () async {
GraphQLClient _client = graphQLConfiguration.clientToQuery();
QueryResult result = await _client.mutate(
MutationOptions(
document: addMutation.deletePerson(txtId.text),
),
);
if (!result.hasException) Navigator.of(context).pop();
},
)
: null,
FlatButton(
child: Text(this.isAdd ? "Add" : "Edit"),
onPressed: () async {
if (txtId.text.isNotEmpty &&
txtName.text.isNotEmpty &&
txtLastName.text.isNotEmpty &&
txtAge.text.isNotEmpty) {
if (this.isAdd) {
GraphQLClient _client = graphQLConfiguration.clientToQuery();
QueryResult result = await _client.mutate(
MutationOptions(
document: addMutation.addPerson(
txtId.text,
txtName.text,
txtLastName.text,
int.parse(txtAge.text),
),
),
);
if (!result.hasException) {
txtId.clear();
txtName.clear();
txtLastName.clear();
txtAge.clear();
Navigator.of(context).pop();
}
} else {
GraphQLClient _client = graphQLConfiguration.clientToQuery();
QueryResult result = await _client.mutate(
MutationOptions(
document: addMutation.editPerson(
txtId.text,
txtName.text,
txtLastName.text,
int.parse(txtAge.text),
),
),
);
if (!result.hasException) {
txtId.clear();
txtName.clear();
txtLastName.clear();
txtAge.clear();
Navigator.of(context).pop();
}
}
}
},
)
],
);
}
}
class Principal extends StatefulWidget {
@override
State<StatefulWidget> createState() => _Principal();
}
class _Principal extends State<Principal> {
List<Person> listPerson = List<Person>();
GraphQLConfiguration graphQLConfiguration = GraphQLConfiguration();
void fillList() async {
QueryMutation queryMutation = QueryMutation();
GraphQLClient _client = graphQLConfiguration.clientToQuery();
QueryResult result = await _client.query(
QueryOptions(
document: queryMutation.getAll(),
),
);
if (!result.hasException) {
for (var i = 0; i < result.data["persons"].length; i++) {
setState(() {
listPerson.add(
Person(
result.data["persons"][i]["id"],
result.data["persons"][i]["name"],
result.data["persons"][i]["lastName"],
result.data["persons"][i]["age"],
),
);
});
}
}
}
@override
void initState() {
super.initState();
fillList();
}
void _addPerson(context) {
showDialog(
context: context,
builder: (BuildContext context) {
AlertDialogWindow alertDialogWindow =
new AlertDialogWindow(isAdd: true);
return alertDialogWindow;
},
).whenComplete(() {
listPerson.clear();
fillList();
});
}
void _editDeletePerson(context, Person person) {
showDialog(
context: context,
builder: (BuildContext context) {
AlertDialogWindow alertDialogWindow =
new AlertDialogWindow(isAdd: false, person: person);
return alertDialogWindow;
},
).whenComplete(() {
listPerson.clear();
fillList();
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Example"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add_circle_outline),
onPressed: () => _addPerson(context),
tooltip: "Insert new person",
),
],
),
body: Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
child: Text(
"Person",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 30.0),
),
),
Container(
padding: EdgeInsets.only(top: 50.0),
child: ListView.builder(
itemCount: listPerson.length,
itemBuilder: (context, index) {
return ListTile(
selected: listPerson == null ? false : true,
title: Text(
"${listPerson[index].getName()}",
),
onTap: () {
_editDeletePerson(context, listPerson[index]);
},
);
},
),
),
],
),
);
}
}