Manipulando solicitações de API com o Flutter Provider
O gerenciamento de estado é muito importante quando trabalhamos com flutter. O provedor Flutter é uma maneira muito melhor de lidar com o estado no Flutter. O pacote provider é fácil de entender e não usa muito código. Ele também usa conceitos que são aplicáveis em todas as outras abordagens.
Não precisamos manter tantos arquivos para usar o provider e a implementação é muito fácil e simples.
Vamos começar. Vou explicar o manuseio da API com uma solicitação get.
Vamos instalar o pacote. Sempre instale a versão mais recente do pacote. Adicione o pacote ao seu arquivo pubspec.yaml.
dependencies: provider: ^6.0.5
Instale o pacote. Execute o comando para obter o pacote.
flutter pub get
importe o pacote para o seu arquivo.
import 'package:provider/provider.dart';
Este é o meu modelo de dados para obter os dados da pós-API do jsonplaceholder. Podemos obter os dados com a solicitação de API getSinglePostData. Como queria brindar quando ocorre um erro, passei o contexto como parâmetro para a requisição.
lass PostModel { final int id; final int userId; final String title; final String body; PostModel({this.id, this.userId, this.title, this.body}); factory PostModel.fromJson(Map<String, dynamic> json) { return PostModel( id: json['id'], userId: json['userId'], title: json['title'] ?? "", body: json['body'] ?? "", ); } }
Future<PostModel> getSinglePostData(context) async { PostModel result; try { final response = await http.get( "https://jsonplaceholder.typicode.com/posts/1", headers: { HttpHeaders.contentTypeHeader: "application/json", }, ); if (response.statusCode == 200) { final item = json.decode(response.body); result = PostModel.fromJson(item); } else { Toast.show("Data not found", context, duration: 2, backgroundColor: Colors.redAccent); } } catch (e) { log(e); } return result; }
Podemos criar nossa classe de provedor com ChangeNotifier para notificar todos os ouvintes. Você pode criar objetos que deseja compartilhar com as outras classes. Dentro da função, adicione o método notifyListeners() para reconstruir os widgets que escutam o objeto que você deseja.
class PostDataProvider with ChangeNotifier { PostModel post = PostModel(); bool loading = false; getPostData(context) async { loading = true; post = await getSinglePostData(context); loading = false; notifyListeners(); } }
Adicione seu método principal assim. Envolva MyApp (a classe que você deseja) com MultiProvider do pacote do provedor e forneça a lista de provedores que você usa em todo o aplicativo.
void main() { runApp( MultiProvider( providers: providers, child: MyApp(), ), ); } List<SingleChildWidget> providers = [ ChangeNotifierProvider<PostDataProvider>(create: (_) => PostDataProvider()), ];
Adicione a classe MyApp() com um MaterialApp com o tema desejado e outros dados. Podemos chamar o DemoScreen dentro desta classe.
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: ProviderDemoScreen(), ); } }
My ProviderDemoScreen é simples da seguinte forma. Eu só precisava mostrar o título e o corpo da postagem da API. Eu chamei o método getPostData() dentro do initState. Podemos criar o modelo da seguinte maneira dentro do initState, mas temos que definir listen false. No método build podemos criar outro model para ouvir o objeto post do arquivo PostDataProvider.
Em seguida, postMdl.post.title e body sempre ouvirão as alterações e atualizarão o widget.
class ProviderDemoScreen extends StatefulWidget { @override _ProviderDemoScreenState createState() => _ProviderDemoScreenState(); } class _ProviderDemoScreenState extends State<ProviderDemoScreen> { @override void initState() { super.initState(); final postMdl = Provider.of<PostDataProvider>(context, listen: false); postMdl.getPostData(context); } @override Widget build(BuildContext context) { final postMdl = Provider.of<PostDataProvider>(context); return Scaffold( appBar: AppBar( title: Text("Provider Demo"), ), body: Container( padding: EdgeInsets.all(20), child: postMdl.loading ? Container( child: CircularProgressIndicator(), ) : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: EdgeInsets.only(top: 40, bottom: 20), child: Text( postMdl.post.title ?? "", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), ), ), Container( child: Text(postMdl.post.body ?? ""), ) ], ) , ), ); } }
Podemos acessar os mesmos dados de muitos arquivos usando o provedor de maneira limpa e com código de manutenção.
Para mais informações, consulte os seguintes links.
![Dart packages](https://pub.dev/static/hash-kkipkgm3/img/flutter-logo-32x32.png)
Obrigado por ler!!!