I have created an http service for handling requests and made a generic response. It works when passing the Generic as a primitive, but when passing a List (even dynamic), it throws an error during assigning. Skipping typing and casting later on doesn't work either. I am stumped.
class Room {
final String name;
const Room({required this.name});
}
List<Room> ownRoomsList = [];
List<dynamic> savedRooms = [];
Future<void> updateRooms() async {
HttpService httpService = new HttpService();
await httpService.init();
final response = await httpService.request<List<Room>>(
url: "puff/rooms", method: Method.POST);
if (response != null) {
setState(() {
ownRoomsList = response.data; // Error here.
});
}
}
class APIResponse<T> {
final bool success;
final T data;
final String message;
const APIResponse(
{required this.success, required this.data, required this.message});
factory APIResponse.fromJson(Map<String, dynamic> json) {
return APIResponse(
success: json['success'],
data: json['data'],
message: json['message'],
);
}
}
class HttpService<T> {
Dio? _dio;
var logger = Logger(
printer: PrettyPrinter(),
);
Future<HttpService> init() async {
SharedPreferences pref = await SharedPreferences.getInstance();
final userId = pref.getInt('userId');
final headers = {
"Content-Type": "application/json",
"userId": userId.toString()
};
_dio = Dio(BaseOptions(baseUrl: BASE_URL, headers: headers));
initInterceptors();
return this;
}
void initInterceptors() {
_dio!.interceptors.add(
InterceptorsWrapper(
onRequest: (requestOptions, handler) {
logger.i(
"REQUEST[${requestOptions.method}] => PATH: ${requestOptions.path}"
"=> REQUEST VALUES: ${requestOptions.queryParameters}"
"=> POST VALUES: ${requestOptions.data}"
"=> HEADERS: ${requestOptions.headers}");
return handler.next(requestOptions);
},
onResponse: (response, handler) {
logger
.i("RESPONSE[${response.statusCode}] => DATA: ${response.data}");
return handler.next(response);
},
onError: (err, handler) {
logger.i("Error[${err.response?.statusCode}]");
return handler.next(err);
},
),
);
}
Future<APIResponse<T>?> request<T>(
{required String url,
required Method method,
Map<String, dynamic>? params}) async {
Response response;
try {
if (method == Method.POST) {
response = await _dio!.post(url, data: params);
} else if (method == Method.DELETE) {
response = await _dio!.delete(url);
} else if (method == Method.PATCH) {
response = await _dio!.patch(url);
} else {
response = await _dio!.get(url, queryParameters: params);
}
if (response.statusCode == 200) {
return APIResponse.fromJson(jsonDecode(response.data));
} else if (response.statusCode == 401) {
//throw Exception("Unauthorized");
} else if (response.statusCode == 500) {
//throw Exception("Server Error");
} else {
//throw Exception("Something went wrong");
}
} on SocketException catch (e) {
logger.e(e);
//throw Exception("No Internet Connection");
} on FormatException catch (e) {
logger.e(e);
//throw Exception("Bad response format");
} on DioError catch (e) {
logger.e(e);
//throw Exception(e);
} catch (e) {
logger.e(e);
//throw Exception("Something went wrong");
}
return null;
}
}
Error:
type 'List<dynamic>' is not a subtype of type 'List<Room>'