# How to Fetch Data from the Internet in Flutter with APIs

## **API (Application Programming Interface)**

An **API (Application Programming Interface)** is like a bridge that lets two software programs talk to each other. It defines how one program can request information or services from another. For example, when you use a weather app, the app asks a weather service API for the current temperature, and the API sends back the data, like "15°C and sunny."

![](https://miro.medium.com/v2/resize:fit:700/0*6Wv21I9qLUfgDS8D.png align="left")

APIs make it easy for systems to work together. For instance, an online store might use a payment gateway API to process payments. When you enter your card details, the API sends the information securely to the bank, processes the payment, and returns a response like "Payment successful." APIs are everywhere, simplifying how apps and services communicate behind the scenes.

> "An API is like a waiter at a restaurant—it takes your request to the kitchen (server) and brings back exactly what you ordered, without you needing to know how it was prepared."

### **Store Analogy for API Requests**

1. **You (Your App)**: Want to buy something (like a new product, which in our case is **news**).
    
2. **The Store (The API)**: Sells the product you need (the **news articles**).
    
3. **Your Request (HTTP Request)**: You go to the store and ask, "Do you have any new products?" (You’re asking for the latest news).
    
4. **Store's Response (HTTP Response)**: The store gives you the latest products (news articles) if they have them, or they say "Sorry, we don’t have it right now."
    

> To use the `http` package in your Flutter project, you can simply run the command `flutter pub add http` in your terminal. This automatically adds the package to your project and installs it. Once the installation is complete, you can import the package into your Dart files using `import 'package:http/http.dart' as http;`. This allows you to easily make HTTP requests in your app.

### **Step 1: API Integration (Backend Logic)**

This file is responsible for making the API request to the "store" (NewsAPI) and retrieving the products (news).

```dart
// File: store_service.dart
import 'package:http/http.dart' as http; // To communicate with the store (HTTP client)
import 'dart:convert'; // To decode the JSON response from the store (unwrap the box)

class StoreService {
  // Function to fetch products (news) from the store (API)
  Future<List<dynamic>> fetchProducts() async {
    final url = Uri.parse(
        'https://jsonplaceholder.typicode.com/posts'); // Store's address (API URL)

    final response = await http.get(url); // Asking the store for the latest products (request)

    if (response.statusCode == 200) {
      // If the store says, "Yes, we have the products!"
      return json.decode(response.body); // Unwrap the box (JSON) and extract the products (news articles)
    } else {
      // If the store replies with an error (no products)
      throw Exception('Failed to load products'); // Show error if the store has no products
    }
  }
}
```

### **Explanation of the Code**

#### **store\_service.dart (Backend Logic)**

1. **Imports**:
    
    * We import `http` to make HTTP requests (ask the store for products) and `dart:convert` to decode the JSON data (unwrap the box containing news articles).
        
2. **StoreService Class**:
    
    * This is where we define the logic for **asking the store for products**. The `fetchProducts` function sends an HTTP request to the API URL, waits for a response, and if successful, decodes the response (JSON) to extract the product data.
        
3. **Error Handling**:
    
    * If the store has no products, we handle it with an exception (`throw Exception('Failed to load products');`).
        

![What is 200 (OK) Response Code: Meaning, Issues with 200 Status Codes](https://sitechecker.pro/wp-content/uploads/2023/09/200-status-code.png align="left")

### **Step 2: UI Page (Store Display)**

```dart
// File: store_page.dart
import 'package:flutter/material.dart'; // For UI components (store shelves)
import 'store_service.dart'; // Asking the store for products (news)

class StorePage extends StatefulWidget {
  @override
  _StorePageState createState() => _StorePageState();
}

class _StorePageState extends State<StorePage> {
  late Future<List<dynamic>> products; // Where we keep the products (news) from the store

  @override
  void initState() {
    super.initState();
    products = StoreService().fetchProducts(); // Asking the store for the latest products (news)
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Simple Store App'), // Store's name (your app title)
      ),
      body: FutureBuilder<List<dynamic>>(
        future: products, // Waiting for the store to give us the products (news)
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(child: CircularProgressIndicator()); // While waiting, show a loading symbol
          } else if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}')); // If the store has an issue (error response)
          } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
            return Center(child: Text('No products available')); // If the store has no products (empty result)
          }

          final items = snapshot.data!; // The products (items) from the store
          return ListView.builder(
            itemCount: items.length, // How many products (news items) to display
            itemBuilder: (context, index) {
              final item = items[index]; // Each individual product (news article)
              return ListTile(
                title: Text(item['title']), // Product name (news title)
                subtitle: Text(item['body']), // Product description (news body)
              );
            },
          );
        },
      ),
    );
  }
}
```

#### **store\_page.dart (UI Logic)**

1. **FutureBuilder**:
    
    * We use a `FutureBuilder` to handle the **asynchronous nature of the API request**. The app will show a loading indicator while waiting for the store to respond and will display the news when available.
        
2. **Displaying Data/News**:
    
    * Once the data is received, the `ListView.builder` dynamically creates a list of products (articles) to display, each with a title and description.
        
3. **Error Handling**:
    
    * If there’s an error or no data, appropriate error messages are displayed on the UI.
        

### **3\. Main File:** `main.dart`

This file initializes the app and opens the "store" to show the products (news).

```dart
// File: main.dart
import 'package:flutter/material.dart';
import 'store_page.dart'; // The page where we see the store products (news)

void main() => runApp(StoreApp());

class StoreApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StorePage(), // Going to the store to see the products (news)
    );
  }
}
```

## Conclusion

This article demonstrates how to fetch and display data in Flutter using the `http` package. By breaking the process into simple steps, we learned how to send API requests, decode JSON responses, handle errors, and display data dynamically using widgets like `FutureBuilder` and `ListView`. This example serves as a foundational guide for building apps that connect to APIs, enabling you to create dynamic, data-driven Flutter applications with real-time internet data integration.
