Easily restore your project to a previous version with our new Instant One-click Backup Recovery

How to build dynamic Flutter apps with Hygraph

In this post, we'll build a news app in Flutter with Hygraph’s unique features.
Malomo Demola

Malomo Demola

Apr 19, 2024
How to build dynamic Flutter apps with Hygraph

In this post, we'll build a news app in Flutter with Hygraph’s unique features.

Hygraph is a headless content management system (CMS) featuring Content Federation that allows users to efficiently create, manage, and deliver content data from diverse sources. It enables you to deliver digital experiences through a unified content endpoint, eliminating the need to migrate everything to a single platform.

Flutter is an open-source UI development kit for building multi-platform applications from a single codebase.

Let’s get started!

#Prerequisites

You’ll need a few things to follow along:

#Project setup

In this project, we’ll use prebuilt UIs to expedite development. The UI consists of:

  • A news component
  • A trending screen and
  • An application entry point

To get started, let’s clone the project by navigating to a desired directory and running the command below:

git clone https://github.com/Mr-Malomz/hygraph_flutter.git && cd hygraph_flutter

Next, we’ll need to install the project dependencies by running the following command:

flutter pub get

Then, select an iOS device and run the project:

flutter run

undefined

#Set up the news app on Hygraph

Before setting up our project on Hygraph, we must understand some of the features it provides. In our case, Hygraph’s Models, Components, and Fields.

  • Models serve as the building blocks of our application, allowing us to structure specific sections. For instance, a news app may have models for trending, users, explore, etc.
  • Components in Hygraph function similarly to widgets in Flutter. You can think of these as templates defined with properties that you can reuse in building applications. A model can contain multiple components.
  • Fields are used to define the properties of our application. For instance, a news app may have properties such as title, preview, cover image, etc.

For our news app, we can set up our application to have a Trending model and a News Row component with Title, Preview, and Cover Image fields.

undefined

Create a Model

To get started, log into your Hygraph console, click the Add project button, input the news app as the project name, select the preferred Region, and Add project.

undefined undefined

Next, navigate to the Schema menu, click the + Add Model button, input Trending as the display name, accept suggested values (for API ID and Plural API ID), and click the Add Model button to create a model.

undefined undefined

Create a Component and Fields

Next, click the + Add button beside the Component submenu, input News Row as the display name, accept suggested values, and click the Add Component button to create it.

undefined undefined

Next, we must add fields to our component by selecting a Field, inputting the corresponding Display name, and then click Add. You can use the table below as a reference:

FieldDisplay name
Single line textTitle
Multi line textPreview
Asset pickerCover Image

Our component should have three fields, as shown below:

undefined

Managing assets with Hygraph

Hygraph offers a built-in asset management system for handling images, videos, PDFs, and more. To further enhance our news app, we need to upload sample images for our cover images. To do so, navigate to the Assets tab and click the Upload button.

undefined

We can utilize the data below to upload the images using the Link (URL) option.

Image nameImage URL
Blockchainhttps://bit.ly/3PfmE78
Computer visionhttps://bit.ly/4c0JM33
Edge computinghttps://bit.ly/4394UzW

undefined undefined

Finally, we need to publish images by selecting them and clicking the Publish button.

undefined

Use the component in the model

Next, we must use our News row component in the Trending model to form our news app's architecture. To do this, navigate to the Schema menu, select the Trending model, and add a Modular field.

undefined

PS: The Modular field will assist us in modeling our application to include multiple *News row* components.

Input News collection as the display name, check the Allow multiple values, select the News Row as the allowed component and Add.

undefined

Add data to the model

With our news app set up on Hygraph, we can proceed to populate it with the required data as shown below:

TitlePreviewCover Image
Blockchain trendThe current trend in the block....Add the uploaded Blockchain image
Computer visionComputer vision is revolutionizing how...Add the uploaded Computer vision image
Edge computingEdge computing is a distributed info...Add the uploaded Edge computing image

To do this, click the Go to content editing link, click the + Add entry button, and fill in the required information.

undefined undefined

Next, we need to make the content available to our Flutter application by clicking the Save & publish button.

undefined

Finally, we can test the published content using the API playground and select desired fields.

undefined

Update content permission

By default, contents stored on Hygraph are secure unless you explicitly define permissions. To enable access to the content, navigate to the Project settings menu, select the API Access submenu, scroll to the Public Content API section, and click the Yes, initialize defaults button.

undefined

Hygraph ships with a robust authorization and authentication mechanism. Learn more about it on its dedicated page.

Lastly, we also need to copy the application endpoint. It will come in handy when building our application.

undefined

#Building the news app with Hygraph and Flutter

To get started, we first need to install the graph_flutter package, a package for interacting with GraphQL in a Flutter application. We can install it by running the command below:

flutter pub add graphql_flutter

Secondly, we need to modify our application entry point lib/main.dart to initialize the GraphQL clients as shown below:

import 'package:flutter/material.dart';
import 'package:hygraph_flutter/screens/home.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
void main() {
runApp(const MyApp());
}
final HttpLink httpLink = HttpLink("COPIED ENDPOINT GOES HERE");
final ValueNotifier<GraphQLClient> client =
ValueNotifier<GraphQLClient>(GraphQLClient(
link: httpLink,
cache: GraphQLCache(),
));
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GraphQLProvider(
client: client,
child: MaterialApp(
title: 'News App',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const Home(),
),
);
}
}

The snippet above does the following:

  • Creates a link using the copied endpoint
  • Configures the GraphQL client to use the link
  • Utilizes the GraphQLProvider to wrap the application, enabling client usage across the entire application

Thirdly, we need to create a lib/utils.dart file to represent our application data. The model will cater to converting the response sent from the JSON response to a Dart object.

class _CoverImage {
String fileName;
String url;
_CoverImage({
required this.fileName,
required this.url,
});
factory _CoverImage.fromJson(Map<dynamic, dynamic> json) {
return _CoverImage(
fileName: json['fileName'],
url: json['url'],
);
}
}
class News {
String id;
String title;
String preview;
_CoverImage coverImage;
News({
required this.id,
required this.title,
required this.preview,
required this.coverImage,
});
factory News.fromJson(Map<dynamic, dynamic> json) {
return News(
id: json['id'],
title: json['title'],
preview: json['preview'],
coverImage: _CoverImage.fromJson(json['coverImage']),
);
}
}

Lastly, we need to modify the lib/screens/home.dart file by importing the required dependencies and creating a query string with the required fields.

//other imports
import 'package:hygraph_flutter/components/news_row.dart';
import 'package:hygraph_flutter/utils.dart';
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
String getNewsQuery = """
query MyQuery {
trendings {
newsCollection {
... on NewsRow {
id
preview
title
coverImage {
createdAt
fileName
url
}
}
}
}
}
""";
class _HomeState extends State<Home> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
// UI CODE GOES HERE
}
}

Then, utilize the query to make requests, check for appropriate responses, and pass the required values to the NewsRow widget.

// imports goes here
class Home extends StatefulWidget {
//code goes here
}
String getNewsQuery = """
//query strings goes here
""";
class _HomeState extends State<Home> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:
const Text('Trending News', style: TextStyle(color: Colors.white)),
backgroundColor: Colors.black,
),
body: Query(
options: QueryOptions(document: gql(getNewsQuery)),
builder: (result, {fetchMore, refetch}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return const Center(
child: CircularProgressIndicator(
color: Colors.black,
));
}
List<News>? newsList =
(result.data?\["trendings"\][0]["newsCollection"] as List<dynamic>)
.map((item) => News.fromJson(item))
.toList();
if (newsList.isEmpty) {
return const Text('No news yet!');
}
return ListView.builder(
itemCount: newsList.length,
itemBuilder: (context, index) {
final news = newsList[index];
return InkWell(
onTap: () {},
child: Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(width: .5, color: Colors.grey),
),
),
padding: EdgeInsets.fromLTRB(10, 20, 10, 20),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
NewsRow(
url: news.coverImage.url,
preview: news.preview,
title: news.title,
)
],
),
],
),
),
);
},
);
},
),
);
}
}

With that done, we can restart the application using the command below:

flutter run

undefined

The complete source code can be found on GitHub.

#Conclusion

This post discusses building a news app in Flutter by exploring some unique functionalities in Hygraph. Beyond the topics discussed above, you can extend the application by exploring Hygraph’s well-tailored features to build small to large enterprise applications.

Finally, join the Slack community to stay updated on the latest developments and connect with fellow Hygraph developers.

Useful resources

Blog Author

Malomo Demola

Malomo Demola

Technical Writer

Demola is an experienced product designer, software developer, and technical writer who is passionate about building products and creating engaging content. Beyond his professional career, Demola loves to cook, explore new places, and watch movies.