Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can i access bloc inside my API request class (widget-less class)

Tags:

flutter

dart

bloc

I'm using the flutter_bloc (https://felangel.github.io/bloc/#/gettingstarted) package which has been amazing. Currently, I have an auth bloc which holds an access token when the user is logged in.

On many of my HTTP requests, I need to send the access token to my back-end.

I am creating a re-usable function to handle all protected HTTP requests that require an access token to be sent. This will be reusable so I don't have to keep passing the access token from my UI layer to my API layer. However, I'm not sure how to access the Auth Bloc from this function since it is not in the widget tree

Data flows like so when I make an HTTP request (based on felangel's flutter bloc tutorials):

UI -> bloc -> repository -> api 
and then:
api -> repository -> bloc -> UI

I have a BlocProvider near the top of my app to provide the AuthBloc, like so:

return BlocProvider(
    builder: (BuildContext context) =>
       AuthBloc(authRepository: authRepository),
       child: Scaffold( 
...

And here is my re-usable function for protected requests. I need to access the Auth Bloc in this function, but I'm not entirely sure how to.

  Future<dynamic> protectedRequest(
      {accessToken, endpoint, dynamic body}) async {
    final uri = Uri.https(baseUrl, endpoint);
    final response = await http.post(uri,
        body: body, headers: {'Authorization': 'Bearer ' + accessToken});
    if (response.statusCode == 200 || response.statusCode == 201) {
      return response;
    } else {
      throw Exception();
    }
  }

Thank You

like image 825
wei Avatar asked Sep 18 '25 23:09

wei


1 Answers

I can offer you a package that dio(https://pub.dev/packages/dio), it could help you at HTTP Requests. You could made a http manager with using that package.

class HttpManager {
  static String token;
  static String cookie;
  final String tag;

  var _dio = Dio();
  HttpManager({this.tag}) {
    _dio.options..baseUrl = AppConfig.baseUrl;
    _dio.interceptors
        .add(InterceptorsWrapper(onRequest: (RequestOptions options) {
      if (token != null) {
        options.headers["Authorization"] = "Bearer $token";
        options.headers["cookie"] = cookie;
      }
      DioLogger.onSend(tag, options);
      return options;
    }, onResponse: (Response response) {
      DioLogger.onSuccess(tag, response);
      return response;
    }, onError: (DioError error) {
      if (error.response.statusCode == 401) {
        AuthenticationBloc().logout();
      } else if (error.response.statusCode == 400) {
        error.response.statusMessage = "400";
      }
      DioLogger.onError(tag, error);
      return error;
    }));
  }

  Dio get client => _dio;
}

And could use _dio variable at your authentication service like:

class AuthService {
  final String tag = "AuthService";
  Dio client;

  AuthService() {
    client = HttpManager(tag: tag).client;
  }

  Future<ResponseModel> authenticate(String username, String password) async {
    try {
       final response = await client.get("/myPath",
          queryParameters: {"username": username, "password": password});


      throwIfNoSuccess(response);

      HttpManager.token = response.data["token"];
      HttpManager.cookie = response.headers.value("cookie");

      return ResponseModel.fromJson(response.data);
    } catch (e) {
      throw (e);
    }
  }

  void throwIfNoSuccess(Response response) {
    print("is the response Null  : ${response.statusCode}");
    if ((response.statusCode ?? 0) < 200 || (response.statusCode ?? 0) > 299) {
      throw new HttpException(response);
    }
  }
}
like image 161
Can Karabag Avatar answered Sep 20 '25 15:09

Can Karabag