我有以下方法:
enum RequestMethod {
get,
put,
post,
delete,
}
typedef FromJson<T> = T Function(Map<String, dynamic>);
class ApiHelper {
Future<T?> apiRequest<T>(
String endPoint,
RequestMethod method, {
FromJson<T>? create,
Object body = '',
bool secure = false,
}) async {
Response resp;
final Map<String, String> headers = new Map<String, String>();
headers.putIfAbsent(
HttpHeaders.contentTypeHeader,
() => 'application/json',
);
headers.putIfAbsent(
HttpHeaders.acceptHeader,
() => 'application/json',
);
if (secure) {
final String? token = await SecureStorage().getToken();
headers.putIfAbsent(
HttpHeaders.authorizationHeader,
() => 'Bearer $token',
);
}
Uri url = Uri.https(
apiUrl,
endPoint,
);
try {
if (method == RequestMethod.get) {
resp = await http.get(
url,
headers: headers,
);
} else if (method == RequestMethod.put) {
resp = await http.put(
url,
headers: headers,
body: jsonEncode(body),
);
} else if (method == RequestMethod.post) {
resp = await http.post(
url,
headers: headers,
body: jsonEncode(body),
);
} else {
resp = await http.delete(
url,
headers: headers,
);
}
switch (resp.statusCode) {
case 200:
{
// Get JSON object
var data = json.decode(resp.body);
// Parse the response form the API
var api = ApiResponse<T>.fromJson(data, create);
if (api.status.isSuccess) {
/* Return the data from the API response */
return api.data;
}
/* Something went wrong, return message to the user */
throw ApiException(api.status.message);
}
case 400:
throw BadRequestException(resp.body);
case 401:
case 403:
throw UnauthorisedException(resp.body);
case 500:
case 404:
default:
throw FetchDataException(resp.statusCode);
}
} on TimeoutException {
throw FetchDataException('Tiempo de espera agotado');
} on SocketException {
throw FetchDataException('Sin conexión');
} on Error catch (e) {
throw FetchDataException('Error general: $e');
}
}
}
class ApiResponse<T>{
final T? data;
final APIStatus status;
ApiResponse({
required this.status,
required this.data,
});
factory ApiResponse.fromJson(
Map<String, dynamic> json,
FromJson<T>? create,
) =>
new ApiResponse(
status: APIStatus.fromJson(json["status"]),
data: (json['data'] != null) ? create!(json['data']) : null,
);
}
一些API方法返回一个对象,因此data != null
,而其他方法返回data = null
,例如:
@override
Future signUp(
String username,
String password,
String firstname,
String lastname,
String phone,
) async {
return await api.apiRequest(
"api/user/signUp",
RequestMethod.get,
body: {
"email": username,
"password": password,
"firstname": firstname,
"lastname": lastname,
"phone": phone
},
secure: false,
);
}
该方法不期望任何返回。
在这两种情况下,我应该如何调用apiRequest
来在下面的方法中强制使用一个非空的SignIn
对象?
@override
Future<SignIn> signIn(
String username,
String password,
) async {
return await api.apiRequest<SignIn>(
"api/user/signIn",
RequestMethod.post,
create: (json) => SignIn.fromJson(json),
body: {
"email": username,
"password": password,
},
secure: false,
)!;
}
我得到了:
A value of type 'SignIn?' can't be returned from the method 'signIn' because it has a return type of 'Future<SignIn>'.
在这两种情况下,我应该如何调用apiRequest
,以便没有可空的SignIn
对象可以被强制执行?
1条答案
按热度按时间e0bqpujr1#
你几乎得到了它,你只需要在
await api.Request
周围添加括号,因为否则它将强制未来为非空,而不是未来的结果。