smart_fetch 1.0.7 copy "smart_fetch: ^1.0.7" to clipboard
smart_fetch: ^1.0.7 copied to clipboard

Beautiful full-screen error pages for server side errors and no internet connection state.

example/smart_fetch_example.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:smart_fetch/smart_fetch.dart';

// Example: Using SmartFetch.call() with SnackBar
// final result = await SmartFetch.call(
//   () => http.get(Uri.parse('https://api.example.com/data')),
//   context: context,
//   errorSnackBar: const SnackBar(
//     content: Text('Request failed. Please try again.'),
//     backgroundColor: Colors.red,
//   ),
// );

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SmartFetch Example',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const LoginExamplePage(),
    );
  }
}

class LoginExamplePage extends StatefulWidget {
  const LoginExamplePage({super.key});

  @override
  State<LoginExamplePage> createState() => _LoginExamplePageState();
}

class _LoginExamplePageState extends State<LoginExamplePage> {
  final emailController = TextEditingController(text: 'test@example.com');
  final passwordController = TextEditingController(text: 'password123');
  bool shouldLogin = false;
  int loginTrigger = 0;

  @override
  void dispose() {
    emailController.dispose();
    passwordController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SmartFetch Login Example'),
        backgroundColor: Colors.blue,
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'Testing SmartFetch.builder()',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 30),
            TextField(
              controller: emailController,
              decoration: const InputDecoration(
                labelText: 'Email',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: passwordController,
              obscureText: true,
              decoration: const InputDecoration(
                labelText: 'Password',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 30),
            if (!shouldLogin)
              SizedBox(
                width: double.infinity,
                height: 50,
                child: ElevatedButton(
                  onPressed: () {
                    setState(() {
                      shouldLogin = true;
                      loginTrigger++;
                    });
                  },
                  style: ElevatedButton.styleFrom(backgroundColor: Colors.blue),
                  child: const Text(
                    'Login with SmartFetch',
                    style: TextStyle(fontSize: 16, color: Colors.white),
                  ),
                ),
              )
            else
              SizedBox(
                height: 200,
                child: SmartFetch.builder(
                  key: ValueKey('login_fetch_$loginTrigger'),
                  future: () {
                    final body = {
                      "email": emailController.text,
                      "password": passwordController.text,
                    };
                    final headers = {
                      "Content-Type": "application/json",
                      "Accept": "application/json",
                    };
                    return http.post(
                      Uri.parse('https://api.example.com/login'),
                      headers: headers,
                      body: jsonEncode(body),
                    );
                  },
                  loadingWidget: const Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        CircularProgressIndicator(color: Colors.blue),
                        SizedBox(height: 16),
                        Text('Logging in...'),
                      ],
                    ),
                  ),
                  onSuccess: (context, response) {
                    if (response.statusCode == 200) {
                      try {
                        return const Center(
                          child: Text('Login Successful!'),
                        ); // TODO: Add your success widget here
                      } catch (e) {
                        WidgetsBinding.instance.addPostFrameCallback((_) {
                          if (mounted) {
                            setState(() {
                              shouldLogin = false;
                            });
                          }
                        });
                        return Center(
                          child: Card(
                            color: Colors.red.shade50,
                            child: Padding(
                              padding: const EdgeInsets.all(16.0),
                              child: Text('Error: $e'),
                            ),
                          ),
                        );
                      }
                    } else {
                      WidgetsBinding.instance.addPostFrameCallback((_) {
                        if (mounted) {
                          setState(() {
                            shouldLogin = false;
                          });
                        }
                      });
                      return Center(
                        child: Card(
                          color: Colors.red.shade50,
                          child: Padding(
                            padding: const EdgeInsets.all(16.0),
                            child: Column(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                const Icon(
                                  Icons.error,
                                  color: Colors.red,
                                  size: 48,
                                ),
                                const SizedBox(height: 8),
                                Text(
                                  'Login Failed!',
                                  style: TextStyle(
                                    fontSize: 18,
                                    fontWeight: FontWeight.bold,
                                    color: Colors.red.shade700,
                                  ),
                                ),
                                const SizedBox(height: 8),
                                Text(
                                  'Status: ${response.statusCode}',
                                  style: const TextStyle(fontSize: 14),
                                ),
                              ],
                            ),
                          ),
                        ),
                      );
                    }
                  },
                  timeout: const Duration(seconds: 10),
                  // Optional: Show SnackBar when error occurs
                  // errorSnackBar: const SnackBar(
                  //   content: Text('Login failed. Please try again.'),
                  //   backgroundColor: Colors.orange,
                  //   duration: Duration(seconds: 4),
                  // ),
                  onError: (context, error) {
                    WidgetsBinding.instance.addPostFrameCallback((_) async {
                      final errorScreen =
                          error.isTimeout
                              ? const TimeoutScreen()
                              : error.isNoInternet
                              ? const NoInternetScreen()
                              : const ServerErrorScreen();

                      await Navigator.push(
                        context,
                        MaterialPageRoute(builder: (_) => errorScreen),
                      );

                      if (mounted) {
                        setState(() {
                          shouldLogin = false;
                        });
                      }
                    });
                    return const SizedBox.shrink();
                  },
                ),
              ),
          ],
        ),
      ),
    );
  }
}
2
likes
150
points
151
downloads

Publisher

unverified uploader

Weekly Downloads

Beautiful full-screen error pages for server side errors and no internet connection state.

Repository (GitHub)

Topics

#flutter #error-handling #timeout #no-internet #server-error

Documentation

API reference

License

MIT (license)

Dependencies

connectivity_plus, flutter, http, lottie

More

Packages that depend on smart_fetch