flutter_resultable 0.0.2 copy "flutter_resultable: ^0.0.2" to clipboard
flutter_resultable: ^0.0.2 copied to clipboard

A lightweight Result type for modeling success/failure in Flutter and Dart using sealed classes.

example/lib/main.dart

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

/// A simple user entity.
class User {
  final String name;
  User(this.name);
}

/// Simulates a repository that fetches a [User] from a remote or local source.
///
/// This method returns a [Result] that contains:
/// - [Result.success] if the operation is successful.
/// - [Result.failure] if the operation fails (simulated with a flag or empty input).
class UserRepository {
  Future<Result<String, User>> fetchUser({
    required String name,
    required bool fail,
  }) async {
    await Future.delayed(const Duration(milliseconds: 500));

    if (fail) return const Result.failure("This is a triggered failure");

    if (name.isNotEmpty) {
      return Result.success(User(name));
    } else {
      return Result.failure("Input cannot be empty");
    }
  }
}

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

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

/// A UI page that demonstrates how to use [Result] to handle asynchronous
/// operations that may fail or succeed.
class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final TextEditingController _nameController = TextEditingController();
  final UserRepository _repository = UserRepository();

  /// Holds the current [Result] of the latest user-fetch operation.
  Result<String, User> _isResult = Failure('Failure: is Empty');

  /// Displays a message based on the result.
  String _message = '';

  /// Shows a loading indicator during fetch.
  bool _loading = false;

  /// Handles the fetch operation using [Result.fold] to determine
  /// success or failure outcome.
  ///
  /// πŸ’‘ This is where [flutter_resultable] shines β€” you avoid nested
  /// `try-catch` or null checks by using [fold] and [Result] variants.
  Future<void> _fetchUser({
    required String name,
    required bool fail,
  }) async {
    setState(() {
      _loading = true;
      _message = '';
    });

    final result = await _repository.fetchUser(name: name, fail: fail);

    // Use `fold` to elegantly handle both success and failure branches.
    result.fold(
      (failure) => _message = '❌ Failure: $failure',
      (success) => _message = 'βœ… Success: Hello, ${success.name}',
    );

    setState(() {
      _isResult = result;
      _loading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Example')),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(32),
        child: Stack(
          children: [
            Visibility(
              visible: !_loading,
              child: Column(
                children: [
                  // πŸ‘€ Input field for the user name
                  TextField(
                    controller: _nameController,
                    decoration: const InputDecoration(
                      labelText: "Enter You'r Name",
                      border: OutlineInputBorder(),
                    ),
                  ),
                  const SizedBox(height: 32),

                  // 🎯 Buttons to trigger success or failure
                  Row(
                    children: [
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () => _fetchUser(
                            name: _nameController.text.trim(),
                            fail: false,
                          ),
                          child: const Text('Trigger Success'),
                        ),
                      ),
                      const SizedBox(width: 32),
                      Expanded(
                        child: ElevatedButton(
                          style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.red,
                          ),
                          onPressed: () => _fetchUser(
                            name: _nameController.text.trim(),
                            fail: true,
                          ),
                          child: const Text('Trigger Failure'),
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 32),

                  // πŸ“ Result message display
                  Text(
                    _message,
                    style: TextStyle(
                      fontSize: 18,
                      color: _isResult.isSuccess ? Colors.green : Colors.red,
                    ),
                  ),
                ],
              ),
            ),

            // ⏳ Loading spinner when fetching
            Visibility(
              visible: _loading,
              child: const Center(child: CircularProgressIndicator()),
            ),
          ],
        ),
      ),
    );
  }
}

void main() {
  runApp(const MyApp());
}
3
likes
140
points
44
downloads

Publisher

unverified uploader

Weekly Downloads

A lightweight Result type for modeling success/failure in Flutter and Dart using sealed classes.

Repository (GitHub)
View/report issues

Topics

#result #either #functional #error-handling #flutter

Documentation

API reference

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

freezed_annotation

More

Packages that depend on flutter_resultable