riverpod_action_listener 0.0.5 copy "riverpod_action_listener: ^0.0.5" to clipboard
riverpod_action_listener: ^0.0.5 copied to clipboard

A Riverpod extension package that provides a standardized pattern for handling one-off actions (like API calls) and their UI side effects.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:riverpod_action_listener/riverpod_action_listener.dart';

// 1. Initialize Global Config
void main() {
  ActionListenerConfig.initialize(
    onError: (context, error, stack) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Global Error Handler: $error'),
          backgroundColor: Colors.red,
        ),
      );
    },
  );

  runApp(const ProviderScope(child: MyApp()));
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: const LoginScreen());
  }
}

// 2. Define Action Notifier
class LoginNotifier extends ActionNotifier<ActionResult<String>> {
  @override
  ActionResult<String> build() => const ActionResult.idle();

  Future<void> login(String userId) async {
    state = const AsyncValue.loading();

    // Simulate network delay
    await Future.delayed(const Duration(seconds: 1));

    if (userId == 'error') {
      state = AsyncValue.error('Invalid Credentials', StackTrace.current);
    } else {
      state = AsyncValue.data(ActionResult.success('Token_$userId'));
    }
  }
}

final loginProvider =
    AsyncNotifierProvider<LoginNotifier, ActionResult<String>>(
      LoginNotifier.new,
    );

// 3. UI Implementation
class LoginScreen extends HookConsumerWidget {
  const LoginScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final usernameController = useTextEditingController(text: 'user123');
    final statusText = useState<String>('Idle');

    // 4. Use Hook
    useActionListener(
      ref,
      loginProvider,
      onSuccess: (token) {
        statusText.value = 'Login Success! Token: $token';
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('Login Success! Navigating...'),
            backgroundColor: Colors.green,
          ),
        );
      },
      onError: (error, stack) {
        // Global handler is called automatically.
        // This is for additional local handling.
        statusText.value = 'Login Failed: $error';
      },
    );

    return Scaffold(
      appBar: AppBar(title: const Text('Action Listener Example')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: usernameController,
              decoration: const InputDecoration(
                labelText: 'Username (type "error" to fail)',
              ),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                ref.read(loginProvider.notifier).login(usernameController.text);
              },
              child: const Text('Login'),
            ),
            const SizedBox(height: 32),
            Text('Status: ${statusText.value}'),
          ],
        ),
      ),
    );
  }
}
0
likes
150
points
14
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Riverpod extension package that provides a standardized pattern for handling one-off actions (like API calls) and their UI side effects.

Repository (GitHub)
View/report issues

Topics

#riverpod #state-management #hooks #side-effects #pattern

License

MIT (license)

Dependencies

flutter, flutter_hooks, hooks_riverpod, riverpod

More

Packages that depend on riverpod_action_listener