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

outdated

ValueNotifier and ValueListenableBuilder but for asynchronous value.

example/lib/main.dart

import 'dart:math';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:sura_flutter/sura_flutter.dart';
import 'package:sura_manager/sura_manager.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SuraProvider(
      errorWidget: (error, onRefresh) {
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(error.toString()),
              TextButton(
                  onPressed: onRefresh, child: const Icon(Icons.refresh)),
            ],
          ),
        );
      },
      child: MaterialApp(
        title: 'Sura Manager Example',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

late FutureManager<int> dataManager = FutureManager(
  reloading: true,
  onError: (err) {},
);

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    dataManager.asyncOperation(() async {
      await Future.delayed(const Duration(milliseconds: 1500));
      //bool error = false;
      //Random().nextBool();
      //if (error) throw "Error while getting data";
      //debugPrint("Get data done");
      return Random().nextInt(20);
    });

    dataManager.addListener(() {
      debugPrint(dataManager.toString());
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    //Use with FutureManagerBuilder
    return Scaffold(
      appBar: AppBar(
        title: const Text("FutureManager example"),
      ),
      body: FutureManagerBuilder<int>(
        futureManager: dataManager,
        onRefreshing: () => const RefreshProgressIndicator(),
        loading: const Center(child: CircularProgressIndicator()),
        onError: (err) {
          //debugdebugPrint("We got an error: $err");
        },
        onData: (data) {
          debugPrint("We got a data: $data");
        },
        ready: (context, data) {
          debugPrint("Rebuild");
          return Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text("My data: $data"),
                const SpaceY(24),
                ElevatedButton(
                  onPressed: () async {
                    await dataManager.modifyData((data) {
                      return data! + 10;
                    });
                  },
                  child: const Text("Add 10"),
                ),
                const SpaceY(24),
                ElevatedButton(
                  onPressed: dataManager.refresh,
                  child: const Text("Refresh"),
                ),
                const SpaceY(24),
                ElevatedButton(
                  onPressed: () => dataManager.refresh(reloading: false),
                  child: const Text("Refresh without reload"),
                ),
                const SpaceY(24),
                ElevatedButton(
                  onPressed: dataManager.resetData,
                  child: const Text("Reset"),
                ),
              ],
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          SuraPageNavigator.push(context, const SuraManagerWithPagination());
        },
        child: const Icon(Icons.assessment),
      ),
    );
  }
}

class SuraManagerWithPagination extends StatefulWidget {
  const SuraManagerWithPagination({Key? key}) : super(key: key);

  @override
  _SuraManagerWithPaginationState createState() =>
      _SuraManagerWithPaginationState();
}

class _SuraManagerWithPaginationState extends State<SuraManagerWithPagination> {
  FutureManager<UserResponse> userController = FutureManager();
  int currentPage = 1;
  int maxTimeToShowError = 0;

  Future fetchData([bool reload = false]) async {
    await Future.delayed(const Duration(seconds: 1));
    if (reload) {
      currentPage = 1;
    }
    userController.asyncOperation(
      () async {
        if (currentPage > 1 && maxTimeToShowError < 2) {
          maxTimeToShowError++;
          throw "Expected error thrown from asyncOperation";
        }

        final response = await Dio().get(
          "https://express-boilerplate-dev.lynical.com/api/user/all",
          queryParameters: {
            "page": currentPage,
            "count": 10,
          },
        );
        return UserResponse.fromJson(response.data);
      },
      onSuccess: (response) {
        if (userController.hasData) {
          response.users = [...userController.data!.users, ...response.users];
        }
        currentPage += 1;
        return response;
      },
      reloading: reload,
    );
  }

  @override
  void initState() {
    dataManager.addError(100, useMicrotask: true);
    fetchData();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Fetch all users with pagination")),
      body: FutureManagerBuilder<UserResponse>(
        futureManager: userController,
        ready: (context, UserResponse response) {
          return SuraPaginatedList(
            itemCount: response.users.length,
            hasMoreData: response.hasMoreData,
            padding: EdgeInsets.zero,
            hasError: userController.hasError,
            itemBuilder: (context, index) {
              final user = response.users[index];
              return ListTile(
                leading: const CircleAvatar(
                  child: Icon(Icons.person),
                ),
                onTap: () {},
                title: Text("${index + 1}: ${user.firstName} ${user.lastName}"),
                subtitle: Text(user.email!),
              );
            },
            dataLoader: fetchData,
            errorWidget: Column(
              children: [
                Text(userController.error.toString()),
                IconButton(
                  onPressed: () {
                    userController.addError(null, updateViewState: false);
                    fetchData();
                  },
                  icon: const Icon(Icons.refresh),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

class UserResponse {
  List<UserModel> users;
  final Pagination? pagination;

  UserResponse({this.pagination, required this.users});

  bool get hasMoreData =>
      pagination != null ? users.length < pagination!.totalItems : false;

  factory UserResponse.fromJson(Map<String, dynamic> json) => UserResponse(
        users: json["data"] == null
            ? []
            : List<UserModel>.from(
                json["data"].map((x) => UserModel.fromJson(x))),
        pagination: json["pagination"] == null
            ? null
            : Pagination.fromJson(json["pagination"]),
      );
}

class UserModel {
  UserModel({
    this.id,
    this.email,
    this.firstName,
    this.lastName,
    this.avatar,
  });

  String? id;
  String? email;
  String? firstName;
  String? lastName;
  String? avatar;

  factory UserModel.fromJson(Map<String, dynamic> json) => UserModel(
        id: json["_id"],
        email: json["email"],
        firstName: json["first_name"],
        lastName: json["last_name"],
        avatar: json["profile_img"],
      );
}

class Pagination {
  Pagination({
    required this.page,
    required this.totalItems,
    required this.totalPage,
  });

  num page;
  num totalItems;
  num totalPage;

  factory Pagination.fromJson(Map<String, dynamic> json) => Pagination(
        page: json["page"] ?? 0,
        totalItems: json["total_items"] ?? 0,
        totalPage: json["total_page"] ?? 0,
      );
}
4
likes
0
points
150
downloads

Publisher

verified publisherasurraa.com

Weekly Downloads

ValueNotifier and ValueListenableBuilder but for asynchronous value.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, rxdart, sura_flutter

More

Packages that depend on sura_manager