free geoip
25

Show Loading Indicator During API Call in Dart

When working with asynchronous API calls in Flutter using Dart, it’s crucial to provide a good user experience by showing…

When working with asynchronous API calls in Flutter using Dart, it’s crucial to provide a good user experience by showing a loading indicator. Without it, users may think the app is stuck or unresponsive.

In this tutorial, you’ll learn how to display a loading spinner (CircularProgressIndicator) while an API call is being processed. We’ll use FutureBuilder and setState methods, and include a simple UI to demonstrate how to show and hide the loading indicator dynamically.

Loading indicator in API call Dart

This approach is especially useful for beginners building apps using Flutter. For a better understanding of asynchronous programming in Dart, check out Dart Asynchronous Programming Guide.

Dependencies

No additional packages needed, just use http for API calls:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
dependencies:
flutter:
sdk: flutter
http: ^0.13.5
dependencies: flutter: sdk: flutter http: ^0.13.5
dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.5

Step-by-step Code Implementation

1. Main UI (main.dart)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'api_service.dart';
void main() => runApp(MyApp());
class MyApp extends <a href="https://aliendro.id/create-ui-with-statelesswidget-in-dart/">StatelessWidget</a> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Loading Demo',
home: ApiCallPage(),
);
}
}
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'api_service.dart'; void main() => runApp(MyApp()); class MyApp extends <a href="https://aliendro.id/create-ui-with-statelesswidget-in-dart/">StatelessWidget</a> { @override Widget build(BuildContext context) { return MaterialApp( title: 'Loading Demo', home: ApiCallPage(), ); } }
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'api_service.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Loading Demo',
      home: ApiCallPage(),
    );
  }
}

2. API Call Page (api_call_page.dart)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import 'package:flutter/material.dart';
import 'api_service.dart';
class ApiCallPage extends <a href="https://aliendro.id/statefulwidget-vs-statelesswidget-in-dart-guide/">StatefulWidget</a> {
@override
_ApiCallPageState createState() => _ApiCallPageState();
}
class _ApiCallPageState extends State<ApiCallPage> {
bool isLoading = false;
String result = '';
void fetchData() async {
setState(() {
isLoading = true;
});
final data = await ApiService.getData();
setState(() {
isLoading = false;
result = data ?? 'Failed to load data';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("API Loading Example")),
body: Center(
child: isLoading
? CircularProgressIndicator()
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(result),
SizedBox(height: 20),
ElevatedButton(
onPressed: fetchData,
child: Text("Fetch Data"),
),
],
),
),
);
}
}
import 'package:flutter/material.dart'; import 'api_service.dart'; class ApiCallPage extends <a href="https://aliendro.id/statefulwidget-vs-statelesswidget-in-dart-guide/">StatefulWidget</a> { @override _ApiCallPageState createState() => _ApiCallPageState(); } class _ApiCallPageState extends State<ApiCallPage> { bool isLoading = false; String result = ''; void fetchData() async { setState(() { isLoading = true; }); final data = await ApiService.getData(); setState(() { isLoading = false; result = data ?? 'Failed to load data'; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("API Loading Example")), body: Center( child: isLoading ? CircularProgressIndicator() : Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(result), SizedBox(height: 20), ElevatedButton( onPressed: fetchData, child: Text("Fetch Data"), ), ], ), ), ); } }
import 'package:flutter/material.dart';
import 'api_service.dart';

class ApiCallPage extends StatefulWidget {
  @override
  _ApiCallPageState createState() => _ApiCallPageState();
}

class _ApiCallPageState extends State<ApiCallPage> {
  bool isLoading = false;
  String result = '';

  void fetchData() async {
    setState(() {
      isLoading = true;
    });

    final data = await ApiService.getData();

    setState(() {
      isLoading = false;
      result = data ?? 'Failed to load data';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("API Loading Example")),
      body: Center(
        child: isLoading
            ? CircularProgressIndicator()
            : Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(result),
                  SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: fetchData,
                    child: Text("Fetch Data"),
                  ),
                ],
              ),
      ),
    );
  }
}

3. API Service (api_service.dart)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import 'package:http/http.dart' as http;
import 'dart:convert';
class ApiService {
static Future<String?> getData() async {
try {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
if (response.statusCode == 200) {
final data = json.decode(response.body);
return data['title'];
} else {
return "Error: ${response.statusCode}";
}
} catch (e) {
return "Exception: $e";
}
}
}
import 'package:http/http.dart' as http; import 'dart:convert'; class ApiService { static Future<String?> getData() async { try { final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1')); if (response.statusCode == 200) { final data = json.decode(response.body); return data['title']; } else { return "Error: ${response.statusCode}"; } } catch (e) { return "Exception: $e"; } } }
import 'package:http/http.dart' as http;
import 'dart:convert';

class ApiService {
  static Future<String?> getData() async {
    try {
      final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        return data['title'];
      } else {
        return "Error: ${response.statusCode}";
      }
    } catch (e) {
      return "Exception: $e";
    }
  }
}

This simple architecture separates UI from API logic and handles loading state efficiently. You can reuse this pattern across your app for various network operations.

rysasahrial

Leave a Reply

Your email address will not be published. Required fields are marked *