resource_network_fetcher

Creator: coderz1093

Last updated:

Add to Cart

Description:

resource network fetcher

Resource Network Fetcher! 🧰 #








🧰 A package that provides you a way to track your request and avoid any errors. #
We use the NetworkBoundResources to make a request, process the response using then and centralize all errors
of the application to a unique function that you inject and provide a friendly message to your users.

πŸ“„ Table of Contents #

Why should I use
Examples
Install
Usage

Setup
AppException
NetworkBoundResources

asFuture
asSimpleStream
asResourceStream
asStream


Resource

Executing a function with resource
States
Loading state
Success state
Failed state


ResourceMetaData
Widgets

ListViewResourceWidget
ResourceWidget




Author
Contributing
Show your support
License

❓ Why should I use #
Resource Network Fetcher standardize your flutter project, making all your functions that can occur errors
return a same value, that is the Resource<T>. This object helps you to pass the error for the view, making a default
way to know what message to display to the user. Other thing that it does is centralize the errors with the function
called AppException errorMapper(e), that receives all errors of the application and map how you want to make the error
readable.
Other thing that it provides is the Status, that can be: Status.success,
Status.loading and
Status.error
πŸ“¦ Examples #
Examples of to-do apps that used resource_network_fetcher as base:

Example
Daily Nasa photo
Todo clean
Todo modular
Example clean
Example clean complete
Example MVC modular
Example MVC modular complete

πŸ”§ Install #
Follow this tutorial: Installation tab
Add resource_network_fetcher to your pubspec.yaml file:
dependencies:
resource_network_fetcher:
copied to clipboard
Import get in files that it will be used:
import 'package:resource_network_fetcher/resource_network_fetcher.dart';
copied to clipboard
πŸŽ‰ Usage #
Setup #
main.dart file #
import 'package:flutter/material.dart';
import 'error_mapper.dart';

void main() {
Resource.setErrorMapper(ErrorMapper.from);
runApp(MyApp());
}
copied to clipboard
error_mapper.dart #
This is an example of minimum configuration to use, you can add other parameters to map better.
import 'package:dio/dio.dart';
import 'package:resource_network_fetcher/resource_network_fetcher.dart';

abstract class ErrorMapper {
static AppException from(dynamic e) {
switch (e.runtimeType) {
case AppException:
return e;
case DioError:
return AppException(
exception: e,
message: _dioError(e),
);
default:
return AppException(
exception: e,
message: e.toString(),
);
}
}

static String _dioError(DioError error) {
switch (error.type) {
case DioErrorType.sendTimeout:
case DioErrorType.connectTimeout:
case DioErrorType.receiveTimeout:
return "Connection failure, verify your internet";
case DioErrorType.cancel:
return "Canceled request";
case DioErrorType.response:
case DioErrorType.other:
default:
}
if (error.response?.statusCode != null) {
switch (error.response!.statusCode) {
case 401:
return "Authorization denied, check your login";
case 403:
return "There was an error in your request, check the data and try again";
case 404:
return "Not found";
case 500:
return "Internal server error";
case 503:
return "The server is currently unavailable, please try again later";
default:
}
}
return "Request error, please try again later";
}
}
copied to clipboard
❌ AppException #
We use this exception to standardize the exceptions to the app
throw AppException(
message: "Error message",
exception: Exception("Error message"),
data: null,
);
copied to clipboard
↕️ Network Bound Resources #
Is a conjunction of rules that run with the Resource.asFuture and transforms the response of the fetch to the model
specified in the processResponse param.
Another use for this is using for offline-first or only to cache your requests. For that you need to use the other params
of the method.
We have other options of methods, that returns a stream or a Future.
Here is an example of how to use in a simple way:
asFuture #
Future<Resource<UserEntity>> getUser() {
return NetworkBoundResources.asFuture<UserEntity, Map<String, dynamic>>(
createCall: _getUserFromNetwork,
processResponse: UserEntity.fromMap,
);
}

Future<Map<String, dynamic>> _getUserFromNetwork() async {
return {}; /// Fetch the api
}
copied to clipboard
asSimpleStream #
Stream<Resource<UserEntity>> streamUser() {
return NetworkBoundResources.asSimpleStream<UserEntity, Map<String, dynamic>>(
createCall: _streamUserFromNetwork,
processResponse: UserEntity.fromMap,
);
}

Stream<Map<String, dynamic>> _streamUserFromNetwork() async* {
yield {}; /// Fetch the api
}
copied to clipboard
asResourceStream #
The difference of this and the asStream is that with this you can return your own Resource in createCall param.
Stream<Resource<UserEntity>> streamUser() {
return NetworkBoundResources.asResourceStream<UserEntity, Map<String, dynamic>>(
createCall: _streamUserFromNetwork,
processResponse: UserEntity.fromMap,
);
}

Stream<Resource<Map<String, dynamic>>> _streamUserFromNetwork() async* {
yield Resource.loading();
yield Resource.success(data: {}); /// Fetch the api
}
copied to clipboard
asStream #
Stream<Resource<UserEntity>> streamUser() {
return NetworkBoundResources.asStream<UserEntity, Map<String, dynamic>>(
createCall: _streamUserFromNetwork,
processResponse: UserEntity.fromMap,
);
}

Stream<Map<String, dynamic>> _streamUserFromNetwork() async* {
yield {}; /// Fetch the api
}
copied to clipboard
πŸ“œ Resource #
⏯‍️ Executing a function with resource #
Here is an example of how to run a function with the Resource, because with that, any error that occur inside will
be mapped with the ErrorMapper setted.
final result = await Resource.asFuture(() async {
/// Here you execute wherever you want and returns the result.
return ["one"];
});
print(result.isSuccess); /// Prints true
print(result.isFailed); /// Prints false
print(result.isLoading); /// Prints false
print(result.data); /// Prints the result: ["one"]
copied to clipboard
States #
We have 3 basic states, the success, loading and failed state. But each state can storage an error
so, in the total can have 6 states, that includes having or not the data.
Loading state #
final resource = Resource.loading<T>({T data});
copied to clipboard
Loading without data state
final resource = Resource.loading<List<String>>();
copied to clipboard
Loading with data state
final resource = Resource.loading<List<String>>(data: ["one"]);
copied to clipboard
Success state #
final resource = Resource.success<T>({T data});
copied to clipboard
Success without data state
final resource = Resource.success<List<String>>();
copied to clipboard
Success with data state
final resource = Resource.success<List<String>>(data: ["one"]);
copied to clipboard
Failed state #
final resource = Resource.failed<T>({dynamic error, T data});
copied to clipboard
Failed without data state
final resource = Resource.failed<List<String>>(error: AppException());
copied to clipboard
Failed with data state
final resource = Resource.failed<List<String>>(error: AppException(), data: ["one"]);
copied to clipboard
πŸ“‘ Resource MetaData #
Is an information about the last returns of the Resource, can be very useful in streams, when you need to know the last
result that was returned. If you use the NetworkBoundResources.asSimpleStream(),
NetworkBoundResources.asResourceStream() or NetworkBoundResources.asStream(), the add to the Resource.metaData is
automatic!
Here is an example that show how you can get the MetaData of a Resource.
var resource = Resource.success(data: <String>[]);
resource = resource.addData(Status.success, ["newData"]);

// Prints the metadata of the resource
print(resource.metaData);

// Prints the last data returned by this resource
print(resource.metaData.data); /// ["newData"]

// Prints the list of the lasts 2 returns of the resource
print(resource.metaData.results); /// [ ["newData"], [] ]
copied to clipboard
❇️️ Widgets #
We created widgets that helps you to summarize your code and work better with Resource<T> object, treating all the
states at your way!
πŸ”Ή ListViewResourceWidget #
Widget build(BuildContext) {
return ListViewResourceWidget(
resource: Resource.success(data: []),
loadingTile: ListTile(),
tileMapper: (data) => ListTile(),
loadingTileQuantity: 2,
refresh: () async {},
emptyWidget: Container(),
);
}
copied to clipboard
πŸ”Έ ResourceWidget #
Widget build(BuildContext) {
return ResourceWidget(
resource: Resource.success(),
loadingWidget: CircularProgressIndicator(),
doneWidget: (data) => Container(),
refresh: () async {},
errorWithDataWidget: (e, data) => Container(),
loadingWithDataWidget: (data) => Container(),
);
}
copied to clipboard
πŸ‘€ Author #
Lucas Henrique Polazzo #

Github: @LucazzP
Gitlab: @LucazzP
LinkedIn: @LucazzP

🀝 Contributing #
Contributions, issues and feature requests are welcome!
Feel free to check issues page. You can also
take a look at
the contributing guide.
πŸ’š Show your support #
Give a ⭐ and a like in Pub.dev️ if this project helped you!
πŸ“ License #
Copyright Β© 2021 Lucas Henrique Polazzo.
This project is BSD-3 Clause licensed.

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Customer Reviews

There are no reviews.