How do you add this kind of query parameters to a Dart http request? - flutter

How do you correctly add this kind of query parameters to a Dart http get request. This is my code
String? token;
String? baseUrl = 'vps';
String? path = 'web/session';
Map<String, dynamic> query ={
"jsonrpc": "1.0",
"method": "call",
"id": "2",
"params": {
"login": username,
"password": password,
"db": "dev.sf.com",
"context": {}
}
};
Uri uri = Uri.http(baseUrl.toString(), '$path/$endPath');
if (query != null) {
uri = Uri.http(baseUrl.toString(), '$path/$endPath', query);
}
return http.get(uri, headers: {
'Authorization': 'Bearer $token',
'Accept': 'application/json',
});
but i get this error
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type '_InternalLinkedHashMap<String, Object>' is not a subtype of type 'Iterable<dynamic>'

Try to send primitive types like int, string, boolean, etc. You send a Map as "params", this shouldnt work.
Map<String, dynamic> query ={
"jsonrpc": "1.0",
"method": "call",
"id": "2",
"login": username,
"password": password,
"db": "dev.sf.com",
};
Alternative (and better imo): Make a post request and send it inside the body.

Related

In Flutter Is that possible to call API request in firebase Messaging BackgroundHandler?

I have implemented chat message app in which user can
reply to chat from push
notification when app is killed/background/foreground.
But when app is in Terminated state API call not work in
firebaseMessagingBackgroundHandler.
Its stuck on sendNotification function.
Code to handle background events:
Future<void>
firebaseMessagingBackgroundHandler(RemoteMessage message)
async {
await GetStorage.init();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform);
//Call HTTP request <Stuck here
sendNotification(
personUid,
title,
body,
notificationTypeId,
chatRoomId,
userTokenDummy,
userToken,
serverKey,
currentUserId,
currentUserToken,
);
}
Here is a code for API request:
sendNotification({
required String personUid,
required String title,
required String body,
required int notificationTypeId,
String? chatRoomId,
String? userTokenDummy,
String? userToken,
String? serverKey,
String? currentUserId,
String? currentUserToken,
}) async {
try {
final response = await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
HttpHeaders.contentTypeHeader:
'application/json',
HttpHeaders.authorizationHeader: 'key=$serverKey'
},
body: jsonEncode(
<String, dynamic>{
"data": <String, dynamic>{
"title": title,
"body": body,
"click_action": "FLUTTER_NOTIFICATION_CLICK",
"id": "1",
"status": "done",
"senderId": currentUserId,
"senderToken": currentUserToken,
"notificationTypeId": notificationTypeId,
"chatRoomId": chatRoomId,
},
"android": {
"priority": "high",
},
"apns": {
"headers": {"apns-priority": "10"}
},
"to": userToken,
"content_available": true,
"mutable-content": 1,
"priority": "high",
},
),
);
return response;
} catch (e) {
console(e.toString());
}
}
Yes,you can call Http request inside firebaseMessagingBackgroundHandler. But make sure that this api is not taking too much time. Because long and intensive tasks impacts on device performance. Also make sure that there is not exception or error in the api which causes the device to freeze.
To make sure that api is not running forever place a timeout in http class.
for more refer to firebase documentation : https://firebase.google.com/docs/cloud-messaging/flutter/receive

How to send sms to user using msg91 in flutter?

I have written the api call like this:
var response = await http.post(
Uri.parse("http://api.msg91.com/api/v2/sendsms"),
headers: {
"Content-Type": "application/json",
"authkey": "API key"
},
body: jsonEncode({
"sender": "note",
"route": "4",
"country": "91",
"flash": 1,
"sms":
{"message": "Message1", "to": "9999999999"}
}),
);
But this giving me error : {type: error, message: Invalid content type.Please send data in formdata,application/xml,application/json format, code: }
How can I correct this?
Try removing theses
"Content-Type": "application/json"
or replace it with
"Content-Type": "application/xml"
You should use multipart/form-data as content-type ->
"Content-Type": "multipart/form-data"

Flutter API Call using http

I'm trying to get json data from Api by using the following
Future<SubjectList> getsubjectList(
String userId, String accountId) async {
final response = await http
.get(Uri.https(_baseUrl, 'v1/package/subject-details'), headers: {
'Content-Type': 'application/json',
'user-id': userId,
'account-id': accountId,
});
SubjectList jsonresponse = json.decode(response.body); //'_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'SubjectList'
print('This is response =$jsonresponse');
return jsonresponse;
}
I have modelled the object as follows
class SubjectList {
SubjectList({
this.subject,
this.score,
this.progress,
});
String? subject;
double? score;
String? progress;
factory SubjectList.fromMap(Map<String, dynamic> json) => SubjectList(
subject: json["subject"],
score: json["score"].toDouble(),
progress: json["progress"],
);
Map<String, dynamic> toJson() => {
"subject": subject,
"score": score,
"progress": progress,
};
}
The Data is as follows
{
"success": true,
"data": [
{
"subject": "Grammar",
"score": 57.17,
"progress": "96.77%"
},
{
"subject": "Maths",
"score": 52.12,
"progress": "73.08%"
},
{
"subject": "EVS",
"score": 55.75,
"progress": "97.96%"
},
{
"subject": "Social Studies",
"score": -1,
"progress": "-1%"
},
{
"subject": "Hindi",
"score": 51.36,
"progress": "60.87%"
},
{
"subject": "Vocabulary",
"score": 62.55,
"progress": "68.12%"
},
]
When ever i try to access using the model i'm receiving the error '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'SubjectList'. How do I get the data properly ?
Change this line
SubjectList jsonresponse = json.decode(response.body);
to something like
List<SubjectList> list = json.decode(response.body)['data'].map((d) => SubjectList.fromMap()).toList();
You can create a class for the response itself and the do the fromMap on it.

How to send large json data inside the body of http post

I need to send a large object with my post method. but it kept giving me error.
Future getResults() async {
var res = await http.post('$SERVER_IP/api/anything/search',
headers: {'Authorization': token, "Accept": "application/json"},
body: {
"name": "",
"type": "",
"organization": "",
"state": "CA",
"appliesTo": {
"Camp": "true",
"Fees": "false",
"Lessons": "false",
},
}).catchError((e) => print({"error": e}));
return json.decode(res.body);
}
I realized that body only accept Map<String, String>. So I added json.encode to my "appliesTo" object.
Future getResults() async {
var res = await http.post('$SERVER_IP/api/anything/search',
headers: {'Authorization': token, "Accept": "application/json"},
body: {
"name": "",
"type": "",
"organization": "",
"state": "CA",
"appliesTo": json.encode({
"Camp": "true",
"Fees": "false",
"Lessons": "false",
}),
}).catchError((e) => print({"error": e}));
return json.decode(res.body);
}
After that it worked and I got a returned data. But my server was ignoring whole "appliesTo" object. So I didn't get the expected data. it's not a problem in my server. I tested it with postman. this flutter http post is not sending proper json body.
So my question is how to attatch large object to the body? was using json.encode at the middle of the object wrong? what is the proper way of doing it? can anyone help?
PS: I wraped the whole Map with json.encode and it gave me error
The documentation of the http package states that
If body is a Map, it's encoded as form fields using encoding. The content-type of the request will be set to "application/x-www-form-urlencoded"; this cannot be overridden.
If you want to send JSON data instead, you have to encode the body manually. Since the content type defaults to text/plain if body is a String, you also have to set the Content-Type header explicitly.
http.post('$SERVER_IP/api/anything/search',
headers: {
'Authorization': token,
"Accept": "application/json",
"Content-Type": "application/json"
},
body: json.encode({
"name": "",
"type": "",
"organization": "",
"state": "CA",
"appliesTo": {
"Camp": "true",
"Fees": "false",
"Lessons": "false",
},
}))

Issue with uploading multi part image file with dio in Flutter

I used Dio framework to upload image to server in my flutter app. Dio version 3.0.9.
Post method.
Added 4 headers
Created form data with image and other fields.
I have analysed many more methods. Like degrading Dio to 2.3.1, to use UploadFileInfo method. Not a success. Then with multipartfileupload. Finally this one.
Future<bool> createStoreWithDio() async {
Map<String, String> headers = {
"Accept": "application/json",
"authorization": tokenString,
"authtype": "admin",
"Content-Type": "multipart/form-data"
};
try {
FormData formData = new FormData.fromMap({
"logo": await http.MultipartFile.fromPath("logo", imageFile.path,
contentType: new MediaType('image', 'png')),
"name": " Bala ios",
"description": "_description",
"website": "www.website.com",
"password": "Test password",
"user_name": "Test userInformationName",
"mobile": "9988776655",
"email": "test#techit.io",
});
print(formData.fields);
Response response = await dio
.post(
"API",
data: formData,
options: Options(
headers: headers,
),
)
.then((value) {
print(value.toString());
});
print(response.toString());
} catch (error) {
print(error);
}
}
imageFile is the file I captured from camera/ gallery.
I am getting 500 exception. Any help would be helpful
I am not sure what caused this,this code is used in an app i have change based on your code,but i am not sending any headers so you need to add then try with this code let me know it it's work for you.also make sure you have file imageFile.path also your api url is correct or not
make sure you have imported
`'import package:http_parser/http_parser.dart';
import 'package:mime/mime.dart';`
Dio dio = new Dio();
final mimeTypeData =
lookupMimeType(imageFile.path, headerBytes: [0xFF, 0xD8]).split('/');
FormData formData = FormData.fromMap({
"name": " Bala ios",
"description": "_description",
"website": "www.website.com",
"password": "Test password",
"user_name": "Test userInformationName",
"mobile": "9988776655",
"email": "test#techit.io",
"logo": await MultipartFile.fromFile(imageFile.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1])),
});
var response = await dio.post(
Urls.ImageInsert,
data: formData,
);
var message = response.data['message'];