Working with APIs in Flutter

Emre Savas
Emre Savas 19 May 2021
Author:

Most of the data on mobile platforms comes from different sources through endpoints. Mobile platforms make their actions according to this incoming data. In this article, we will get to know Flutter, an open source mobile application development SDK developed by Google, and then work with an API on Flutter.

flutter api

What is Flutter

Flutter is a free and open source mobile UI framework created by Google and released in May 2017 that you can use to develop mobile, web and desktop applications.

Flutter is cross platform, it enables both IOS and Android based applications to be developed using the same codebase.

Why Flutter

  • Flutter is a system that is easy to learn and can be used practically. So with flutter, you can easily create your mobile applications in a modern framework.
  • With Flutter, you can change codes quickly. In this way, you can see the results with a click. When you make very important changes, you do not need to take time-consuming actions such as reloading.
  • It is very cheap to develop a mobile application using Flutter. Developing and maintaining mobile apps for both Android and IOS can be costly.
  • Native applications are always preferred for high performance in mobile application development. However, it is difficult to see a difference between the flutter app and native apps in terms of performance.
  • You can use the widgets offered by Flutter without difficulty. In this way, you can offer a high-quality user interface with a high user experience and personalize your mobile application as you wish.

Creating a Boilerplate Application

In this section, we will create an application with a working API on Flutter.

Create Project

First, let's create our sample project by running the command below.

    
        flutter create my_application
    

Let's edit the default codes according to our own project.

File: main.dart

    
        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,
                ),
                home: Yugioh_List(),
            );
        }
        }

        class Yugioh_List extends StatefulWidget {
            @override
            _Yugioh_ListState createState() => _Yugioh_ListState();
        }

        class _Yugioh_ListState extends State {
            @override
            Widget build(BuildContext context) {
                return Container();
            }
        }

Include the Http Package

After creating our project, let's include the http package in the "pubspec.yaml" file so that we can bring our data via http.

File: pubspec.yaml

    
        name: my_application
        description: Flutter Application

        version: 1.0.0+1

        environment:
        sdk: ">=2.7.0 < 3.0.0"

        dependencies:
        flutter:
            sdk: flutter
        cupertino_icons: ^1.0.1

        http: ^0.13.0 

        dev_dependencies:
        flutter_test:
            sdk: flutter
        integration_test:
            sdk: flutter
    

After defining the necessary packages to the project, let's import the http package to our Main.dart file.

    
import 'package: http / http.dart' as http;
    

Create Model

We will work with a sample Json data in our project. Yugioh data will be used for this application. (https://raw.githubusercontent.com/KianBennett/Yugioh-Database-Downloader/master/cards.json)

We are bringing our Yugioh data in Json format to a format to be used in Flutter using the https://app.quicktype.io/ site. Then we open the "Models" folder in the directory of our project and open a file named "Yugioh.dart" into it and copy the codes we brought to the Flutter format here.

code editor

Create Homepage

Now, when we want to use a field in our model class, we can create an object from this class and pull the relevant field.

In this step, we will take the necessary steps in the "main.dart" file.

File: main.dart

    
        Yugioh _yugioh;

        Future getCards() async {
            var response = await http.get("https://raw.githubusercontent.com/KianBennett/Yugioh-Database-Downloader/master/cards.json");
            var responseBody = json.decode(response.body);
            var _yugioh = Yugioh.fromJson(responseBody);
            return _yugioh;
        }
    

We created a method called getCards of type future. In this method, we first said that we will request a get to our Url address. There are String statements in our request. We specified that we will take the body part of the string expression that comes with Json.decode and assign it to the variable named responseBody. So we converted the body part of the incoming String expression to the json object.

We used the Yugioh.from Json method to create a Yugioh object from the Json object. This method allows us to create an object from the Yugioh class using the incoming json object.

File: main.dart

    
        Widget build(BuildContext context) {
            return Scaffold(
              appBar: AppBar(
                title: Text("Yugioh"),
              ),
              body: FutureBuilder(
                future: getCards(),
                builder: (context, AsyncSnapshot snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  } else if (snapshot.connectionState == ConnectionState.done) {
                    debugPrint("successfully connected");
                    return Center(child: Container(child: Text("successfully connected"),));
        
                  } else {
                    return Center(
                      child: Text(snapshot.error.toString()),
                    );
                  }
                },
              ),
            );        
    

Let's create our script and define a Future builder in the body part. In the future feature of the future builder widget, we will define our getCards method, which will take a long time. We will create our main structure in the Builder section. First, let's carry out our checks on connection.

After this step, after making a small design, we will pull some of the Yugioh class and place them on the page.

Copy the following codes to the "else if" code block we just added.

File: main.dart

    
        else if (snapshot.connectionState == ConnectionState.done) {
            debugPrint("successfully connected");
            return GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2),
                itemBuilder: (context, index) {
                  return InkWell(
                    onTap: (){
                      Navigator.of(context).push(MaterialPageRoute(builder: (context)=>yugiohDetail(mycards: snapshot.data.cards[index],)));
                    },
                    child: Hero(
                      tag: snapshot.data.cards[index].id,
                      child: Container(
                        height: 500,
                        width: 500,
                        child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [
                          Expanded(
                              child: Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: Container(
                                  height: 400,
                                  child: FadeInImage.assetNetwork(fit: BoxFit.fill,
                                    placeholder: "assets/loading.gif",
                                    image: snapshot.data.cards[index].imageUrl,
                                  ),
                                ),
                              )),
                          
                        ]),
                      ),
                    ),
                  );
                });
          }
       
    

I used the imageUrl in the Yugioh class and preferred to use Gridview for viewing. I chose to use Inkwell to give cards clicks. I mentioned that the Inkwell widget should redirect the onTap feature to the yugiohDetail page. When we run the codes, we will get the following output.

app screenshot app screenshot

Create Detail Page

Let's create a structure that will display the properties of the relevant card when clicking on any card on this page.

Let's create a file named "yugiohDetail.dart" in the project directory and paste the following codes into this file.

File: yugiohDetail.dart

    
        class yugiohDetail extends StatelessWidget {

            Cards cards;
          
            yugiohDetail({this.cards});
          
            @override
            Widget build(BuildContext context) {
              return Scaffold(resizeToAvoidBottomInset: false,
                  backgroundColor: Colors.green,
                  appBar: AppBar(
                    elevation: 0,
                    title: Text(cards.title),
                  ),body:Stack(),);
            }
          }
    

In this page I created, I created a constructive method to bring the Yugioh card clicked first. We will use the Stack structure in the Body part. We will create a Card Widget in the middle of the page, insert the image of the relevant Yugioh card at the top of this Widget, and print the information of the relevant card in the Card Widget.

app card detail page

Let's continue by pasting the following codes into the "yugiohDetail.dart" file.

File: yugiohDetail.dart

    
        Stack(
      children: [
        Positioned(
          height: MediaQuery.of(context).size.height * (3 / 4),
          width: MediaQuery.of(context).size.width - 20,
          left: 10,
          top: MediaQuery.of(context).size.height * 0.1,
          child: Card(
              elevation: 3,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15)),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  SizedBox(
                    height: 200,
                  ),
                  Text(
                    "Card Name",
                    style:
                    TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
                  ),
                  Text(
                    cards.title,
                    style: TextStyle(fontSize: 15),
                  ),
                  Text(
                    "Card Effect Types",
                    style:
                    TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
                  ),
                  Text(
                    cards.effectTypes.toString(),
                    style: TextStyle(fontSize: 15),
                  ),
                  Text(
                    "Card Info",
                    style:
                    TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
                  ),
                  SingleChildScrollView(
                    child: Text(
                      cards.lore,
                      style: TextStyle(fontSize: 15),
                    ),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      Expanded(
                        child: Column(
                          children: [
                            Text(
                              "Tips",
                              style: TextStyle(
                                  fontSize: 15, fontWeight: FontWeight.bold),
                            ),
                            Chip(
                              label: Text(
                                cards.sets.map((e) => e.setName).toString(),
                                style: TextStyle(fontSize: 10),
                              ),
                            ),
                            Chip(
                              label: Text(
                                cards.sets.map((e) => e.rarity).toString(),
                                style: TextStyle(fontSize: 10),
                              ),
                            ),
                          ],
                        ),
                      )
                    ],
                  ),
                ],
              )),
        ),
        Align(
          alignment: Alignment.topCenter,
          child: Hero(
            tag: cards.id.toString(),
            child: Container(
              height: 300,
              width: 300,
              child: Image.network(
                cards.imageUrl,
                fit: BoxFit.contain,
              ),
            ),
          ),
        ),
      ],
    ),);

    

In the Card Widget, we showed the "name" of the card in our Cards class, the "property" of the card, the "lore" value where the information about the card is kept, and the "type" properties of the card.

We showed the image of the corresponding Yugioh card using the Align Widget.

Let's see how the application works.

app card detail page app card detail page app card detail page

Conclusion

In this article, we worked with APIs on Flutter. Quite simply, we have developed a Yugioh Card application with the data received by sending a request to an endpoint via the http package. You can find more information about Flutter in its official document (https://flutter.dev/).

Share:
 
Emre Savas
Written by

Emre Savas

Addicted to providing the best experience.