async_action 1.0.0 copy "async_action: ^1.0.0" to clipboard
async_action: ^1.0.0 copied to clipboard

A library for making asynchronous actions highly reactive to state changes in Flutter UI.

example/lib/main.dart

import 'package:async_action/async_action.dart';
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AsyncAction Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const ExampleScreen(),
    );
  }
}

typedef UserProfile = ({String name, String email});

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

  @override
  State<ExampleScreen> createState() => _ExampleScreenState();
}

class _ExampleScreenState extends State<ExampleScreen> {
  // 1. Define actions in your state/viewmodel
  late final loginAction = AsyncAction0<String>(_simulateLogin);
  
  // Example using AsyncAction1 with a typedef for params
  late final fetchProfileAction = AsyncAction1<UserProfile, String>(_fetchProfile);

  Future<Result<String>> _simulateLogin() async {
    await Future.delayed(const Duration(seconds: 2));
    // Simulated random failure
    if (DateTime.now().millisecond % 5 == 0) {
      return Result.error(Exception('Network timeout'));
    }
    return const Result.ok('User logged in!');
  }

  Future<Result<UserProfile>> _fetchProfile(String userId) async {
    await Future.delayed(const Duration(seconds: 1));
    return Result.ok((name: 'John Doe', email: 'john@example.com'));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('AsyncAction Example'), centerTitle: true),
      body: Padding(
        padding: const EdgeInsets.all(24.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const Text(
              'Simulated Login Action',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            
            // 2. Use AsyncActionButton for automatic loading/error handling
            AsyncActionButton.elevated(
              action: loginAction,
              onTap: loginAction.execute,
              errorBuilder: (context) => const Text('Error! Tap to retry'),
              child: const Text('Login'),
            ),
            
            const SizedBox(height: 32),
            
            const Text(
              'Profile Data (Reactive Builder)',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),

            // 3. Use buildWidget extension for reactive data views
            fetchProfileAction.buildWidget(
              builder: (context, profile, child) {
                return Card(
                  child: ListTile(
                    title: Text(profile.name),
                    subtitle: Text(profile.email),
                    leading: const Icon(Icons.person),
                  ),
                );
              },
              loadingBuilder: (context) => const Center(
                child: Padding(
                  padding: EdgeInsets.all(8.0),
                  child: CircularProgressIndicator(),
                ),
              ),
              errorBuilder: (context, error) => TextButton.icon(
                onPressed: () => fetchProfileAction.execute('123'),
                icon: const Icon(Icons.refresh),
                label: const Text('Fetch Profile'),
              ),
            ),
            
            const Spacer(),
            
            // 4. Manually handling states with ListenableBuilder
            ListenableBuilder(
              listenable: loginAction,
              builder: (context, _) {
                if (loginAction.completed) {
                  return Text(
                    'Success: ${(loginAction.result! as Ok).value}',
                    textAlign: TextAlign.center,
                    style: const TextStyle(color: Colors.green),
                  );
                }
                return const SizedBox.shrink();
              },
            ),
          ],
        ),
      ),
    );
  }
}
2
likes
160
points
108
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A library for making asynchronous actions highly reactive to state changes in Flutter UI.

Repository (GitHub)
View/report issues

Topics

#async #state-management #ui-reactivity #flutter

License

MIT (license)

Dependencies

flutter

More

Packages that depend on async_action