Server API not accept JSON edcoded data Flutter - json

Edit:
After hours of work, i might because when i send "content-type": "application/json", it send "application/json; charset=utf-8" to server. How to remove ; charset=utf-8 from header?
Edit2:
The problem is because flutter send charset=utf-8 in Content-type. I fix by contact my backend developer to allow "application/json; charset=utf-8" in Content-type header
I send post request to server, return error
{"error":"true","code":"30","message":" Data must JSON"}
This is my code:
Future<void> _getToken() async {
final url =
Uri.parse("http://apimobile.xxxx.co.id/Apimobile/auth");
final Map<String, String> data = {
"username": "xxxx",
"password": "xxxx"
};
try {
final response = await http.post(url,
headers: {
"Content-Type": "application/json",
"accept": "application/json",
},
body: jsonEncode(data));
print(response.body);
final responseData = jsonDecode(response.body);
_token = responseData["message"];
} catch (error) {
throw error;
}
}
Is there something wrong in my code? 🤔
The API work on Postman, ThunderClient VS Code, and React Native
Thanks for your help

Create model like this:
import 'dart:convert';
LoginData loginDataFromJson(String str) => LoginData.fromJson(json.decode(str));
String loginDataToJson(LoginData data) => json.encode(data.toJson());
class LoginData {
LoginData({
required this.username,
required this.password,
});
final String username;
final String password;
factory LoginData.fromJson(Map<String, dynamic> json) => LoginData(
username: json["username"],
password: json["password"],
);
Map<String, dynamic> toJson() => {
"username": username,
"password": password,
};
#override
String toString() {
return '$runtimeType($username, $password)';
}
#override
bool operator ==(Object other) {
if (other is LoginData) {
return username == other.username && password == other.username;
}
return false;
}
#override
int get hashCode => hash2(username, password);
}
And now you can write your code like this:
Future<void> _getToken() async {
final url =
Uri.parse("http://apimobile.xxxx.co.id/Apimobile/auth");
final LoginData data = LoginData(
username: "xxxx",
password: "xxxx"
);
try {
final response = await http.post(url,
headers: {
"Content-Type": "application/json",
"accept": "application/json",
},
body: data.toJson());
print(response.body);
final responseData = jsonDecode(response.body);
_token = responseData["message"];
} catch (error) {
throw error;
}
}

The headers field in the http.post method has to be changed to have Content-Type equal to application/json and accept equal to application/json.
Future<void> _getToken() async {
final url =
Uri.parse("http://apimobile.xxxx.co.id/Apimobile/auth");
final Map<String, String> data = {
"username": "xxxx",
"password": "xxxx"
};
try {
final response = await http.post(url,
headers: {
"Content-Type": "application/json",
"accept": "application/json",
},
body: jsonEncode(data));
print(response.body);
final responseData = jsonDecode(response.body);
_token = responseData["message"];
} catch (error) {
throw error;
}
}

Try encode your data using convert
import 'dart:convert' as convert;
//...
const JsonEncoder encoder = JsonEncoder();
final response = await http.post(url,
headers: {
"Content-Type": "application/json",
"accept": "application/json",
},
body: encoder.convert(data)
);
Hope this will help

Related

Create POST request with Int key value, status code returns 422 or 415

At first, I was confused about sending an integer value to the key id. Then an error will appear type 'int' is not a subtype of type 'String' in type cast.
After a long time of fixing it, I finally managed to fix the previous error with a code like the following:
class UserData with ChangeNotifier {
Map<String, dynamic> _map = {};
bool _error = false;
String _errorMessage = '';
Map<String, dynamic> get map => _map;
bool get error => _error;
String get errorMessage => _errorMessage;
Future<void> get fetchData async {
final Map<String, dynamic> userBody = {
'id': 1,
'username': 'bunn1est',
};
String _body = jsonEncode(userBody);
final response = await http.post(
Uri.parse('https://*******'),
headers: {
"Accept": "application/json",
"content-type": "application/json",
},
body: _body,
);
if (response.statusCode <= 1000) {
try {
_map = jsonDecode(response.body);
_error = false;
} catch (e) {
_error = true;
_errorMessage = e.toString();
_map = {};
}
} else {
_error = true;
_errorMessage = "Error: It would be your internet connection";
_map = {};
}
notifyListeners();
}
void initialValues() {
_map = {};
_error = false;
_errorMessage = "";
notifyListeners();
}
}
The above code works fine, but I get the status code 422 instead. And then I get the error status code 415 if I try to remove headers inside http.post
headers: {
"Accept": "application/json",
"content-type": "application/json",
},
Is there something wrong with my class model, or is the error happening because it's from the server-side?
If the error status code 422 shows because of my code error, which part should I fix?
EDIT
I've tried it on postman, and it works fine. I still haven't figured out how to store the key value with the Integer data type
Just modify this code
final Map<String, dynamic> userBody = {
'id': 1,
'username': 'bunn1est',
};
String _body = jsonEncode(userBody);
with this
int id = 1;
final _body = {
'id': id.toString(),
'username': 'bunn1est',
};

Flutter Registration with API

I successfully can login with my API connection also can display the data in my app.
I follow the same method for the registration to send data in API So that I can login.
But the registration is not happening, although it didn't show any error. My SnackBar showing You are already registered . But When I try to login with the data which I provided in registration form, its showing user not found( Obvious reason registration process didn't perform). Is there any problem with my API MODEL?
Here is my Parameters
{
"Email":"qwer#gmail.com",
"Mobile":"1237891",
"Password":"9991",
"RetypePassword":"9991"
}
And here is the Json response
{
"Status": "1",
"Message": "You are registered successfully",
"UserData": {
"Name": "qwer#gmail.com",
"EncUserId": "IS0QOCrLby8Ft1kbkzn/mg=="
}
}
After that I created a registration form, when user click the Register button it's run my API function registrationOfuser()
Future <void> registrationOfuser(String email, contact, pass,conpass) async{
var jsonResponse ;
Map data = {
'Email': email,
'Mobile': contact,
'Password': pass,
'RetypePassword': conpass,
};
print(data);
String body = json.encode(data);
var url = 'http://myurl/home/djkjkfjkjfwkjfkwjkjfkjwjfkwjfkwf';
var response = await http.post(
url,
body: body,
headers: {
"Content-Type": "application/json",
"accept": "application/json",
"Access-Control-Allow-Origin": "*"
},
);
print(response.body);
print(response.statusCode);
if (response.statusCode == 200) {
jsonResponse = json.decode(response.body.toString());
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content:Text(" ${jsonResponse['Message']}"))) ;
//Or put here your next screen using Navigator.push() method
print('success');
} else {
print('error');
}
}
And here is my MODEL
class RegistrationApiResponse {
RegistrationApiResponse({
required this.status,
required this.message,
required this.userData,
});
String status;
String message;
//UserData userData;
UserData? userData;
factory RegistrationApiResponse.fromJson(Map<String, dynamic> json) => RegistrationApiResponse(
status: json["Status"],
message: json["Message"],
userData: json["UserData"] == null? null:UserData.fromJson(json["UserData"] as Map<String, dynamic>),
}
class UserData {
UserData({
required this.name,
required this.encUserId,
});
String name;
String encUserId;
factory UserData.fromJson(Map<String, dynamic> json) => UserData(
name: json["Name"],
encUserId: json["EncUserId"],
);
}
Try to below code help:
Create TextEditingController
final TextEditingController email = new TextEditingController();
final TextEditingController contact = new TextEditingController();
final TextEditingController password = new TextEditingController();
final TextEditingController conpassword = new TextEditingController();
Create one function for registration
register(String email, contact, pass,conpass) async {
Map data = {
'Email': email,
'Mobile': contact,
'Password': pass,
'RetypePassword': conpass,
};
print(data);
String body = json.encode(data);
var url = 'Your url here';
var response = await http.post(
url,
body: body,
headers: {
"Content-Type": "application/json",
"accept": "application/json",
"Access-Control-Allow-Origin": "*"
},
);
print(response.body);
print(response.statusCode);
if (response.statusCode == 200) {
//Or put here your next screen using Navigator.push() method
print('success');
} else {
print('error');
}
}
Create Button
ElevatedButton(
child:Text('Register'),
onPressed:(){
register(email.text, contact.text, password.text, conpassword.text);
},
),
You need to get text from controller. Do as follows:
body:({
'Email':emailController.text,
'Mobile':phoneController.text,
'Password':passwordController.text,
'RetypePassword':rePasswordController.text,
}));
class ApiService {
callloginapi(
var email,
) async {
LoginReg? userModel;
Response response = await post(
Uri.parse('http://13.127.138.139/api/Login_Register_User'),
body: {
'mobile': email,
});
var jsonResponse = jsonDecode(response.body.toString());
userModel = LoginReg.fromJson(jsonResponse);
print(jsonResponse['token']);
var flag = jsonResponse['data']['flag'];
log('==========flag ===========$flag');
//return userModel;
var message = jsonResponse['message'];
if (response.statusCode == 200) {
if (flag == 'true') {
Get.offAllNamed(PageRoutes.home);
// t
emailController.clear();
print('$message');
// moveToHome(context);
} else {
// server error
print('Not Register');
}
}
}}

Post form data to server flutter

I have been having a lot of trouble sending a post request to a server. It expects a form data type.
This is the error I get after my input.
`image: [The image must be an image.]}}
Most of my data are strings except for an int and a file Image which is selected from gallery by user.
This is my code:
dart code
if(_image!=null){
setState(() {
_isLoading = true;
});
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
var uri = NetworkUtils.host +
AuthUtils.updateSessionRequest;
Map<String, String> data = {"_method": "PATCH",
"first_name": widget.first_name,
"last_name": widget.last_name,
"phone": widget.phone,
"industry":widget.industry,
"country": widget.country,
"state": widget.state,
"fav_quote": widget.fav_quote,
"bio_interest": widget.bio_text,
"terms": "1",
"company": widget.company,
"position": widget.job_position,
"linked_in":widget.linkedin_profile,
"institution": widget.institution,
"degree": widget.degree,
"preference[0]": widget.industry};
String authToken = sharedPreferences.getString("token");
try {
final response = await http.post(
uri,
body: data,
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer ' + authToken,
},
);
final responseJson = json.decode(response.body);
print(responseJson.toString());
if (response.statusCode == 200 || response.statusCode == 201) {
//upload image to server after success response
uploadImage(_image);
NetworkUtils.showToast("Profile successfully update!");
});
} else{
setState(() {
_isLoading = false;
});
NetworkUtils.showSnackBar(_scaffoldKey, 'An error occurred. Please try again');
}
return responseJson;
} catch (exception) {
print(exception.toString());
setState(() {
_isLoading = false;
});
NetworkUtils.showSnackBar(_scaffoldKey, 'An error occurred. Please try again');
}
}
uploadImage(File image) async{
var request = http.MultipartRequest(
"POST",
Uri.parse(NetworkUtils.host +
AuthUtils.endPointUpdateProfile));
request.files.add(await http.MultipartFile.fromPath(
'image',
image.path,
));
try {
var streamedResponse = await request.send();
var response = http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
rethrow;
}
}
}
You need to pass your image like this
request.files.add(await http.MultipartFile.fromPath(
'image',
_image,
));
Here an example how to pass File and String using http
var request = http.MultipartRequest(
"POST",
Uri.parse("http://....."));
request.fields['first_name'] = widget.first_name;
request.fields['last_name'] = widget.last_name;
.....
request.files.add(await http.MultipartFile.fromPath(
'image',
path,
));
try {
var streamedResponse = await request.send();
var response = http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
rethrow;
}
From the above only, with a little modification
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void executePostMethod(String title) async {
var request = http.MultipartRequest("POST", Uri.parse("https://localhost:44377/API/GetStateList"));
request.fields['CountryID'] = "1";
// .....
//request.files.add(await http.MultipartFile.fromPath('image',path,)
//);
// send request to upload image
await request.send().then((response) async {
//print(response);
response.stream.transform(utf8.decoder).listen((value) async {
print(value);
// print("ResponseVal: $value");
if (response.statusCode == 200) {
var imgUploadData = json.decode(value);
print(imgUploadData);
} else {
throw Exception("Faild to Load!");
}
});
}).catchError((e) {
print(e);
});
}

how can i make post method in flutter?

How can i make post method in flutter for json like this
{
"app_id": "3djdjkdjde",
"include_external_user_ids": ["88"],
"contents": {"en": "your order is created"}
}
as you see its json inside json my problem in contents it's has a json as its value
i made this model with post method but i don't know how can i parse content you can see i make it's value null for now
it's okay if contents with static message no need for dynamic value in this time
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
Notifications notificationsFromJson(String str) => Notifications.fromJson(json.decode(str));
String notificationsToJson(Notifications data) => json.encode(data.toJson());
class Notifications {
String appId;
List<String> includeExternalUserIds;
Contents contents;
Notifications({
this.appId,
this.includeExternalUserIds,
this.contents,
});
factory Notifications.fromJson(Map<String, dynamic> json) => new Notifications(
appId: json["app_id"],
includeExternalUserIds: new List<String>.from(json["include_external_user_ids"].map((x) => x)),
contents: Contents.fromJson(json["contents"]),
);
Map<String, dynamic> toJson() => {
"app_id": appId,
"include_external_user_ids": new List<dynamic>.from(includeExternalUserIds.map((x) => x)),
"contents": contents.toJson(),
};
static Future<bool> postNotification(serviceUri, notificationData) async {
var client = new http.Client();
bool result = false;
try {
final Map<String, String> _notificationData = {
'app_id': notificationData['app_id'].toString(),
'include_external_user_ids': orderData['include_external_user_ids'].toString(),
"contents": null,
};
await client.post(serviceUri,
body: json.encode(_notificationData),
headers: { 'Authorization' : 'Bearer ' + notificationData['Token'], "Content-Type": "application/json"}
)
.then((http.Response response) {
var responseModel = json.decode(response.body);
if(responseModel != null && responseModel['status'] == true) {
result = true;
} else {
result = false;
}
});
}
catch(e) {
result = false;
}
finally {
client.close();
}
return result;
}
}
class Contents {
String en;
Contents({
this.en,
});
factory Contents.fromJson(Map<String, dynamic> json) => new Contents(
en: json["en"],
);
Map<String, dynamic> toJson() => {
"en": en,
};
}
thanks
Future<Map<String, dynamic>> postRequest(String url, Map jsonMap) async{
print('$url , $jsonMap');
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
String reply = await response.transform(utf8.decoder).join();
print(reply);
httpClient.close();
Map<String, dynamic>map = json.decode(reply);
return map;
}
Add this http: ^0.12.0+1 in your pubspec.yaml file

Creating flutter Json Login form with user Basic authentication

Have been stuck for quite a while on this step. can someone show me how to send a request such that upon pressing the "login" button a new instance of a user with Basic authentication is created. i would love to understand how to know how the headers are arranged to access the url database
void Login() {
final form = formKey.currentState;
if (form.validate()) {
form.save();
makePost();
}
}
second part my json methond
Future<Post> makePost() async {
String Username = "denisPos";
String Password = "moV4b90WqpHfghghsg";
final response = await http.post('http://.60.4546.109:4520/postRequest',
headers: {HttpHeaders.authorizationHeader: '$Password:$Username:$url'});
final responseJson = json.decode(response.body);
return Post.fromJson(responseJson);
}
class Post {
final String phone;
final String password;
final String body;
Post({this.phone, this.password, this.body});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
phone: json['phone'],
password: json['password'],
body: json['body'],
);
}
}
If you are talking about Basic authentication you can have something like the following code:
Future<Post> makePost() async {
String username = "denisPos";
String password = "moV4b90WqpHfghghsg";
var bytes = utf8.encode("$username:$password");
var credentials = base64.encode(bytes);
var headers = {
"Accept": "application/json",
"Authorization": "Basic $credentials"
};
var url = ...
var requestBody = ....
http.Response response = await http.post(url, body: requestBody, headers: headers);
var responseJson = json.decode(response.body);
return Post.fromJson(responseJson);
}
If you are sending a GET request you can omit the requestBody altogether.
http.Response response = await http.get(url, headers: headers);
Future<http.Response> post() async {
var url = 'http://xxxxxxxxxxxxx;
String password = "xxxxxxxxxxxxxxxx;
String username = "
var bytes = utf8.encode("$username:$password");
var credentials = base64.encode(bytes);
var headers = {
"Content-Type": "application/json",
"Authorization": "Basic $credentials"
};
var requestBody = jsonEncode({ 'phone': phone, 'pass': pass});
http.Response response = await http.post(
url, body: requestBody, headers: headers);
var responseJson = json.decode(response.body);
print(Utf8Codec().decode(response.bodyBytes));
print("Body: " + responseJson);
}