Unable to use http.post in compute() function - flutter

I'm trying to use the compute() function to trigger a top level method that calls an HTTP POST.
I can see the method being executed, but then it just hangs where I do the actual post, with no errors returned.
However if I call this without calling compute, it works fine
uploadData(Map args) {
print("uploading data"); // i see this in the logs
API().uploadData(args["data"], args["user"], args["apikey"]);
}
and it's called via
compute(uploadData, {
"data": dataList,
"user": widget.userProps,
"apikey": widget.apiKey
});
lastly this is my API uploadData method
uploadData(List files, User userdata, String apikey) async {
try {
String sessionid = await _getSession();
String _base = 'http://192.168.2.13:3000/upload';
String body = json.encode({
"api": apikey,
"user": userdata.toMap(),
"data": files,
"sessionid": sessionid
});
print("I AM HERE"); // this is called
await http.post(_base,
body: body, headers: {"Content-Type": "application/json"});
print("this is not called");
} catch (e) {
print("Error"); // no error
print(e);
}
}

you have to return, because API().uploadData returns a future (of null, I assume). If we don't return, API().uploadData is executed and then uploadData(Map args) return null value and pops out of the stack immediate; isolate has no functions, microtask queue or event queue left, it will exit.
uploadData(Map args) {
print("uploading data"); // i see this in the logs
return API().uploadData(args["data"], args["user"], args["apikey"]);
}

Related

Unable to process data from push notification in IOS

I have set up everything and i do receive a push notification but I am unable to process it. i.e I want a pop up window to show together when i receive the message. The pop
As the notification is received i want to use this function retrieveRideRequestInfo(getRideRequestId(message.data)!, context); to get the data in the notification and build a pop up window. On IOS i get Null check operator used on a null value at (message.data)!
This is the getRideRequestId function
String? getRideRequestId(Map<String, dynamic> message) {
String? rideRequestId = "";
if (Platform.isAndroid) {
// print();
rideRequestId = message['ride_request_id'];
print("This is ride request ID :$rideRequestId");
} else {
//for ios
rideRequestId = message['data'];
}
//doublenotification++;
return rideRequestId;
}
In android it works fine but in Ios I get an error Null check operator used on a null value This is at retrieveRideRequestInfo(getRideRequestId(message.data)!, context);
This is How i send the notification from another device, Is it correct ror ios ?
static sendNotificationToDriver(
String token, context, String rideRequestId) async {
try {
await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
'Authorization': serverToken,
'Content-Type': 'application/json',
},
body: jsonEncode({
"to": token,
"collapse_key": "type_a",
"notification": {
"body": "Nepali Rider",
"title": "You have a new Ride"
},
"data": {"ride_request_id": rideRequestId}
}),
);
print('FCM request for device sent!');
} catch (e) {
print(e);
}
print("ride request id :$rideRequestId");
print("ride request id :$token");
print(jsonEncode);
}

Function does not continue after catch

I have a try..catch within a dart function. When the await client.post throws an error, it does not continue after the catch, why?
#override
Future<http.Response> post(url, {Map<String, String?>? headers, body, Encoding? encoding, BuildContext? context}) async {
headers = await prepareHeaders(headers);
http.Response? response = null;
try {
response = await client.post(url, headers: headers as Map<String, String>?, body: body, encoding: encoding);
} catch (_) {
debugPrint('test'); // It comes here
}
// Does not come here
log(url: url, type: 'POST', body: body as String?, response: response!);
return await parse(response, context: context);
}
And it shouldnt. In the code below the catch, you are relying on the response object being set. If the post errors, that wont be the case, producing more errors. Move the log and the return call inside the try block.
Your code almost certainly is continuing after the catch block; it's just immediately throwing another exception. If client.post throws an exception, then response will not be set and will retain its initial value of null. However, after your catch block, you do:
log(url: url, type: 'POST', body: body as String?, response: response!);
which asserts that response is not null. That will throw a TypeError.
I don't know why you aren't observing the TypeError, but I'd suspect that you have a blanket catch block somewhere higher up in the call stack that is swallowing the exception (especially given your use of catch (_) in what code you have shown). This is why Effective Dart recommends:
Avoiding catch without on.
Not catching Errors.
The function will not execute after the catch block, the function will be terminated after the catch whenever any exception occurred then the catch block gets called. To solve this issue you can try this.
#override
Future<http.Response> post(url, {Map<String, String?>? headers, body,
Encoding? encoding, BuildContext? context}) async {
headers = await prepareHeaders(headers);
http.Response? response = null;
try {
response = await client.post(url, headers: headers as Map<String,
String>?, body: body, encoding: encoding);
log(url: url, type: 'POST', body: body as String?, response: response!);
return await parse(response, context: context);
} catch (_) {
debugPrint('test');
rethrow;
}
}

Dio instance doesnt return a response when getting a API endpoint

I am trying to get a response from an Api but there is no response in return.
Dio instance doesnt return a response when getting a API endpoint
import 'package:dio/dio.dart';
class DioService {
static const baseUrl = "https://dictionaryapi.dev/";
Dio dio = Dio();
DioService() {
initializeInterceptors();
}
initializeInterceptors() {
dio.interceptors.add(InterceptorsWrapper(onError: (e, _) {
print(e.message);
}, onRequest: (r, _) {
print(r.method);
print(r.path);
}, onResponse: (r, _) {
print(r.data);
}));
}
Future<Response> getRequest(String endPoint) async {
Response response;
try {
response = await dio.get(endPoint);
print(response.toString());
} on DioError catch (e) {
print(e);
throw Exception(e.message);
}
return response;
}
}
console :
I/flutter (17735): GET
I/flutter (17735): https://api.dictionaryapi.dev/api/v2/entries/en_US/dog
Your interceptor is routing the request into a black hole.
The second parameter to each interceptor method is a handler. In order to continue a request, the interceptor must pass (possibly modified) request options to the handler, and the same holds for the error and response handlers.
dio.interceptors.add(InterceptorsWrapper(onError: (e, handler) {
print(e.message);
handler.next(e);
}, onRequest: (r, handler) {
print(r.method);
print(r.path);
handler.next(r);
}, onResponse: (r, handler) {
print(r.data);
handler.next(r);
}));
For logging in particular, note that Dio provides a LogInterceptor class, so you don't need to roll your own.

This expression has a type of 'void' so its value can't be used

I have created a new method to use it at as recursion i am creating function to get refresh token backe from API server
void postLogin(LoginRequest loginRequest) async {
_postStream.sink.add(Result<String>.loading("Loading"));
try {
final response = await client.post('$BASE_URL\/$LOGIN_URL', headers: customHeader, body: json.encode(loginRequest));
print(response.body.toString());
if (response.statusCode == 200) {
_postStream.sink.add(Result<LoginResponse>.success(
LoginResponse.fromJson(json.decode(response.body))));
} else if(response.statusCode == 401) {
getAuthUpadate(postLogin(loginRequest));//error is showing at this place
}
else{
_postStream.sink.add(Result.error(REQUEST_ERROR));
}
} catch (error) {
print(error.toString());
_postStream.sink.add(Result.error(INTERNET_ERROR));
}
}
//////////////
i tried this function inside function in flutter it saying
void cant be allowed
getAuthUpadate(Function function()) async {
try{
final response = await client.post('$BASE_URL\/NEW_ACCESS_TOKEN_PATH', headers: customHeader,body:json.encode('RefreshToken'));
//get the refreshToken from response
String accessToken = response.body.toString();
//store this access token to the data
function();
}
catch (error){
}
}
I could give you an idea about this issue.
You are just calling the function which has return value void and passing it as a parameter to the function getAuthUpdate.
You can try something like this,
getAuthUpadate(Function function, LoginRequest loginRequest) async { }
and in the postLogin method, you could try something like this,
else if(response.statusCode == 401) {
getAuthUpadate(postLogin, loginRequest); // Just pass Reference as parameter!
}
finally, the iteration part of getAuthUpdate method,
try{
final response = await client.post('$BASE_URL\/NEW_ACCESS_TOKEN_PATH', headers: customHeader,body:json.encode('RefreshToken'));
//get the refreshToken from response
String accessToken = response.body.toString();
//store this access token to the data
function(loginRequest);
}
catch (error){
}
Hope that works!
This error happened to me when I passed in a void in a callback method (e.g. calling function() when function is declared to be void function() { ... }.
For example:
IconButton(
icon: Icon(
MdiIcons.plusCircle,
),
onPressed: _navigateToJoinQuizScreen()); // <--- Wrong, should just be _navigateToJoinQuizScreen

how to pass parameters in http get request?

i would like to pass parameters in a http get request in my flutter app. here is the code cUrl code i want to transform in a http get request.
and here is the code i want to ameliorate
Future<http.Response> getTarget(String type, String q) async {
try {
final response = await dio.Dio().get(
'https://graph.facebook.com/v2.11/search',
queryParameters: {'type': type, 'q': q, 'access_token': ACCESS_TOKEN},
);
} catch (e) {
print('Error: $e');
print(e.code);
}
}
You can checkout the following link (see examples section).
As per your question, you can send the parameters in queryParameters (as you already did) or you can pass them in the URL as in the following:
Future<http.Response> getTarget(String type, String q) async {
try {
final response = await dio.Dio().get(
"https://graph.facebook.com/v2.11/search?type=${type}&q=${q}&access_token=${ACCESS_TOKEN}"
);
} catch (e) {
print('Error: $e');
print(e.code);
}
}