๐ŸŒ Lesson 11: Fetch Live Data

โฑ 35-45 min ๐Ÿ“Š Advanced ๐Ÿ“– In-depth tutorial ๐Ÿ”— Official Source
0

The Complete Data Pipeline: Internet โ†’ Your App

๐Ÿง  Your CLI app can talk to the entire internet using HTTP requests

With the package:http package, Dart can send HTTP requests to any REST API, receive JSON responses, and integrate live data into your application. The official tutorial uses the Wikipedia API as a real-world example.

๐Ÿ’ป Your Dart App
โ†’
๐Ÿ“ก HTTP GET
package:http
โ†’
๐ŸŒ Wikipedia API
โ†’
๐Ÿ“ฅ JSON Response
โ†’
๐Ÿ—๏ธ jsonDecode()
+ Model Class
1

HTTP Requests with package:http

๐Ÿง  The http package provides simple functions for all HTTP methods

Add package:http to your pubspec.yaml dependencies. Then use http.get(), http.post(), http.put(), or http.delete() to make requests. Each returns a Future<Response>.

Setting Up

# pubspec.yaml
dependencies:
  http: ^1.3.0

Making a GET Request โ€” Line by Line

// 1. Import the http package
import 'package:http/http.dart' as http;
import 'dart:convert';

Future<void> fetchData() async {
  // 2. Build the URL using Uri.parse()
  final url = Uri.parse(
    'https://api.example.com/data'
  );
  
  // 3. Send the GET request (returns Future<Response>)
  final response = await http.get(url);
  
  // 4. Check if the request succeeded
  if (response.statusCode == 200) {
    // 5. Decode the JSON body
    final data = jsonDecode(response.body);
    print(data);
  } else {
    // 6. Handle failure
    print('Request failed: \${response.statusCode}');
  }
}

๐Ÿ“ Breakdown

1 Import with as http for clarity
2 Also import dart:convert for jsonDecode
4 Function must be async โ€” network is async
6 Uri.parse() creates a valid URI object
11 await pauses until response arrives
14 Always check statusCode first!
16 jsonDecode converts body to Map/List
19 Handle non-200 responses gracefully
๐Ÿ“Œ The Response object contains: statusCode (int), body (String), headers (Map), and isRedirect (bool). Always check statusCode before using body.
2

The Official Tutorial โ€” Fetching from Wikipedia

๐Ÿ“– This complete example comes directly from the official Dart fetch-data tutorial

The official tutorial demonstrates fetching live data from Wikipedia's REST API. Below is the complete example with explanations.

๐Ÿง  The Wikipedia REST API provides article summaries at a simple URL pattern

The URL pattern is: https://en.wikipedia.org/api/rest_v1/page/summary/ARTICLE_TITLE. You replace ARTICLE_TITLE with the Wikipedia page title (spaces become underscores).

The Complete Wikipedia Fetch Example (from the official tutorial)

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

Future<void> main() async {
  // The Wikipedia page we want
  final title = 'Dart_(programming_language)';
  
  // Build the API URL
  final url = Uri.parse(
    'https://en.wikipedia.org/api/rest_v1/page/summary/\$title'
  );
  
  // Make the HTTP GET request
  final response = await http.get(url);
  
  // Check if successful
  if (response.statusCode == 200) {
    // Parse the JSON response
    final data = jsonDecode(response.body);
    
    // Extract and display the title and extract
    print('๐Ÿ“„ \${data['title']}');
    print('\${data['extract']}');
  } else {
    print('Failed to load article: \${response.statusCode}');
  }
}

๐Ÿ“ What This Code Does

1-2 Import http and dart:convert
4 main() async โ€” entry point is async
6 Wikipedia article title (underscores for spaces)
9-11 Construct the REST API URL
9 Uri.parse() validates and creates URI
14 await http.get(url) โ€” the actual network call
17 Check for HTTP 200 (success)
19 jsonDecode(response.body) parses JSON
22-23 Access data['title'] and data['extract']

What the Wikipedia API Returns

{
  "title": "Dart (programming language)",
  "displaytitle": "Dart",
  "pageid": 33033735,
  "extract": "Dart is a programming language developed by Google...",
  "extract_html": "<p>Dart is a programming language...</p>",
  "thumbnail": {
    "source": "https://upload.wikimedia.org/...",
    "width": 320
  },
  "content_urls": {
    "desktop": {
      "page": "https://en.wikipedia.org/wiki/Dart_(programming_language)"
    }
  }
}
๐Ÿ”‘ Key Fields in the Response: title (the article title), extract (a plain-text summary of the article โ€” perfect for CLI display), and content_urls.desktop.page (link to the full article).

๐Ÿงช Simulate: Fetch a Wikipedia Article

Enter an article title and click Fetch...
3

Understanding HTTP Status Codes

๐Ÿง  Every HTTP response includes a 3-digit status code that tells you what happened

Codes are grouped by the first digit: 2xx = success, 3xx = redirect, 4xx = client error (your fault), 5xx = server error (their fault). Always check the status code before processing the response body.

โœ… 2xx โ€” Success

Your request worked.

200 OK 201 Created

response.statusCode == 200

๐Ÿ”„ 3xx โ€” Redirect

Resource moved elsewhere.

301 Moved

http package follows redirects automatically

โŒ 4xx โ€” Client Error

You made a mistake.

400 Bad Request 404 Not Found 429 Rate Limited

Check your URL and parameters

๐Ÿ’ฅ 5xx โ€” Server Error

The server broke.

500 Internal Error 503 Unavailable

Retry later with backoff

Click a status code to see handling code...
4

Error Handling & Retry Logic

๐Ÿง  Network requests can fail in many ways. Your app needs to handle them all.

Network errors (no connection), timeouts, rate limiting, and server errors all require different handling strategies. The most robust approach is retry with exponential backoff.

Common Network Errors and How to Handle Them

try {
  final response = await http.get(url)
      .timeout(Duration(seconds: 10));
  
  if (response.statusCode == 200) {
    return jsonDecode(response.body);
  } else if (response.statusCode == 404) {
    throw NotFoundException('Article not found');
  } else if (response.statusCode == 429) {
    print('Rate limited โ€” waiting before retry');
    await Future.delayed(Duration(seconds: 60));
    return fetchData(); // Retry after waiting
  } else {
    throw HttpException('Server error: \${response.statusCode}');
  }
} on TimeoutException {
  print('Request timed out โ€” check your connection');
} on SocketException {
  print('No internet connection');
}

Retry with Exponential Backoff

Future<T> fetchWithRetry<T>(
  Future<T> Function() request,
  {int maxRetries = 3}
) async {
  for (int attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await request()
          .timeout(Duration(seconds: 10));
    } catch (e) {
      if (attempt == maxRetries) rethrow;
      // Wait longer each attempt: 2s, 4s, 8s
      final delay = Duration(seconds: 2 * attempt);
      await Future.delayed(delay);
      print('Retry \$attempt/\$maxRetries after \${delay.inSeconds}s');
    }
  }
}

๐Ÿ“ How It Works

1-5 Generic function โ€” works with any return type
7 Loop for each retry attempt
9 try the request with a timeout
12 On failure, check if this was the last try
12 rethrow on final attempt โ€” gives up
14 Exponential: 2ร—1=2s, 2ร—2=4s, 2ร—3=6s
15 Wait before retrying

๐Ÿงช Simulate Network Scenarios

Select a scenario to see how it's handled...
5

Putting It All Together โ€” A Complete Wikipedia Client

๐Ÿง  Combining HTTP requests, JSON parsing, status code handling, and retry logic into a reusable function

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

class WikipediaClient {
  static const _baseUrl = 'https://en.wikipedia.org/api/rest_v1/page/summary/';
  
  /// Fetches a Wikipedia article summary
  Future<Map<String, dynamic>> fetchArticle(String title) async {
    final url = Uri.parse('\$_baseUrl\$title');
    
    try {
      final response = await http.get(url)
          .timeout(Duration(seconds: 10));
      
      return switch (response.statusCode) {
        200 => jsonDecode(response.body),
        404 => throw Exception('Article not found: \$title'),
        _ => throw HttpException('HTTP \${response.statusCode}'),
      };
    } on TimeoutException {
      throw Exception('Request timed out');
    } on SocketException {
      throw Exception('No internet connection');
    }
  }
}

// Usage in main()
Future<void> main() async {
  final client = WikipediaClient();
  try {
    final article = await client.fetchArticle('Dart_(programming_language)');
    print('๐Ÿ“„ \${article['title']}');
    print(article['extract']);
  } catch (e) {
    print('โŒ Error: \$e');
  }
}

๐ŸŽฏ Fetch Data Quiz

Score: 0/5 | Hints: 3

Loading question...

๐Ÿš€

Practice Projects

Apply what you've learned by building these hands-on projects.

๐Ÿ“ฆ Project 1 ๐Ÿ“ฆ Project 2