How to pass nested Json into my http API in Dart - json

I need to pass json data into my http APIs. I am not able to find the right way to do this yet. Here's my code snippet:
For all interactions to/from API, I have created an Dbhelper class.
Here's my Dbhelper class
class Dbhelper {
String fbody; // json parameter
Map result; // Response json for the api called
Dbhelper({this.fbody});
Future<void> executeData() async {
try {
//Make post request
Response response = await post('http://<my domain>/api/GetInfo',headers: {"content-type":"application/json"},body: $fbody);
var deviceinfo = jsonDecode(response.body);
print('In dbhelper $deviceinfo');
result = deviceinfo;
} catch(e) {
print('Something occured $e');
result = null;
}
}
}
This is what i am trying to do. I have login class which takes input from UI - UserName and password and need to pass this into Dbhelper object.
the intended json to be passed in my API is :
{
"strjson":{ "cUserName":"sandy" , "cPassword":"12345" },
"strSPName":"App_Userlogin"
}
toMap(String u, String p ){
return {
"strSPName":"App_userregister",
"strjson":{
"cUserName":u,
"cPassword":p
}
};
}
void _checkLogin(String u , String p) async {
try {
Map inputs = toMap(u,p);
print(inputs);
Dbhelper db = Dbhelper(fbody: inputs);
await db.executeData();
User user = User.fromJson(db.result);
if (user.uid >0)
Navigator.of(context).pushReplacementNamed('home');
else
print("User not found");
}catch(e){
print(e.toString());
User user = User(uid:0,username:'',userbalance: 0);
}
}
Please help me what I am missing in this

While passing body to http.post request . Try passing body inside single quotes.
Response response = await post('http://<my domain>/api/GetInfo',headers: {"content-type":"application/json"},body: '$fbody');
If this doesn't work, you can try encoding your body in json format using jsonEncode as shown
body: jsonEncode(<String, String> {'uname':'SomeName',})
Hope this works!

Json that I have posted in body..
{
"user": {
"UserName": "username",
"password": "password",
"Name": "name",
"Email": "email"
}
}
Your Post Api call be like:
Future<User> postUser(String username, String password, String name, String
email) async {
Paste your api url here
String url = '';
final response = await http.post(apiUrl, headers: {
// Enter your headers parameter if needed
// E.g:
'Authorization' : 'xyz',
'Content-Type' : 'application/json'
},
body: jsonEncode(<String, String>{
'UserName' : username,
'password' : password,
'Name' : name,
'Email' : email
}));
if (response.statusCode == 200) {
var data = jsonDecode(response.body.toString());
print(data);
return User.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to post user.');
}
}
Your model be like:
class User {
User? user;
User({this.user});
User.fromJson(Map<String, dynamic> json) {
user = json['user'] != null ? new User.fromJson(json['user']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.user != null) {
data['user'] = this.user!.toJson();
}
return data;
}
}
class User {
String? userName;
String? password;
String? name;
String? email;
User({this.userName, this.password, this.name, this.email});
User.fromJson(Map<String, dynamic> json) {
userName = json['UserName'];
password = json['password'];
name = json['Name'];
email = json['Email'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['UserName'] = this.userName;
data['password'] = this.password;
data['Name'] = this.name;
data['Email'] = this.email;
return data;
}
}

Related

How can I fetch data in API without giving this error

I want to retrieve some data in API, but that's giving an error . How can i get List of all posts
This is my DataModel class:
class DataModel {
DataModel({
required this.id,
required this.title,
required this.body,
});
int id;
String title;
String body;
factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
id: json["id"],
title: json["title"],
body: json["body"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"body": body,
};
}
And this is my get future data function:
Future<DataModel?> getData(context) async {
DataModel? result;
try {
final response = await http.get(
Uri.parse("https://someapi.com/posts"),); // this is example api for security
if (response.statusCode == 200) {
final data = json.decode(response.body);
result = DataModel.fromJson(data);
} else {
// ignore: avoid_print
print("error");
}
} catch (e) {
log(e.toString());
}
return result;
}
That's giving me an error like that:
type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'
I think in the reponse you are getting a list of items which has to be used like the following
var list = json.decode(response.body);
List<DataModel> result = list.map((i) => DataModel.fromJSON(i)).toList();
return result;
And the method will return
Future<List<DataModel>>?

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');
}
}
}}

How to map the jsonDecode return with User Class in flutter

Future<Map<String, dynamic>> getUserDetails(String accessToken) async {
final url = 'https://$AUTH0_DOMAIN/userinfo';
final response = await http.get(
url,
headers: {'Authorization': 'Bearer $accessToken'},
);
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to get user details');
}
}
How can I get this return value jsonDecode(response.body) to Map with the User class so I can access the name and email in another dart file.
class User {
final String name;
final String email;
User(this.name, this.email);
User.fromJson(Map<String, dynamic> json)
: name = json['name'],
email = json['email'];
Map<String, dynamic> toJson() => {
'name': name,
'email': email,
};
}
The getUserDetails is in auth.dart file, the User class is in another dart file and I have to access name and email in another dart file. PLease help.
Just call first the request like that:
var response = await ClassAuth().getUserDetails(token);
And then parse data to user object:
User user = User.fromJson(response);
String email = user.email;
You can use the Provider package to solve this problem.
You can put your value and then get it from a child widget of auth provider.

problem converting json response to object in Flutter

first all sorry about my "engrish"...
I'm trying to consume an own API method with http package in Flutter.
I'm able to get a response from API but I'm having trouble trying to map the response (json) to my custom object called APILoginResponse.
I'm calling the API method like this:
APILoginResponse apiLogin = await api.apiLogin();
but I'm getting a runtime error "dynamic is not subtype of AccessToken".
Here is my API login method:
Future<APILoginResponse> apiLogin() async {
final http.Response response = await http.post(
api_end_point + '/api/Auth/login',
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(
<String, String>{'userName': api_user, 'password': api_password}),
);
if (response.statusCode == 200) {
return APILoginResponse.fromJson(json.decode(response.body));
} else {
throw Exception('Error en login de la API');
}
}
...and here is my APILoginResponse object:
class APILoginResponse {
final AccessToken accessToken;
final String refreshToken;
APILoginResponse({this.accessToken, this.refreshToken});
factory APILoginResponse.fromJson(Map<String, dynamic> json) {
return APILoginResponse(
accessToken: json['accessToken'],
refreshToken: json['refreshToken'],
);
}
}
class AccessToken {
String token;
int expiresIn;
}
error is in the line:
accessToken: json['accessToken']
inside APILoginResponse class.
Here is my json response:
{
"accessToken": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiIiLCJzdWIiOiJib3N0b25jcmVkX2NsaWVudGVzIiwianRpIjoiZjBkMzY0ZDMtMmRkNS00NzkzLWE5ZTktMzY1YzJmODNiYmI3IiwiaWF0IjoxNTk0MTMxODAwLCJyb2wiOiJhcGlfYWNjZXNzIiwiaWQiOiIyMzg3YTMzZi1hYzE5LTRhMzYtODcyZC04MTE3MzExZDFjY2IiLCJuYmYiOjE1OTQxMzE3OTksImV4cCI6MTU5NDEzMjM5OSwiaXNzIjoid2ViQXBpIiwiYXVkIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzMTcvLyJ9.PqCPkVct4e4duWFEr63fALZ0h_0x25vsV_GBx336Apw",
"expiresIn": 600
},
"refreshToken": "W6wyiw9xYuC2UaJmyCOYujKIZTs0jAscnfcWTrEyVIk="
}
Any help with this will be appreciated. Thanks!
If you are sure that the returning value is an AccessToken you can try this:
factory APILoginResponse.fromJson(Map<String, dynamic> json) {
return APILoginResponse(
accessToken: (json['accessToken'] as Map<String,dynamic>) as AccessToken ?? null,
refreshToken: json['refreshToken'],
);
}
Change your AccessToken class to this:
class AccessToken {
final Map<String,dynamic> tokenData;
AccessToken(tokenData)
}
well I think #P4yam answer was right but I was getting the same error over and over, so I changed my APILoginResponse class as follow:
class APILoginResponse {
AccessToken accessToken;
String refreshToken;
APILoginResponse({this.accessToken, this.refreshToken});
APILoginResponse.fromJson(Map<String, dynamic> json) {
accessToken = json['accessToken'] != null
? new AccessToken.fromJson(json['accessToken'])
: null;
refreshToken = json['refreshToken'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.accessToken != null) {
data['accessToken'] = this.accessToken.toJson();
}
data['refreshToken'] = this.refreshToken;
return data;
}
}
class AccessToken {
String token;
int expiresIn;
AccessToken({this.token, this.expiresIn});
AccessToken.fromJson(Map<String, dynamic> json) {
token = json['token'];
expiresIn = json['expiresIn'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['token'] = this.token;
data['expiresIn'] = this.expiresIn;
return data;
}
}
and everything works fine now! thanks!

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