Open In App

Flutter – Make an HTTP GET Request

Last Updated : 16 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In app development, the ability to fetch data from external sources, such as REST APIs, is a fundamental requirement. In Flutter, Whether you need to fetch data from a RESTful API, access a database, or retrieve content from a web server, Flutter provides you with the tools and packages(HTTP) to do this kind of API calls easily. Here we will explore how to interact with external data sources, retrieve JSON data, and integrate it into your Flutter application.

Required Tools

To build this app, you need the following items installed on your machine:

  • Visual Studio Code / Android Studio
  • Android Emulator / iOS Simulator / Physical Device device.
  • Flutter Installed
  • Flutter plugin for VS Code / Android Studio.

About the API

This is a joke API that gives Random joke in each API call.

API Request method:

GET - https://api.chucknorris.io/jokes/random

JSON Data Fromat (Sample):

{
"categories": [],
"created_at": "2020-01-05 13:42:28.984661",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "plj3-pqiRWuomVQKAy_AwQ",
"updated_at": "2020-01-05 13:42:28.984661",
"url": "https://api.chucknorris.io/jokes/plj3-pqiRWuomVQKAy_AwQ",
"value": "Chuck Norris can have his cake, eat it, then roundhouse kick you in the face with the extra power it gave him."
}

Step By Step Implementations

Step 1: Create a New Project in Android Studio

To set up Flutter Development on Android Studio please refer to Android Studio Setup for Flutter Development, and then create a new project in Android Studio please refer to Creating a Simple Application in Flutter.

Step 2: Add the dependency to our project

In the pubspec.yaml file we have to add the below dependency for the http package which provide varrious API call methods.

dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
http: ^1.1.0


Step 3: Import the Package

First of all import material.dart file.

import 'package:flutter/material.dart';


Step 4: Create the DataModel for the JSON

Here we are going to create a DataModel class to retrieve our jokes from the API.

Dart




class Joke {
  String id;
  String value;
  
  Joke.fromJson(Map<String, dynamic> json)
      : id = json['id'],
        value = json['value'];
}


Step 5: Execute the main Method

Here the execution of our app starts.

Dart




void main() {
  runApp(MyApp());
}


Step 6: Create MyApp Class

In this class we are going to implement the MaterialApp , here we are also set the Theme of our App.

Dart




class MyApp extends StatefulWidget {
  const MyApp({super.key});
  
  @override
  State<MyApp> createState() => _MyAppState();
}
  
class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.green, // Set the app's primary theme color
      ),
      home: APICall(),
    );
  }
}


Step 7: Create APICall Class

In this class we are going to make HTTP GET request to the API endpoint and fetch the data from it.

Dart




class APICall extends StatefulWidget {
  @override
  State<APICall> createState() => _APICallState();
}
  
class _APICallState extends State<APICall> {
  // Function to fetch a random Chuck Norris joke from an API
  Future<Joke> fetchJoke() async {
    final response =
        await http.get(Uri.parse("https://api.chucknorris.io/jokes/random"));
  
    if (response.statusCode == 200) {
      return Joke.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to fetch joke');
    }
  }
  
  // Function to change and update the displayed joke
  void changeJoke() {
    setState(() {
      // Rebuild the widget to fetch and display a new joke
      build(context);
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Chuck Norris Jokes'), // Set the app bar title
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            margin: EdgeInsets.all(20),
            padding: EdgeInsets.all(20),
            child: FutureBuilder<Joke>(
              future: fetchJoke(),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  // Display the fetched joke when data is available
                  return Center(child: Text(snapshot.data!.value));
                } else if (snapshot.hasError) {
                  // Display an error message if there's an error
                  return Text('${snapshot.error}');
                } else {
                  // Display a loading indicator while waiting for data
                  return Center(child: CircularProgressIndicator());
                }
              },
            ),
          ),
          ElevatedButton(onPressed: changeJoke, child: Text("Next Joke")) // Button to fetch a new joke
        ],
      ),
    );
  }
}


Here is the full Code of main.dart file

Dart




// Importing necessary libraries and packages
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
  
// Assuming Joke.dart contains the Joke class definition
import 'package:httpget/Joke.dart'
  
void main() {
  runApp(MyApp()); // Entry point of the Flutter application
}
  
// Defining the main application widget
class MyApp extends StatefulWidget {
  const MyApp({super.key});
  
  @override
  State<MyApp> createState() => _MyAppState();
}
  
// Defining the state for the main application widget
class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.green, // Set the app's primary theme color
      ),
      home: APICall(), // Display the APICall widget as the home screen
    );
  }
}
  
// Widget responsible for making API calls and displaying jokes
class APICall extends StatefulWidget {
  @override
  State<APICall> createState() => _APICallState();
}
  
class _APICallState extends State<APICall> {
  // Function to fetch a random Chuck Norris joke from an API
  Future<Joke> fetchJoke() async {
    final response =
        await http.get(Uri.parse("https://api.chucknorris.io/jokes/random"));
  
    if (response.statusCode == 200) {
      return Joke.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to fetch joke');
    }
  }
  
  // Function to change and update the displayed joke
  void changeJoke() {
    setState(() {
      // Rebuild the widget to fetch and display a new joke
      build(context);
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Chuck Norris Jokes'), // Set the app bar title
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            margin: EdgeInsets.all(20),
            padding: EdgeInsets.all(20),
            child: FutureBuilder<Joke>(
              future: fetchJoke(),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  // Display the fetched joke when data is available
                  return Center(child: Text(snapshot.data!.value));
                } else if (snapshot.hasError) {
                  // Display an error message if there's an error
                  return Text('${snapshot.error}');
                } else {
                  // Display a loading indicator while waiting for data
                  return Center(child: CircularProgressIndicator());
                }
              },
            ),
          ),
          // Button to fetch a new joke
          ElevatedButton(onPressed: changeJoke, child: Text("Next Joke")) 
        ],
      ),
    );
  }
}


Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads