Flutter: Parsing JSON array - flutter

I'm trying out http requests from flutter to my backend.
My JSON is like this:
"_hits": {
"Do8HpM3w0mh99SF": {
"docid": "Do8HpM3w0mh99SF"
},
"HNLvkccTCIlmrcQ": {
"docid": "HNLvkccTCIlmrcQ"
},
"QNSInDU2BJMF5SD": {
"docid": "QNSInDU2BJMF5SD"
},
"UVDfRueZXIVCssk": {
"docid": "UVDfRueZXIVCssk"
},
"Y9bNKklTr2Sg6Ai": {
"docid": "Y9bNKklTr2Sg6Ai"
},
"kJgwwMbgF6PBwmMJSiKC": {
"docid": "kJgwwMbgF6PBwmMJSiKC"
},
"py5MbGK11SsbXQ1": {
"docid": "py5MbGK11SsbXQ1"
}
}
My code to request:
Future<SearchResults> fetchJson() async {
final response =
await http.get('MyWebsite.com');
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
// print(response.body);
return SearchResults.fromJson(json.decode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load request');
}
}
The Search Results Class:
class SearchResults {
final String hits;
SearchResults({this.hits});
factory SearchResults.fromJson(Map<String, dynamic> json) {
return SearchResults(
hits: json['_hits'],
);
}
}
What I'm trying to achieve:
Print the value of docid under the array of _hits
Coming From iOS Swift, this is very new to me, any input is greatly appreciated.

Your SearchResuts object is wrong as _hits is not a String but a Map<String, dynamic> to do it simple :
class SearchResults {
Map<String, dynamic> hHits;
SearchResults({this.hHits});
SearchResults.fromJson(Map<String, dynamic> json) {
hHits = json['_hits'];
}
}
From here, you can iterate on your docids by getting a list of _hits elements like this :
print(searchResults.hHits.values.toList());
will print
[{docid: Do8HpM3w0mh99SF}, {docid: HNLvkccTCIlmrcQ}, {docid: QNSInDU2BJMF5SD}, {docid: UVDfRueZXIVCssk}, {docid: Y9bNKklTr2Sg6Ai}, {docid: kJgwwMbgF6PBwmMJSiKC}, {docid: py5MbGK11SsbXQ1}]

Related

I am getting flutter at the start in my response. Even when my response does not include flutter before the List of Objects

Get request using dio package.
void fetchData() async {
try {
var response = await dio.get(
"http://localhost:8888/api/screen",
);
if (response.statusCode == 200) {
setState(() {
lineData = response.data;
});
}
} on DioError catch (err) {
print(err);
}
}
Getting response after printing lineData. This flutter keyword is added to my data.
flutter: [{_id: id1, day: 1, data: 7.3, percent: 1.3}, {_id: id2, day: 2, data: 1.2,
percent: 0.5}]
Server response in post man. Without flutter at the start.
[
{
"_id": "<id1>",
"day": 1,
"data": 7.3,
"percent": 1.3
},
{
"_id": "<id2>",
"day": 2,
"data": 1.2,
"percent": 0.5
}
]
change this code
void fetchData() async {
try {
var response = await dio.get(
"http://localhost:8888/api/screen",
);
if (response.statusCode == 200) {
setState(() {
lineData = jsonDecode(response.data);
});
}
} on DioError catch (err) {
print(err);
}
}
Probably, you are printing your response on your debug console. If you are trying to print this response, IDE will always add a flutter append to your response.
You can try to show this response on your screen (for example, with Text())

How to receive the response of a POST request using flutter

I am new to flutter and am trying to receive a response that is returned when I do a post request. I want to display the response object in a preview modal however, i am stuck on how to go about it. I have so far been able to hit the post endpoint successfully and a console.log shows me the response as I expected. How can I receive the response and assign it to a variable that I can then pass to a view modal?
Here is what I have done so far:
/* The Post DbRequest */
Future < Reservation ? > priceReservation(Reservation priceReservation) async {
var content = jsonEncode(priceReservation.toJson());
const baseUrl = ApiEndPoint.baseUrl;
searchUrl = '$baseUrl/reservation/price';
var response = await http.post(
Uri.parse(searchUrl),
body: content,
headers: {
"Content-Type": "application/json"
},
);
final data = json.decode(response.body);
if (response.statusCode == 202) {
print(data);
return data;
} else
print(data);
return null;
}
/* The Post Service */
priceReservation(priceReservation) async {
ReservationDbRequests requests = ReservationDbRequests();
Reservation ? reservation =
await requests.priceReservation(priceReservation);
return reservation;
}
/* How can I receive the response in this save method and assign it the data variable */
_save() async {
if (_formKeyBooking.currentState!.validate()) {
Reservation reservationObject = new Reservation(
roomId: _roomController.text,
email: _emailController.text,
quantity: _quantityController.text.toString(),
checkInDate: DateTime.parse(_checkInController.text),
checkOutDate: DateTime.parse(_checkOutController.text),
);
Response data = await Provider.of < BookingService > (context, listen: false)
.priceReservation(reservationObject);
print(data);
setState(() {
_isLoading = false;
});
toastMessage(ToasterService.successMsg);
} else {
toastMessage(ToasterService.errorMsg);
}
}
// Here is my response
{
"id": "c204b78b-cae3-44ea-9aaf-2f439488fef9",
"email": "adeleke#email.com",
"quantity": 1,
"nights": 5,
"totalPricePerRoomPerNight": 134.07,
"totalPrice": {
"rooms": 615.0,
"discounts": 0.0,
"taxes": 55.35,
"total": 670.35
},
"room": {
"id": "d54986a8-4e00-4332-8edc-acf6e380f6c4",
"name": "villa",
"price": 123.0
},
"checkInDate": "2021-09-29T12:00:00+03:00",
"checkOutDate": "2021-10-04T12:00:00+03:00",
"taxes": [
{
"name": "room services",
"percent": 9.0,
"amount": 11.07
}
],
"discounts": []
}
will this help? check this artilcle for json serilization for complex response
Future <Map<String,dynamic>?> priceReservation(Reservation priceReservation) async {
//you API access code goes here
//check the status first before decoding
if (response.statusCode == 200) { //got the response with data
return json.decode(response.body);
} else if (response.statusCode == 204) { //got the response but no data
return null;
} else { //throw exception for other status code
throw 'error';
}
}
/* The Post Service */
Future<Map<String,dynamic>?> priceReservation(priceReservation) async {
ReservationDbRequests requests = ReservationDbRequests();
Map<String,dynamic>? response =
await requests.priceReservation(priceReservation);
return response;
}
//view
Map<String,dynamic>?> response = await Provider.of < BookingService > (context, listen: false)
.priceReservation(reservationObject);
print(response); //now it should be a Map
if(response != null){
print(response); //all response
print(response['id']); //access id
print(response['email']); //access email
print(response['room']['name']); //access room name
}

Push array into list flutter

So i'm trying to create a list with objects of type 'MessageListItem'. I'm trying to push data returned from my API into the list. The variable I want it pushed into is 'messages'. I am getting an error in the 'getMessages()' function.
The error I am getting is: A value of type 'MessageListItem' can't be assigned to a variable of type 'List'.
The API call & code is:
List<MessageListItem> messages;
getMessages() async {
List<MessageListItem> res = MessageListItem.fromJson(await getMessageList());
// I'm getting the error on the line above.
print(res);
}
Future<dynamic> getMessageList() async {
final response = await http.get(baseUrl + 'message/jxchumber');
print(response.statusCode);
if (response.statusCode == 200) {
var res = json.decode(response.body);
return res;
} else {
throw Exception('Failed to get data');
}
}
MessageListItem Class
class MessageListItem {
int id;
int senderId;
int recipientId;
String senderUsername;
String recipientUsername;
int itemId;
String messageContentString;
bool read;
dynamic dateTimeSent;
MessageListItem(
{this.id,
this.senderId,
this.recipientId,
this.senderUsername,
this.recipientUsername,
this.itemId,
this.messageContentString,
this.read,
this.dateTimeSent});
factory MessageListItem.fromJson(Map<String, dynamic> json) {
return MessageListItem(
id: json['id'],
senderId: json['senderId'],
recipientId: json['recipientId'],
senderUsername: json['senderUsername'],
recipientUsername: json['recipientUsername'],
itemId: json['itemId'],
messageContentString: json['messageContentString'],
read: json['read'],
dateTimeSent: json['dateTimeSent'],
);
}
}
The data being returned from the API is:
[
{
"id": 4,
"senderId": 1,
"recipientId": 3,
"senderUsername": "jxchumber",
"recipientUsername": "pavster31",
"itemId": 0,
"messageContentString": "hello1",
"read": false,
"dateTimeSent": "2020-12-14T22:23:55.1473414"
},
{
"id": 3,
"senderId": 1,
"recipientId": 9,
"senderUsername": "jxchumber",
"recipientUsername": "larsen",
"itemId": 0,
"messageContentString": "hello1",
"read": false,
"dateTimeSent": "2020-12-14T16:04:50.8232055"
}
]
I'm trying to push it into the variable 'messages'
Try this
getMessages() async {
var list = await getMessageList();
List<MessageListItem> res = list.map((i)=>MessageListItem.fromJson(i)).toList();
}

Can't access Nested array object flutter

I have set of data, with some details,when i try to display the the one value returns null,other 2 data is fine,but if i try to show other data it's shows null,if i try to add that to setState,everything become null,There is no problem when i get the "Description","imagepath" i can show it, but the data from the replys object doesn't show
JSON
{
"doc": {
"image": {
"Description": "tested",
"replay": " ",
"Image_Rating": 0,
"replay_status": 0,
"Report_Date": "1591228800",
"Status": 1,
"_id": "5ed88ae73025a4445568ece3",
"image_path": "http://xxx.xxx.xxx.xxx:xxx/area_images/1670281356001.jpg",
"Created_User_Id": "5ed22c2507a33e2c1cf3a3a5",
"Branch_Id": "5ed22bf807a33e2c1cf3a3a4",
"image_temp_path": "http://xxx.xxx.xxx.xxx:xxx/area_images_temp/1670281356001.jpg",
"Order_Id": 32425,
"reg_date": "1591249638163",
"Area_Id": "5dc11c4046c214298f85e2e0",
"Section_Id": "5dc1097546c214298f85e2ae",
"Report_Time_Type": 1,
"mapperId": "5ed22c4207a33e2c1cf3a3a6",
"Created_At": "Thursday, June 4th, 2020, 11:17:18 AM",
"__v": 0
},
"replays": [
{
"replay": "Good\n",
"Report_Date": "1590796800",
"_id": "5ed248e0c1a47a3e8c4ce8bb"
}
]
}
}
Code
Future<String> getImageView(String imageid) async {
Future token = SharedPrefrence().getToken();
token.then((data) async {
var token = data;
var response = await http.post(Urls.Image_Details,
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer $token",
},
body: json.encode({
"imageId": imageid,
}));
if (response.statusCode == 200) {
try {
var resp = response.body;
Map<String, dynamic> value = json.decode(resp);
var name = value['doc']['image'];
Description = name["Description"].toString();
image_path = name["image_path"].toString();
replay = name["replays"]["replay"].toString();
setState(() {
Description = name["Description"].toString();
image_path = name["image_path"].toString();
// replay = name["replays"]["replay"].toString();
});
} catch (e) {
e.toString();
}
}
});
}
"replays" is an array. Try this: name["replays"][0]["replay"].toString()
By adding [0] it will get your first object from that array.
EDIT:
After looking at your json some more I see that name is the wrong object.
"replays" is a member of "doc" not of "image".
I think this should work:
replay = value['doc']["replays"][0]["replay"].toString();
The problem is
"replays": [
{
"replay": "Good\n",
"Report_Date": "1590796800",
"_id": "5ed248e0c1a47a3e8c4ce8bb"
}
]
This is a List of Maps. So as we access the first element in the list you should use
replay= value['doc']["replays"][0]["replay"].toString();
that is the zeroth element of the list.

How to handle difference responses API?

How to handle the difference between the results of a successful and failed fire response?
RESPONSE SUCCESS:
{
"header":{
"status":true,
"respcode":"00",
"message":"Successfully."
},
"data":{
"userid":"3485345",
"password":"3423424",
"bit18":"0000",
}
}
RESPONSE FAILED:
{
"header":{
"status":false,
"respcode":"01",
"message":"Userid Tidak Terdaftar"
},
"data":""
}
assuming you'll always have headers in your responses, you can do something like this:
Map<String, dynamic> res1 = {
"header": {"status": true, "respcode": "00", "message": "Successfully."},
"data": {
"userid": "3485345",
"password": "3423424",
"bit18": "0000",
}
};
Map<String, dynamic> res2 = {
"header": {
"status": false,
"respcode": "01",
"message": "Userid Tidak Terdaftar"
},
"data": ""
};
// bla = res2 for failed case
final bla = res1;
if (bla['header']['status']) {
print(res1['data']['userid']);
// do your success code here
} else {
// do your fail code here
print('fail');
}
I don't know why in the failed case, data is string (and not object). In theory, the failed case should have an empty object instead of a string. Any way, assuming you don't have control over the server's response, you might want to do something like below :
(The first two lines I wrote just to make sure the parsing works.)
Map<String, dynamic> mData = {
"header":{
"status":true,
"respcode":"00",
"message":"Successfully."
},
"data":{
"userid":"3485345",
"password":"3423424",
"bit18":"0000",
}
};
String jData = json.encode(mData);
Map<String, dynamic> decodedBody = json.decode(jData);
print(decodedBody["header"]["respcode"]); // prints 00
if (decodedBody['header']['status'])
{
User user = User.fromJson(decodedBody['data']);
print(user.userId); // This prints 3485345
}
else {
// login failed
}
And the User model is defined as below :
class User {
final String userId;
final String password;
final String bit18;
User({#required this.userId, #required this.password, this.bit18});
User.fromJson(Map json)
: this.userId = json['userid'],
this.password = json['password'],
this.bit18 = json['bit18'];
}