This article will walk you through creating a Flutter project and plugging into GraphQL.
Project depend on
- Flutter Development Environment – See How to Install Flutter
- Code editor for the Flutter plugin installed – see Configuration Editor
- A GraphQL backend running – see building a GraphQL Backend Project in 10 Minutes
- LAN IP on the backend of GraphQL – See “How to View LAN IP address on the Command Line”
Create a project
Create a brand new Flutter project tinyLearn_client:
$ flutter create tinylearn_client
Copy the code
Use the code editor to open the project:
Click on the file lib/main.dart, clean up the code, remove the comment and change it to:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page')); }}class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
returnScaffold( appBar: AppBar( title: Text(widget.title), ), body: Container(), ); }}Copy the code
After running, we get:
Access to theGraphQL
Install the dependency library Graphql_flutter:
pubspec.yaml:
dependencies:
flutter:
sdk: flutter
+ graphql_flutter: ^ 3.0.1
Copy the code
Run:
$ flutter pub get
Copy the code
With that in mind, let’s review what we learned in the previous episode “Building a GraphQL Back-end Project in 10 Minutes” :
This is the “Postman” page we mentioned in the last video. In the middle of the image is the JSON returned by the server. Let’s first parse the JSON.
You can parse JSON any way you like. Here I use the online tool QuickType to generate the Model. See How to Convert JSON to Model using the Online Transcoding Tool Flutter.
Save the parsing code in a new file lib/ postsdata.dart:
// To parse this JSON data, do
//
// final postsData = postsDataFromJson(jsonString);
import 'dart:convert';
class PostsData {
final List<Post> posts;
PostsData({
this.posts,
});
factory PostsData.fromJson(String str) => PostsData.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory PostsData.fromMap(Map<String.dynamic> json) => PostsData(
posts: json["posts"] = =null ? null : List<Post>.from(json["posts"].map((x) => Post.fromMap(x))),
);
Map<String.dynamic> toMap() => {
"posts": posts == null ? null : List<dynamic>.from(posts.map((x) => x.toMap())),
};
}
class Post {
final String id;
final int created;
final String content;
Post({
this.id,
this.created,
this.content,
});
factory Post.fromJson(String str) => Post.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory Post.fromMap(Map<String.dynamic> json) => Post(
id: json["id"] = =null ? null : json["id"],
created: json["created"] = =null ? null : json["created"],
content: json["content"] = =null ? null : json["content"]);Map<String.dynamic> toMap() => {
"id": id == null ? null : id,
"created": created == null ? null : created,
"content": content == null ? null : content,
};
}
Copy the code
Dart = lib/main.dart = lib/main.dart
import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:tinylearn_client/PostsData.dart'; .final _uri = 'http://10.0.0.10:4444/'; // The IP address is the LAN IP address of the server, and the port number is 4444. You need to configure it according to the network environment
class _MyHomePageState extends State<MyHomePage> {
Future<PostsData> _postsData;
@override
void initState() {
final client = GraphQLClient(
cache: InMemoryCache(),
link: HttpLink(uri: _uri)
);
_postsData = _createPostsData(client);
super.initState();
}
Future<PostsData> _createPostsData(GraphQLClient client) async {
final result = await client.query(QueryOptions(
documentNode: gql(r''' query { posts { id created content } } ''')));if (result.hasException) throw result.exception;
returnPostsData.fromMap(result.data); }... }Copy the code
First, configure a GraphQLClient that lets you send requests to the GraphQL server.
final _uri = 'http://10.0.0.10:4444/';
class _MyHomePageState extends State<MyHomePage> {...@override
void initState() {
finalclient = GraphQLClient( cache: InMemoryCache(), link: HttpLink(uri: _uri) ); . }... }Copy the code
Note that final _uri = ‘http://10.0.0.10:4444/’; Is the address of the GraphQL server. Using the backend written in the previous article “Building a GraphQL Backend Project in 10 Minutes”, we need to configure it as the BACKEND LAN IP and port number: http://${backendLanIP}:4444/
BackendLanIP may be 192.169.0.10 or 10.0.0.10, which you need to query yourself.
Let’s define a method Future
.class _MyHomePageState extends State<MyHomePage> {
Future<PostsData> _postsData;
@override
void initState() {
finalclient = ... ; _postsData = _createPostsData(client);super.initState();
}
Future<PostsData> _createPostsData(GraphQLClient client) async {
final result = await client.query(QueryOptions(
documentNode: gql(r''' query { posts { id created content } } ''')));if (result.hasException) throw result.exception;
returnPostsData.fromMap(result.data); }... }Copy the code
The requested parameters are from the configuration to the left of “Postmain”.
Next, we draw the page, which will consume the request and display the results as a list:
. Future<PostsData> _createPostsData(GraphQLClient client)async{... }@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: FutureBuilder<PostsData>(
future: _postsData,
builder: (context, snapshot) {
if (snapshot.hasData) {
final List<Post> posts = snapshot.data.posts;
return _buildListView(posts);
}
if (snapshot.hasError) {
return Text('${snapshot.error}', textAlign: TextAlign.center);
}
returnCircularProgressIndicator(); },),),); } ListView _buildListView(List<Post> posts) {
return ListView.separated(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
return _postListTile(post);
},
separatorBuilder: (context, index) => Divider(),
);
}
ListTile _postListTile(Post post) {
returnListTile( title: Text(post.content), subtitle: Text(post.created.time.toString()), ); }...Copy the code
Finally, add an extension method to convert the int timestamp returned by the server to DateTime.
.class MyHomePage extends StatefulWidget {... } extension Time onint {
DateTime get time => DateTime.fromMillisecondsSinceEpoch(this);
}
Copy the code
Run:
And you’re done!
To be continued
This time we got through the front and back ends of GraphQL and demonstrated some basic functionality. The next article, When to Use GraphQL? We’ll start with the design philosophy of GraphQL, its strengths and weaknesses. Later, we will put these concepts into action and create a fully functional front and back end product.
If you have any ideas, please leave me a message.
Source:
The code address
lib/main.dart:
import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:tinylearn_client/PostsData.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page')); }}class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
final _uri = 'http://10.0.0.105:4444/';
class _MyHomePageState extends State<MyHomePage> {
Future<PostsData> _postsData;
@override
void initState() {
final client = GraphQLClient(
cache: InMemoryCache(),
link: HttpLink(uri: _uri)
);
_postsData = _createPostsData(client);
super.initState();
}
Future<PostsData> _createPostsData(GraphQLClient client) async {
final result = await client.query(QueryOptions(
documentNode: gql(r''' query { posts { id created content } } ''')));if (result.hasException) throw result.exception;
return PostsData.fromMap(result.data);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: FutureBuilder<PostsData>(
future: _postsData,
builder: (context, snapshot) {
if (snapshot.hasData) {
final List<Post> posts = snapshot.data.posts;
return _buildListView(posts);
}
if (snapshot.hasError) {
return Text('${snapshot.error}', textAlign: TextAlign.center);
}
returnCircularProgressIndicator(); },),),); } ListView _buildListView(List<Post> posts) {
return ListView.separated(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
return _postListTile(post);
},
separatorBuilder: (context, index) => Divider(),
);
}
ListTile _postListTile(Post post) {
return ListTile(
title: Text(post.content),
subtitle: Text(post.created.time.toString()),
);
}
}
extension Time on int {
DateTime get time => DateTime.fromMillisecondsSinceEpoch(this);
}
Copy the code
lib/PostData.dart:
// To parse this JSON data, do
//
// final postsData = postsDataFromJson(jsonString);
import 'dart:convert';
class PostsData {
final List<Post> posts;
PostsData({
this.posts,
});
factory PostsData.fromJson(String str) => PostsData.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory PostsData.fromMap(Map<String.dynamic> json) => PostsData(
posts: json["posts"] = =null ? null : List<Post>.from(json["posts"].map((x) => Post.fromMap(x))),
);
Map<String.dynamic> toMap() => {
"posts": posts == null ? null : List<dynamic>.from(posts.map((x) => x.toMap())),
};
}
class Post {
final String id;
final int created;
final String content;
Post({
this.id,
this.created,
this.content,
});
factory Post.fromJson(String str) => Post.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory Post.fromMap(Map<String.dynamic> json) => Post(
id: json["id"] = =null ? null : json["id"],
created: json["created"] = =null ? null : json["created"],
content: json["content"] = =null ? null : json["content"]);Map<String.dynamic> toMap() => {
"id": id == null ? null : id,
"created": created == null ? null : created,
"content": content == null ? null : content,
};
}
Copy the code
reference
- Flutter
- GraphQL