I need to make a list of messages, I have this model
enum MessageType {sent, received}
class Messages {
MessageType status;
String contactName;
String message;
String time;
Messages({ this.status, this.message, this.contactName, this.time});
}
And this way to make a list
final response = await http.get(url);
if(response.statusCode == 200){
print(response.body);
var allMessages = (json.decode(response.body) as Map)['messages'] as Map<String, dynamic>;
var MessagesList = List<Messages>();
allMessages.forEach((String key, dynamic val){
var record = Messages(contactName: val['ownerName'], message: val['body'], time: '123', status: );
});
I have two questions.
How can I substitute the value 'received' in status?
2.how to set received or sent depending on which id?
If id = 1, then put 'received', if other then put 'sent'
You should do something like this.
Convert your JSON to a List of Message using a custom "fromJson" method and, during the conversion, set the MessageType as needed.
enum MessageType { sent, received }
class Message {
MessageType status;
String contactName;
String message;
String time;
Message({this.status, this.message, this.contactName, this.time});
factory Message.fromJson(Map<String, dynamic> json) => Message(
status: json["status"] == 1 ? MessageType.received : MessageType.sent,
contactName: json["contactName"],
message: json["message"],
time: json["time"],
);
}
Future<List<Message>> getMessage() async {
final response = await http.get(url);
if (response.statusCode == 200) {
print(response.body);
List<Message> allMessages = List<Message>.from(
json.decode(response.body).map((x) => Message.fromJson(x)));
return allMessages;
}
}
You should be able to just use an inline ternary operator like this: testCondition ? trueValue : falseValue
implemented in your code would look like this:
allMessages.forEach((String key, dynamic val){var record = Messages(
contactName: val['ownerName'],
message: val['body'],
time: '123',
status: id==1 ? MessageType.received : MessageType.sent);
});
Hope this helps!
Related
Im trying to make a searchbar that fetch data from mysql , but i have a problem that when i call data fetch function it returns
Instance of '_Future<List>'
this is my code
Future<List<Students>> getStudents(String id) async {
var url = 'http://localhost/getStudents.php';
final response = await http.post(Uri.parse(url), body: {
'id':id,
});
var res = jsonDecode(response.body)['fname'] as List;
if (response.statusCode == 200) {
return res.map((std) => Students.fromJson(std)).toList();
}else {
throw Exception('Failed to load shows');
}
}
my class :
class Students{
final int id;
final String fname;
final String sname;
final String tname;
const Students( {
required this.id,
required this.sname,
required this.tname,
required this.fname,
});
factory Students.fromJson(Map<String, dynamic> json) => Students(
id: json['Id'],
sname: json['secname'],
tname:json['thirdname'] ,
fname: json['firstname'],
);
}
getStudents is a future function and you need to await for it:
List<Students> result = await getStudents('');
My debug statement is displaying the database correctly, by after something is going wrong and in getting the error: Unhandled Exception: NoSuchMethodError: Class 'int' has no instance method '[]'. I am getting null data when I'm trying to display is in my application, this is because the list i am using to store the values has length 0
following is my class
class UserDetails extends ChangeNotifier {
final String? userId;
final String? mobileno;
bool? userStatus;
final String? adhar;
final String? pan;
final String? adharno;
final String? panno;
UserDetails(
{this.userId,
this.mobileno,
this.userStatus = false,
this.adhar,
this.pan,
this.adharno,
this.panno});
}
following is my api where I am facing error
Future<void> getUsers(BuildContext context) async {
final url = '${PurohitApi().baseUrl}${PurohitApi().users}';
final List<UserDetails> loadedUsers = [];
try {
final client = RetryClient(
http.Client(),
retries: 4,
when: (response) {
return response.statusCode == 401 ? true : false;
},
onRetry: (req, res, retryCount) async {
//print('retry started $token');
if (retryCount == 0 && res?.statusCode == 401) {
var accessToken = await Provider.of<Auth>(context, listen: false)
.restoreAccessToken();
// Only this block can run (once) until done
req.headers['Authorization'] = accessToken;
}
},
);
var response = await client.get(
Uri.parse(url),
headers: {'Authorization': authToken!},
);
final extractedData = json.decode(response.body) as Map<String, dynamic>;
print(extractedData);
if (extractedData['data'] == null) {
return;
}
extractedData.forEach((userId, userData) {
print(userId);
loadedUsers.add(
UserDetails(
userId: userData['data']['id'],
mobileno: userData['data']['mobileno'],
userStatus: userData['data']['userstatus'],
adhar: userData['data']['adhar'],
pan: userData['data']['pan'],
adharno: userData['data']['adharno'],
panno: userData['data']['panno'],
),
);
});
_users = loadedUsers.reversed.toList();
//print(users);
notifyListeners();
} catch (e) {
print(e);
}
}
}
I am facing NoSuchMethodError: Class 'int' has no instance method '[]'Tried calling: from above api following is my response
I think userId should not be String, It should be an integer
class UserDetails extends ChangeNotifier {
final int? userId;
final String? mobileno;
bool? userStatus;
final String? adhar;
final String? pan;
final String? adharno;
final String? panno;
UserDetails(
{this.userId,
this.mobileno,
this.userStatus = false,
this.adhar,
this.pan,
this.adharno,
this.panno});
}
try to print your data in this error I think your data should be like userData['id'],
the above error is you try to use int as an object in the data returned
the returned userData is an int
change this code :
extractedData.forEach((userId, userData) {
print(userId);
loadedUsers.add(
UserDetails(
userId: userData['data']['id'],
mobileno: userData['data']['mobileno'],
userStatus: userData['data']['userstatus'],
adhar: userData['data']['adhar'],
pan: userData['data']['pan'],
adharno: userData['data']['adharno'],
panno: userData['data']['panno'],
),
);
});
to this :
loadedUsers.add(
UserDetails(
userId: extractedData['data']['id'],
mobileno: extractedData['data']['mobileno'],
userStatus: extractedData['data']['userstatus'],
adhar: extractedData['data']['adhar'],
pan: extractedData['data']['pan'],
adharno: extractedData['data']['adharno'],
panno: extractedData['data']['panno'],
),
);
the reason why :
extractedData is a map<String,dynamic>, when you call function forEach(key, value) :
the value is not a map, is an Object, or dynamic. the key is a String.
when you call this fuction :
value['data]
its will throw that error
if you extractedData is a List of Map, you can keep you original code, and change type of extractedData to List :
final extractedData = json.decode(response.body) as List<Map<String, dynamic>>;
Edit :
your data in the response is a list Of a map so the code will be this :
final extractedData = json.decode(response.body) as Map<String,dynamic>;
List<Map<String,dynamic>> data = extractedData['data'];
for (var map in data){
loadedUsers.add(
UserDetails(
userId: map['id'],
mobileno: map['mobileno'],
userStatus: map['userstatus'],
adhar: map['adhar'],
pan: map['pan'],
adharno: map['adharno'],
panno: map['panno'],
),
);
}
Hi I am getting this error. As I understand it, it appears when a request is made to the server, I don’t understand why.
By the way, I tried to find the answer here, but unfortunately, either the answers are not clear to me, or they do not suit me.
Here is some information that might be useful to you
Response from the server in the form -
Model -
factory DetailsModel.fromJson(Map<String, dynamic> json) {
return DetailsModel(
cpu: json['CPU'],
camera:json['camera'],
id: json['id'],
price: json['price'],
rating: json['rating'],
sd: json['sd'],
ssd:json['ssd'],
title: json['title'],
capacity: json['capacity'],
color: json['color'],
images:json['images']
);
}
Request -
class DetailsRemoteDataSorceImpl implements DetailsRemoteDataSorce {
final http.Clientclient;
DetailsRemoteDataSorceImpl({required this.client});
#override
Future<List<DetailsModel>> getAllDetails() async {
final response = await http.get(
Uri.parse(ConfigUrl.details),
headers: {'Content-Type': 'application/json'}
);
if(response.statusCode == 200) {
final details = json.decode(response.body);
return (details as List).map((e) => DetailsModel.fromJson(e)).toList();
} else {
throw ServerException();
}
}
}
And here's how I'm trying to display -
Text(details[0].title,)
response.body -
Result response.body: {CPU: Exynos 990, camera: 108 + 12 mp, capacity: [126, 252], color: [#772D03, #010035], id: 3, images: [https://avatars.mds.yandex.net/get-mpic/5235334/img_id5575010630545284324.png/orig, https://www.manualspdf.ru/thumbs/products/l/1260237-samsung-galaxy-note-20-ultra.jpg], isFavorites: true, price: 1500, rating: 4.5, sd: 256 GB, ssd: 8 GB, title: Galaxy Note 20 Ultra}
Please help, I spent about 3-4 hours on this
As you can see in your api response, it is returning a single object not list of them, if you expect a list of item maybe you should contact backend developer, but if receive what you want, you should do this:
if(response.statusCode == 200) {
List<DetailsModel> result =[];
DetailsModel detail = DetailsModel.fromJson(json.decode(response.body))
result.add(detail);
return result;
} else {
throw ServerException();
}
as i see your model accepts some lists so you have to convert your model like this below :
class DetailsModel {
String? cPU;
String? camera;
List<String>? capacity;
List<String>? color;
String? id;
List<String>? images;
bool? isFavorites;
int? price;
double? rating;
String? sd;
String? ssd;
String? title;
DetailsModel(
{this.cPU,
this.camera,
this.capacity,
this.color,
this.id,
this.images,
this.isFavorites,
this.price,
this.rating,
this.sd,
this.ssd,
this.title});
DetailsModel.fromJson(Map<String, dynamic> json) {
cPU = json['CPU'];
camera = json['camera'];
capacity = json['capacity'].cast<String>();
color = json['color'].cast<String>();
id = json['id'];
images = json['images'].cast<String>();
isFavorites = json['isFavorites'];
price = json['price'];
rating = json['rating'];
sd = json['sd'];
ssd = json['ssd'];
title = json['title'];
}}
and your request will be somthing like this :)
getAllDetails() async {
final response = await http.get(
Uri.parse(ConfigUrl.details),
headers: {'Content-Type': 'application/json'}
);
if(response.statusCode == 200) {
final details = json.decode(response.body);
return DetailsModel.fromJson(details));
} else {
throw ServerException();
}
}
I hope it will work :)
I'm having trouble consuming an API. I can save data to the database, but the following error occurs:
_TypeError (type '(dynamic) => Null' is not a subtype of type '(String, dynamic) => void' of 'action')
This is a part of my repository.
Future<MyModel?> test() async {
.
.
var headerParameters = {
"teanantId": tenantId,
"Authorization": headerAuth,
};
var queryParameters = {
'deviceId': appController.deviceId,
};
try {
Response response = await dio.post(
BASE_URL + methodPost,
data: jsonEncode(queryParameters),
options: Options(
headers: headerParameters,
contentType: 'application/json',
responseType: ResponseType.json),
);
if (response.statusCode == 200) {
var saida = MyModel.fromJson(json.decode(response.data));
return saida;
}
} on DioError catch (exc) {
throw ('Exception ${exc.message}');
}
return null;
}
Here's my model.
class MyModel {
List<Data?>? data;
bool? success;
int? statusCode;
String? message;
.
.
MyModel.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) {
data = <Data>[];
json['data'].forEach((v) {
data!.add(new Data.fromJson(v));
});
}
success = json['success'];
statusCode = json['statusCode'];
message = json['message'];
}
.
.
.
class Data {
String? id;
String? type;
User? user;
String? value;
String? status;
// List<Null>? errors;
String? createdAt;
// Null? verificationCode;
// Null? crossValidationIdentifier;
Data({
this.id,
this.type,
this.user,
this.value,
this.status,
this.createdAt,
});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
type = json['type'];
user = json['user'] != null ? new User.fromJson(json['user']) : null;
value = json['value'];
status = json['status'];
createdAt = json['createdAt'];
}
How can I get past this error?
The error occurs in foreach.
just decode the response.data to Map<String,dynamic>
import 'dart:convert';
....
final post = MyModel.fromJson(json.decode(response.data));
return post;
if your data is not list of map, then you just need to convert it from json.
Data? data;
...
MyModel.fromJson(Map<String, dynamic> json) {
data = Data.fromJson(json.decode(json["data"]));
success = json['success'];
statusCode = json['statusCode'];
message = json['message'];
}
this will work if your data from api is a Map, not list of map.
I'm developing a web app using Flutter Web and RESTful API for backend.
So, I'm trying the fetch the data from the api, serialize it by using Flutter Models, then return the result.
The Problem is, I'm getting this result
Expected a value of type 'Map<String, dynamic>', but got one of type 'List<dynamic>'
How to fix this ?
Here's my flutter codes:
models
// To parse this JSON data, do
//
// final medicalRecordsModel = medicalRecordsModelFromJson(jsonString);
import 'dart:convert';
class MedicalRecordsModel {
MedicalRecordsModel({
this.id,
this.category,
this.fileName,
this.dateTimestamp,
this.description,
this.upload,
this.patientName,
this.age,
this.address,
this.userId,
this.patientId,
this.isActive,
});
final String id;
final String category;
final String fileName;
final String dateTimestamp;
final String description;
final String upload;
final String patientName;
final String age;
final String address;
final dynamic userId;
final int patientId;
final bool isActive;
factory MedicalRecordsModel.fromJson(Map<String, dynamic> json) {
return MedicalRecordsModel(
id: json["id"],
category: json["category"],
fileName: json["fileName"],
dateTimestamp: json["dateTimestamp"],
description: json["description"],
upload: json["upload"],
patientName: json["patientName"],
age: json["age"],
address: json["address"],
userId: json["userId"],
patientId: json["patientId"],
isActive: json["isActive"],
);
}
}
API Connection
import 'dart:convert';
import 'dart:developer';
import 'dart:async';
import 'package:app/src/constants/medical_records.dart';
import 'package:app/src/models/medical_records/medical_records.dart';
import 'package:app/src/pages/Medical-Records/medical_record.dart';
import 'package:http/http.dart' as http;
class MedicalRecordsManager {
var client = http.Client();
var url = ConstantMedicalRecords.medical_records_api;
Future<MedicalRecordsModel> getRecords() async {
var url = ConstantMedicalRecords.medical_records_api;
log('$url');
try {
final response = await client.get(url);
if (response.statusCode == 200) {
return MedicalRecordsModel.fromJson(jsonDecode(response.body));
// print(recordsModel);
}
} catch (Exception) {
print(Exception);
print("Error occured");
}
}
}
Here is the JSON data I want to get
{
"id": "103",
"category": "DOCUMENT",
"fileName": "Check Up",
"dateTimestamp": "2021-02-1012:59:46",
"description": "string",
"upload": "String",
"patientName": "1",
"age": "25",
"address": "Earth",
"userId": null,
"patientId": 12,
"isActive": true
}
Please help me with this one.
you can do it like that
MedicalRecordsModel.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
change the getRecord as follows
Future<MedicalRecordsModel> getRecords() async {
var url = ConstantMedicalRecords.medical_records_api;
log('$url');
try {
final response = await client.get(url);
if (response.statusCode == 200) {
return MedicalRecordsModel.fromJson(jsonDecode(response.body)[0]);
// print(recordsModel);
}
} catch (Exception) {
print(Exception);
print("Error occured");
}
}
I think jsonDecode gives list of Maps therefore your json map is the first element of that list.
This code wiil work as you expected:
import 'package:json_helpers/json_helpers.dart';
void main() {
// responseBody is the same response.body
// When response is a list of objects
final list = responseBody1.jsonList((e) => MedicalRecordsModel.fromJson(e));
var obj = list[0];
print(obj.category);
print(obj.fileName);
// When response is an object
obj = responseBody2.json((e) => MedicalRecordsModel.fromJson(e));
print(obj.category);
print(obj.fileName);
}
final responseBody1 = '''
[
{
"id":"103",
"category":"DOCUMENT",
"fileName":"Check Up",
"dateTimestamp":"2021-02-1012:59:46",
"description":"string",
"upload":"String",
"patientName":"1",
"age":"25",
"address":"Earth",
"userId":null,
"patientId":12,
"isActive":true
}
]''';
final responseBody2 = '''
{
"id":"103",
"category":"DOCUMENT",
"fileName":"Check Up",
"dateTimestamp":"2021-02-1012:59:46",
"description":"string",
"upload":"String",
"patientName":"1",
"age":"25",
"address":"Earth",
"userId":null,
"patientId":12,
"isActive":true
}''';
class MedicalRecordsModel {
final String id;
final String category;
final String fileName;
final String dateTimestamp;
final String description;
final String upload;
final String patientName;
final String age;
final String address;
final dynamic userId;
final int patientId;
final bool isActive;
MedicalRecordsModel({
this.id,
this.category,
this.fileName,
this.dateTimestamp,
this.description,
this.upload,
this.patientName,
this.age,
this.address,
this.userId,
this.patientId,
this.isActive,
});
factory MedicalRecordsModel.fromJson(Map<String, dynamic> json) {
return MedicalRecordsModel(
id: json['id'] as String,
category: json['category'] as String,
fileName: json['fileName'] as String,
dateTimestamp: json['dateTimestamp'] as String,
description: json['description'] as String,
upload: json['upload'] as String,
patientName: json['patientName'] as String,
age: json['age'] as String,
address: json['address'] as String,
userId: json['userId'] as String,
patientId: json['patientId'] as int,
isActive: json['isActive'] as bool,
);
}
}
Output:
DOCUMENT
Check Up
DOCUMENT
Check Up
That is, when response is a list of objects:
final list = response.body.jsonList((e) => MedicalRecordsModel.fromJson(e));
When response is an object:
final object = response.body.json((e) => MedicalRecordsModel.fromJson(e));
If you don't know what the result is, then you can try both methods.
response.body.json((e) => Model.fromJson(e));
response.body.jsonList((e) => Model.fromJson(e));
If you have already decoded a JSON string and want to convert the result (or part of it), you can use the following methods:
If the type of the decoded value is Map:
final object = value.json((e) => Model.fromJson(e));
If the type of the decoded value is List:
final objects = value.json((e) => Model.fromJson(e));
Every response is sended and received as text, which can be converted to the
Map Format with the dart inbuilt core library import 'dart:convert';.
So the response from the request can be treated like this.
final res = await http.post(Uri.parse(url), body: json.encode({
'userId': uid,
'email': email,
}),
head body: json.encode({
'userId': uid,
'email': email,
}),
headers: {'Content-Type': 'application/json', 'token64': token});
here json.encode() is used to convert to String from Map.
now res variable contain the response which is also a string which can be convert to the Map with json.decode() like this.
final data = json.decode(res);
when working with the data sometimes we occur errors like Map is not a type of Map<String, String> etc.
Which can be solved by type casting the res, like this.
Map<String, String> notification = Map<String, String>.from(data['notification']);
I see these type casting method used in the The boring Flutter Development show in Youtube.
I faced the same kind of problem after I built an API and tried consuming it in flutter. I first extracted the data and check if the extracted data is null. When the condition is false, I made a list loadStudents that will hold the data after the loop. This is what worked out for me after a ton of stress looking for solutions online.