Preface:

I have previously shared how to package DIO. Today, LET’s share how to make network requests using Bloc. Here are some information you may need

  • Dio Package: juejin.cn/post/706552…
  • Dev /#/zh-cn/get…
  • Bloc tutorial, well written: juejin.cn/post/685626…
A: Bloc

Bloc is a state management framework that allows UI and logic to be separated and data to be reused. For example, you write a template for retrieving user information using Bloc, and then you can use bloc to retrieve user information on the home page or anywhere else

B: Bloc
  • Add the library first

    // The version of bloc 7.0.1 is installed here. The higher version is written differently

    Dependencies: flutter_bloc: 7.0.1

  • Create a network request class

    import 'dart:async';
    import 'package:dio/dio.dart';
    import 'package:flutter_network/network/network.dart';
    
    class HomeRepository {
      final Dio dio = Network.instance;
    
      Future<String> getData() async {
        // In this case, the network requests and then returns the simulated data
        final result = await Future.delayed(Duration(seconds: 2), () {
          return 'hello world';
        });
        returnresult; }}Copy the code
  • Create a template for Bloc through the plug-in

  • Creates a status enumeration that describes the status of the current network request

    enum Status {
      / / initialization
      pure,
      / / load
      progress,
      // The request succeeded
      success,
      // The request failed
      failure,
    }
    
    extension Function on Status {
      // Extend some methods of enumeration
      bool get isPure => this == Status.pure;
    
      bool get isProgress => this == Status.progress;
    
      bool get isSuccess => this == Status.success;
    
      bool get isFailure => this == Status.failure;
    }
    Copy the code
  • Change the state file to:

    part of 'home_bloc.dart';
    
    @immutable
    class HomeState {
      // Request status
      final Status status;
    
      // Data after successful request
      final String data;
    
      // Request failed error
      final Exception? exception;
    
      // Private named constructor
      HomeState._({
        required this.status,
        required this.data,
        this.exception,
      });
    
      // The factory constructor by which bloc initializes the true state
      factory HomeState.init() => HomeState._(
            status: Status.pure,
            data: ' ',);// The generated instance is returned using this method to generate a new state
      HomeState copyWith({
        Status? status,
        String? data,
        Exception? exception,
      }) =>
          HomeState._(
            status: status ?? this.status,
            data: data ?? this.data,
            exception: exception,
          );
    }
    
    
    Copy the code
  • Adds the event for the network request

    part of 'home_bloc.dart';
    
    @immutable
    abstract class HomeEvent {}
    // Network requested event
    class HomeDataLoaded extends HomeEvent {}
    Copy the code
  • Add logical processing to the above events in bloc

    import 'dart:async';
    
    import 'package:bloc/bloc.dart';
    import 'package:flutter_network/view/model/status.dart';
    import 'package:flutter_network/view/repository/home_repository.dart';
    import 'package:meta/meta.dart';
    
    part 'home_event.dart';
    part 'home_state.dart';
    
    class HomeBloc extends Bloc<HomeEvent.HomeState> {
      // An instance of the repository for network requests
      final HomeRepository repository = HomeRepository();
    
      HomeBloc() : super(HomeState.init());
    
      @override
      Stream<HomeState> mapEventToState(
        HomeEvent event,
      ) async* {
        // If this is the event, then do the inside processing
        if(event is HomeDataLoaded) {
          yield* _mapHomeDataLoadedToState();
        }
      }
    
      Stream<HomeState> _mapHomeDataLoadedToState() async* {
        // Change the state to loading
        yield state.copyWith(status: Status.progress);
    
        yield await repository.getData().then((value) {
          // Change the status to success and save the data
          return state.copyWith(status: Status.success, data: value);
        }).onError((Exception? error, stackTrace) {
          // Change the status to failed and save the error message
          returnstate.copyWith(status: Status.failure, exception: error); }); }}Copy the code
  • How to use it, look at the code

    import 'package:flutter/material.dart';
    import 'package:flutter_bloc/flutter_bloc.dart';
    import 'package:flutter_network/view/bloc/home_bloc.dart';
    import 'package:flutter_network/view/model/status.dart';
    
    class HomePage extends StatelessWidget {
      const HomePage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
    
        // Here we use BlocBuilder to wrap the widget we want to use bloc data with
        final content = BlocBuilder<HomeBloc, HomeState>(builder: (context, state) {
          return Column(
            children: [
              state.status.isProgress
                  ? CircularProgressIndicator(
                color: Colors.blue,
              )
                  : Text(
                  state.data.toString()
              ),
              IconButton(
                icon: Icon(Icons.add),
                onPressed: () {
                  context.read<HomeBloc>().add(HomeDataLoaded());
                },
              )
            ],
          );
        });
    
        return Scaffold(
          appBar: AppBar(title: Text('Bloc & Dio'),centerTitle: true),
          body: Center(
            // Create our bloc herechild: BlocProvider( create: (context) => HomeBloc(), child: content, ), ), ); }}Copy the code

  • If you want to automatically load requests as soon as the page comes in, you can add events directly to the bloc by using the cascade operator while creating the bloc

    BlocProvider( create: (context) => HomeBloc().. add(HomeDataLoaded()), child: content, )Copy the code
OK, thank you for watching. 🙂