我如何在我的 API 请求 class 中访问 bloc(无小部件 class)
how can i access bloc inside my API request class (widget-less class)
我正在使用 flutter_bloc (https://felangel.github.io/bloc/#/gettingstarted) 软件包,它非常棒。目前,我有一个 auth bloc,它在用户登录时持有一个访问令牌。
在我的许多 HTTP 请求中,我需要将访问令牌发送到我的后端。
我正在创建一个可重复使用的函数来处理所有需要发送访问令牌的受保护 HTTP 请求。这将是可重复使用的,因此我不必一直将访问令牌从我的 UI 层传递到我的 API 层。但是,我不确定如何从此函数访问 Auth Bloc,因为它不在小部件树中
当我发出 HTTP 请求时,数据流是这样的(基于 felangel 的 flutter bloc 教程):
UI -> bloc -> repository -> api
and then:
api -> repository -> bloc -> UI
我的应用程序顶部附近有一个 BlocProvider 来提供 AuthBloc,如下所示:
return BlocProvider(
builder: (BuildContext context) =>
AuthBloc(authRepository: authRepository),
child: Scaffold(
...
这是我的受保护请求的可重用函数。我需要在此函数中访问 Auth Bloc,但我不太确定如何访问。
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();
}
}
谢谢
我可以为您提供一个 dio(https://pub.dev/packages/dio) 包,它可以帮助您处理 HTTP 请求。您可以使用该包制作一个 http 管理器。
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;
}
并且可以在您的身份验证服务中使用 _dio 变量,例如:
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);
}
}
}
我正在使用 flutter_bloc (https://felangel.github.io/bloc/#/gettingstarted) 软件包,它非常棒。目前,我有一个 auth bloc,它在用户登录时持有一个访问令牌。
在我的许多 HTTP 请求中,我需要将访问令牌发送到我的后端。
我正在创建一个可重复使用的函数来处理所有需要发送访问令牌的受保护 HTTP 请求。这将是可重复使用的,因此我不必一直将访问令牌从我的 UI 层传递到我的 API 层。但是,我不确定如何从此函数访问 Auth Bloc,因为它不在小部件树中
当我发出 HTTP 请求时,数据流是这样的(基于 felangel 的 flutter bloc 教程):
UI -> bloc -> repository -> api
and then:
api -> repository -> bloc -> UI
我的应用程序顶部附近有一个 BlocProvider 来提供 AuthBloc,如下所示:
return BlocProvider(
builder: (BuildContext context) =>
AuthBloc(authRepository: authRepository),
child: Scaffold(
...
这是我的受保护请求的可重用函数。我需要在此函数中访问 Auth Bloc,但我不太确定如何访问。
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();
}
}
谢谢
我可以为您提供一个 dio(https://pub.dev/packages/dio) 包,它可以帮助您处理 HTTP 请求。您可以使用该包制作一个 http 管理器。
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;
}
并且可以在您的身份验证服务中使用 _dio 变量,例如:
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);
}
}
}