I am new to flutter and working on converting my native iOS app to it. I am trying to display a list of jobs in a list view. I have a couple models that I am mapping to, but I am not sure how to do it right, as I get this error. _InternalLinkedHashMap<String, dynamic> is not a subtype of type 'JobModel' in type cast
class ProviderJobsJson {
final String status;
final String message;
final List<JobModel> jobs;
final int numUnreadConnectionMsgs;
final int numUnreadTaskMsgs;
const ProviderJobsJson({
required this.status,
required this.message,
required this.jobs,
required this.numUnreadConnectionMsgs,
required this.numUnreadTaskMsgs,
});
factory ProviderJobsJson.fromJson(Map<String, dynamic> json) {
return ProviderJobsJson(
status: json['status'],
message: json['message'],
jobs: json['jobs'],
numUnreadConnectionMsgs: json['numUnreadConnectionMsgs'],
numUnreadTaskMsgs: json['numUnreadTaskMsgs'],
);
}
}
Above I have a list of jobs. Similar setup to the ProviderJobsJson class. Here is what I have in the Widget build.
child: FutureBuilder<List<dynamic>>(
future: futureJobs,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<JobModel> data = snapshot.data!.cast<JobModel>();
return ListView.builder(itemBuilder: (BuildContext context, int index) {
return Container(
height: 75,
color: Colors.white,
child: Center(child: Text(data[index].businessName)),
);
});
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
How do I go about fixing this error?
JobModel:
class JobModel {
final String startDate;
final String requirement;
final String endDate;
final String jobKey;
final String jobRequirement;
final double minAverageRatingGiven;
final String managerKey;
final String pictureUrl;
final List<String> jobKeywords;
final bool useJobEngineOutNetwork;
final String businessKey;
final double maxNumberOfHoursPerProviderPerDayForThisJob;
final AddressModel location;
final String scheduleKey;
final String dateTimeCreated;
final String dateTimeUpdated;
final String jobScheduleStatus;
final String jobState;
final double maxNumberOfHoursPerProviderPerWeek;
final String jobDescription;
final double maxNumberOfHoursPerProviderPerDay;
final double minAverageRatingReceived;
final double minNumberOfHoursPerProviderPerWeekForThisJob;
final double minNumberOfHoursPerShift;
final double payRate;
final String businessName;
final List<String> supervisorKeys;
final bool didLike;
final bool didAdd;
final int numTasks;
final int numUserTasksOnJob;
final int numLikes;
final int numUsers;
const JobModel({
required this.startDate,
required this.requirement,
required this.endDate,
required this.jobKey,
required this.jobRequirement,
required this.minAverageRatingGiven,
required this.managerKey,
required this.pictureUrl,
required this.jobKeywords,
required this.useJobEngineOutNetwork,
required this.businessKey,
required this.maxNumberOfHoursPerProviderPerDayForThisJob,
required this.location,
required this.scheduleKey,
required this.dateTimeCreated,
required this.dateTimeUpdated,
required this.jobScheduleStatus,
required this.jobState,
required this.maxNumberOfHoursPerProviderPerWeek,
required this.jobDescription,
required this.maxNumberOfHoursPerProviderPerDay,
required this.minAverageRatingReceived,
required this.minNumberOfHoursPerProviderPerWeekForThisJob,
required this.minNumberOfHoursPerShift,
required this.payRate,
required this.businessName,
required this.supervisorKeys,
required this.didLike,
required this.didAdd,
required this.numTasks,
required this.numUserTasksOnJob,
required this.numLikes,
required this.numUsers,
});
factory JobModel.fromJson(Map<String, dynamic> json) {
return JobModel(
startDate: json['startDate'],
requirement: json['requirement'],
endDate: json['endDate'],
jobKey: json['jobKey'],
jobRequirement: json['jobRequirement'],
minAverageRatingGiven: json['minAverageRatingGiven'],
managerKey: json['managerKey'],
pictureUrl: json['pictureUrl'],
jobKeywords: json['jobKeywords'],
useJobEngineOutNetwork: json['useJobEngineOutNetwork'],
businessKey: json['businessKey'],
maxNumberOfHoursPerProviderPerDayForThisJob: json['maxNumberOfHoursPerProviderPerDayForThisJob'],
location: json['location'],
scheduleKey: json['scheduleKey'],
dateTimeCreated: json['dateTimeCreated'],
dateTimeUpdated: json['dateTimeUpdated'],
jobScheduleStatus: json['dateTimeUpdated'],
jobState: json['dateTimeUpdated'],
maxNumberOfHoursPerProviderPerWeek: json['dateTimeUpdated'],
jobDescription: json['dateTimeUpdated'],
maxNumberOfHoursPerProviderPerDay: json['dateTimeUpdated'],
minAverageRatingReceived: json['dateTimeUpdated'],
minNumberOfHoursPerProviderPerWeekForThisJob: json['dateTimeUpdated'],
minNumberOfHoursPerShift: json['dateTimeUpdated'],
payRate: json['dateTimeUpdated'],
businessName: json['dateTimeUpdated'],
supervisorKeys: json['dateTimeUpdated'],
didLike: json['dateTimeUpdated'],
didAdd: json['dateTimeUpdated'],
numTasks: json['dateTimeUpdated'],
numUserTasksOnJob: json['dateTimeUpdated'],
numLikes: json['dateTimeUpdated'],
numUsers: json['dateTimeUpdated'],
);
}
}
JSON:
{
"status": "success",
"numUnreadConnectionMsgs": 0,
"message": "6 jobs retrieved for Rob Smith",
"jobs": [
{
"startDate": "2020-11-25",
"requirement": "",
"endDate": "2022-11-24",
"numLikes": 2,
"didAdd": true,
"minAverageRatingGiven": null,
"managerKey": "ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgKzKpIAKDA",
"timeUpdated": 1649024746000,
"jobImageKey": "ag5zfndya2lvLXNlcnZlcnIyCxIISm9iSW1hZ2UiD2pvYl9pbWFnZV90YWJsZQwLEghKb2JJbWFnZRiAgIDs9_2KCgw",
"useJobEngineOutNetwork": null,
"jobState": "Active",
"businessKey": null,
"didLike": false,
"maxNumberOfSharingProviders": null,
"title": "Cashier",
"jobKeywordsJson": "{\"jobTitle\":\"cashier\",\"managerName\":\"jerry pi\",\"businessName\":\"goodmart inc.\"}",
"maxNumberOfHoursPerProviderPerDayForThisJob": null,
"numShares": 0,
"location": {
"hashValue": null,
"addressType": null,
"street": "W McDermott Dr",
"latDegx32": null,
"latDegx16": null,
"city": "Allen",
"zipcode": "75013",
"latDeg": 33,
"state": "TX",
"latDegx2": null,
"latDegx4": null,
"latitude": 33.1010907,
"latDegx8": null,
"timeZoneName": "Central Daylight Time",
"dateTimeUpdated": "2022-04-03T22:25:46.590006",
"lngDeg": -97,
"timeZoneOffset": -18000,
"timeZoneId": "America/Chicago",
"dateTimeCreated": "2020-11-25T18:11:05.605947",
"country": null,
"longitude": -96.6905647,
"streetNumber": "930"
},
"scheduleKey": "ag5zfndya2lvLXNlcnZlcnIVCxIIU2NoZWR1bGUYgICArOWWlAsM",
"maxNumberOfHoursPerProviderPerWeek": null,
"status": "active",
"description": "Cashier",
"timeCreated": 1606327800000,
"maxNumberOfHoursPerProviderPerDay": null,
"minAverageRatingReceived": null,
"jobScheduleStatus": "on",
"dateTimeUpdated": "2022-04-03T22:25:46.589963",
"pictureUrl": "https://lh3.googleusercontent.com/t-2IjQvzdfouVUiZDqUl_F50wrAJ9jlPRiiqMNUfE30gX7-QpZFaAmzlEBZqik0Jo5HOF6EXXmsbXeKOYxDGsPvT9ZWEWrZXLJZY5iY",
"jobImageKeyStr": "ag5zfndya2lvLXNlcnZlcnIyCxIISm9iSW1hZ2UiD2pvYl9pbWFnZV90YWJsZQwLEghKb2JJbWFnZRiAgICMn5aFCgw",
"useJobEngineInNetwork": null,
"managerName": "Jerry Pi",
"maxNumberOfHoursPerProviderPerWeekForThisJob": null,
"keyStr": "ag5zfndya2lvLXNlcnZlcnIQCxIDSm9iGICAgIyy74QKDA",
"dateTimeCreated": "2020-11-25T18:10:00.962624",
"numUsers": 3,
"minNumberOfHoursPerShift": null,
"payRate": null,
"businessName": "Goodmart Inc.",
"numUserTasksOnJob": 0,
"supervisorKeys": [
"ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgKzKpIAKDA",
"ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgIzd6YoJDA"
],
"numTasks": 38
},
{
"startDate": "2020-01-15",
"requirement": "Type stuff",
"endDate": "2021-05-31",
"numLikes": 0,
"didAdd": true,
"minAverageRatingGiven": null,
"managerKey": "ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgJztxpwKDA",
"pictureURL": null,
"timeUpdated": 1639411421000,
"jobImageKey": null,
"useJobEngineOutNetwork": null,
"jobState": "Active",
"businessKey": null,
"didLike": false,
"maxNumberOfSharingProviders": null,
"title": "Clerk",
"jobKeywordsJson": "{\"jobTitle\":\"clerk\",\"managerName\":\"rsmith\",\"businessName\":\"tester\"}",
"maxNumberOfHoursPerProviderPerDayForThisJob": null,
"numShares": 0,
"location": {
"timeZoneId": "America/Chicago",
"city": "Prosper",
"hashValue": null,
"addressType": null,
"timeZoneName": "Central Daylight Time",
"dateTimeCreated": "2021-04-01T17:21:23.372484",
"country": null,
"zipcode": "75078",
"longitude": -96.78947339999999,
"dateTimeUpdated": "2021-12-13T16:03:41.926708",
"latDegx4": 133,
"state": "TX",
"street": "Address",
"latDegx2": 66,
"streetNumber": "Test",
"latDegx16": 532,
"latitude": 33.234941,
"latDegx8": 266,
"latDeg": 33,
"timeZoneOffset": -18000,
"latDegx32": 1064
},
"scheduleKey": "ag5zfndya2lvLXNlcnZlcnIVCxIIU2NoZWR1bGUYgICAzPuUhAoM",
"maxNumberOfHoursPerProviderPerWeek": null,
"status": "active",
"description": "Clerk Stuff",
"timeCreated": 1608655993000,
"maxNumberOfHoursPerProviderPerDay": null,
"minAverageRatingReceived": null,
"jobScheduleStatus": "on",
"dateTimeUpdated": "2021-12-13T16:03:41.926660",
"pictureUrl": "https://www.wrkio.com/images/job_default.jpg",
"jobImageKeyStr": null,
"useJobEngineInNetwork": null,
"managerName": "Rsmith",
"maxNumberOfHoursPerProviderPerWeekForThisJob": null,
"keyStr": "ag5zfndya2lvLXNlcnZlcnIQCxIDSm9iGICAgMyk650KDA",
"dateTimeCreated": "2020-12-22T16:53:13.277595",
"numUsers": 4,
"minNumberOfHoursPerShift": null,
"payRate": null,
"businessName": "Tester",
"numUserTasksOnJob": 36,
"supervisorKeys": [
"ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgJztxpwKDA",
"ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgOyQ_4sKDA"
],
"numTasks": 76
},
{
"startDate": "2021-10-01",
"requirement": "At least 2 years experience in retail sales.",
"endDate": "2022-12-31",
"numLikes": 2,
"didAdd": true,
"minAverageRatingGiven": null,
"managerKey": "ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgKzKpIAKDA",
"timeUpdated": 1646856651000,
"jobImageKey": null,
"useJobEngineOutNetwork": null,
"businessKey": null,
"didLike": false,
"maxNumberOfSharingProviders": null,
"title": "Sales Associate",
"jobKeywordsJson": "{\"jobTitle\":\"sales associate\",\"managerName\":\"jerry pi\",\"businessName\":\"goodmart inc.\"}",
"maxNumberOfHoursPerProviderPerDayForThisJob": null,
"numShares": 0,
"location": {
"timeZoneId": "America/Chicago",
"city": "Allen",
"hashValue": null,
"addressType": null,
"timeZoneName": "Central Daylight Time",
"dateTimeCreated": "2021-09-29T19:09:47.923394",
"country": "US",
"zipcode": "75013",
"longitude": -96.6905647,
"dateTimeUpdated": "2022-03-09T20:10:51.425776",
"latDegx4": 132,
"state": "TX",
"street": "W McDermott Dr",
"latDegx2": 66,
"streetNumber": "930",
"latDegx16": 530,
"latitude": 33.1010907,
"latDegx8": 265,
"latDeg": 33,
"timeZoneOffset": -18000,
"latDegx32": 1059
},
"scheduleKey": "ag5zfndya2lvLXNlcnZlcnIVCxIIU2NoZWR1bGUYgICAnN-WjQoM",
"maxNumberOfHoursPerProviderPerWeek": null,
"description": "Sales on the floor; \r\nhelp customers find products; \r\nanswer questions; \r\ncomplete sales transactions, etc.",
"timeCreated": 1632942589000,
"maxNumberOfHoursPerProviderPerDay": null,
"minAverageRatingReceived": null,
"jobScheduleStatus": "on",
"dateTimeUpdated": "2022-03-09T20:10:51.425732",
"pictureUrl": "https://www.wrkio.com/images/job_default.jpg",
"useJobEngineInNetwork": null,
"managerName": "Jerry Pi",
"maxNumberOfHoursPerProviderPerWeekForThisJob": null,
"keyStr": "ag5zfndya2lvLXNlcnZlcnIQCxIDSm9iGICAgKy__ZAKDA",
"dateTimeCreated": "2021-09-29T19:09:49.315609",
"numUsers": 3,
"minNumberOfHoursPerShift": null,
"payRate": null,
"businessName": "Goodmart Inc.",
"numUserTasksOnJob": 1,
"supervisorKeys": [
"ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgKzKpIAKDA"
],
"numTasks": 21
},
{
"startDate": "2021-10-11",
"requirement": "Sit at desk",
"endDate": "2021-11-20",
"numLikes": 0,
"didAdd": true,
"minAverageRatingGiven": null,
"managerKey": "ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgJztxpwKDA",
"timeUpdated": 1639411424000,
"jobImageKey": null,
"useJobEngineOutNetwork": null,
"jobState": "Active",
"businessKey": null,
"didLike": false,
"maxNumberOfSharingProviders": null,
"title": "Tech Support (Clone)",
"jobKeywordsJson": "{\"jobTitle\":\"tech support\",\"managerName\":\"rsmith\",\"businessName\":\"bitdelve\"}",
"maxNumberOfHoursPerProviderPerDayForThisJob": null,
"numShares": 0,
"location": {
"timeZoneId": "America/Chicago",
"city": "Prosper",
"hashValue": null,
"addressType": null,
"timeZoneName": "Central Daylight Time",
"dateTimeCreated": "2021-04-29T01:31:22.687751",
"country": "US",
"zipcode": "75078",
"longitude": -96.857587,
"dateTimeUpdated": "2021-12-13T16:03:44.180033",
"latDegx4": 133,
"state": "TX",
"street": "Aquilla Way",
"latDegx2": 66,
"streetNumber": "16016",
"latDegx16": 532,
"latitude": 33.230967,
"latDegx8": 266,
"latDeg": 33,
"timeZoneOffset": -18000,
"latDegx32": 1063
},
"scheduleKey": "ag5zfndya2lvLXNlcnZlcnIVCxIIU2NoZWR1bGUYgICAjIbJmQoM",
"maxNumberOfHoursPerProviderPerWeek": null,
"description": "Take tech calls",
"timeCreated": 1619659882000,
"maxNumberOfHoursPerProviderPerDay": null,
"minAverageRatingReceived": null,
"jobScheduleStatus": "on",
"dateTimeUpdated": "2021-12-13T16:03:44.179992",
"pictureUrl": "https://www.wrkio.com/images/job_default.jpg",
"useJobEngineInNetwork": null,
"managerName": "Rsmith",
"maxNumberOfHoursPerProviderPerWeekForThisJob": null,
"keyStr": "ag5zfndya2lvLXNlcnZlcnIQCxIDSm9iGICAgIyLooEKDA",
"dateTimeCreated": "2021-04-29T01:31:22.938398",
"numUsers": 1,
"minNumberOfHoursPerShift": null,
"payRate": null,
"businessName": "Bitdelve",
"numUserTasksOnJob": 3,
"supervisorKeys": [],
"numTasks": 3
},
{
"startDate": "2020-10-10",
"requirement": "Model Maker",
"endDate": "2021-10-10",
"numLikes": 0,
"didAdd": true,
"minAverageRatingGiven": null,
"managerKey": "ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgJztxpwKDA",
"timeUpdated": 1639411426000,
"jobImageKey": null,
"useJobEngineOutNetwork": null,
"jobState": "Archived",
"businessKey": null,
"didLike": false,
"maxNumberOfSharingProviders": null,
"title": "Model Maker",
"jobKeywordsJson": "{\"jobTitle\":\"model maker\",\"managerName\":\"rsmith\",\"businessName\":\"metal earth\"}",
"maxNumberOfHoursPerProviderPerDayForThisJob": null,
"numShares": 0,
"location": {
"hashValue": null,
"addressType": null,
"street": "E Main",
"latDegx32": 1064,
"latDegx16": 532,
"city": "Prosper",
"zipcode": "75078",
"latDeg": 33,
"state": "TX",
"latDegx2": 66,
"latDegx4": 133,
"latitude": 33.2364799,
"latDegx8": 266,
"timeZoneName": "Central Daylight Time",
"dateTimeUpdated": "2021-12-13T16:03:46.859589",
"lngDeg": -97,
"timeZoneOffset": -18000,
"timeZoneId": "America/Chicago",
"dateTimeCreated": "2020-11-17T15:09:17.828183",
"country": null,
"longitude": -96.80324259999999,
"streetNumber": "101"
},
"scheduleKey": "ag5zfndya2lvLXNlcnZlcnIVCxIIU2NoZWR1bGUYgICAjKHinAoM",
"maxNumberOfHoursPerProviderPerWeek": null,
"status": "active",
"description": "Model Maker",
"timeCreated": 1605625758000,
"maxNumberOfHoursPerProviderPerDay": null,
"minAverageRatingReceived": null,
"jobScheduleStatus": null,
"dateTimeUpdated": "2021-12-13T16:03:46.859548",
"pictureUrl": "https://www.wrkio.com/images/job_default.jpg",
"jobImageKeyStr": null,
"useJobEngineInNetwork": null,
"managerName": "Rsmith",
"maxNumberOfHoursPerProviderPerWeekForThisJob": null,
"keyStr": "ag5zfndya2lvLXNlcnZlcnIQCxIDSm9iGICAgJzT5JwKDA",
"dateTimeCreated": "2020-11-17T15:09:18.367621",
"numUsers": 1,
"minNumberOfHoursPerShift": null,
"payRate": null,
"businessName": "Metal Earth",
"numUserTasksOnJob": 2,
"supervisorKeys": [
"ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgJztxpwKDA"
],
"numTasks": 2
},
{
"startDate": "2020-10-10",
"requirement": "Developer",
"endDate": "2023-10-10",
"numLikes": 2,
"didAdd": true,
"minAverageRatingGiven": null,
"managerKey": "ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgJztxpwKDA",
"timeUpdated": 1650609176000,
"jobImageKey": "ag5zfndya2lvLXNlcnZlcnIyCxIISm9iSW1hZ2UiD2pvYl9pbWFnZV90YWJsZQwLEghKb2JJbWFnZRiAgICso6yNCgw",
"useJobEngineOutNetwork": null,
"businessKey": null,
"didLike": false,
"maxNumberOfSharingProviders": null,
"title": "Developer",
"jobKeywordsJson": "{\"jobTitle\":\"developer\",\"managerName\":\"rsmith\",\"businessName\":\"devops\"}",
"maxNumberOfHoursPerProviderPerDayForThisJob": null,
"numShares": 0,
"location": {
"hashValue": null,
"addressType": null,
"street": "Aquilla Way",
"latDegx32": 1063,
"latDegx16": 532,
"city": "Prosper",
"zipcode": "75078",
"latDeg": 33,
"state": "TX",
"latDegx2": 66,
"latDegx4": 133,
"latitude": 33.230967,
"latDegx8": 266,
"timeZoneName": "Central Daylight Time",
"dateTimeUpdated": "2022-04-22T06:32:56.217252",
"lngDeg": -97,
"timeZoneOffset": -18000,
"timeZoneId": "America/Chicago",
"dateTimeCreated": "2020-11-24T21:43:58.943213",
"country": null,
"longitude": -96.857587,
"streetNumber": "16016"
},
"scheduleKey": "ag5zfndya2lvLXNlcnZlcnIVCxIIU2NoZWR1bGUYgICArLadkgoM",
"maxNumberOfHoursPerProviderPerWeek": null,
"description": "Developer",
"timeCreated": 1606254239000,
"maxNumberOfHoursPerProviderPerDay": null,
"minAverageRatingReceived": null,
"jobScheduleStatus": "on",
"dateTimeUpdated": "2022-04-22T06:32:56.217213",
"pictureUrl": "https://lh3.googleusercontent.com/B4fSb4rdc35_pqsungw_QuafECNTyPST17dkbCVSXbGZlpeFE9M6vmsXfqOX9LUgnDletyuTrRvfAmpdNZsSkpXWa3bEV7O57DCm",
"jobImageKeyStr": null,
"useJobEngineInNetwork": null,
"managerName": "Rsmith",
"maxNumberOfHoursPerProviderPerWeekForThisJob": null,
"keyStr": "ag5zfndya2lvLXNlcnZlcnIQCxIDSm9iGICAgOybroAKDA",
"dateTimeCreated": "2020-11-24T21:43:59.409896",
"numUsers": 6,
"minNumberOfHoursPerShift": null,
"payRate": null,
"businessName": "DevOps",
"numUserTasksOnJob": 27,
"supervisorKeys": [
"ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgKzKpIAKDA",
"ag5zfndya2lvLXNlcnZlcnIWCxIJV3JraW9Vc2VyGICAgJztxpwKDA"
],
"numTasks": 42
}
],
"numUnreadTaskMsgs": 11
}
API Call:
Future<List<dynamic>> fetchJobs(String userId, String authToken) async {
final response = await http.post(Uri.parse('URL'));
if (response.statusCode == 200) {
var model = ProviderJobsJson.fromJson(jsonDecode(response.body));
//return List<JobModel>.from(model.jobs.where((i) => i.businessName.length > 0 ));//
List<dynamic> list = model.jobs;//.cast<JobModel>();
return list;
} else {
throw Exception('Failed to load jobs');
}
}
CodePudding user response:
It looks like the ProviderJobsJson.fromJson is not parsing the list of jobs for you.
You might do it like this:
var model = ProviderJobsJson.fromJson(jsonDecode(response.body));
var jsonJobs = model.jobs;
List<JobModel> jobs = List<JobModel>.from(jsonJobs.map((x) => JobModel.fromJson(x)));