JSON Parsing using Encodable class - json

I am trying to parse long response data :
below is the code structure
struct VizLog_UserProfile: Codable {
let data: UserProfileData
let app: App
}
struct UserProfileData: Codable {
let roles: [String]
let users: UserDetails
let member: ProfileMember
enum CodingKeys: String, CodingKey {
case roles
case users
case member
}
}
struct UserDetails: Codable {
let user_id: String
let auth_id: String
let unit_id: String
let company_id: String
let visitor_id: String
let session_token: String
let gender: String
let visitor_type: String
let email: String
let first_name: String
let last_name: String
let mobile: String
let avatar: String
var complex: Complex? = nil
enum CodingKeys: String, CodingKey {
case user_id
case auth_id
case unit_id
case company_id
case visitor_id
case session_token
case gender
case visitor_type
case email
case first_name
case last_name
case mobile
case avatar
case complex = "complex"
}
enum Complex_CodingKeys: String, CodingKey {
case company_id
case unit_id
case complex_name
case setup_steps
case complex_type
case access_type
case pass_type
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
user_id = getValUserDetails(key: .user_id, decoder: decoder, container: container)
auth_id = getValUserDetails(key: .auth_id, decoder: decoder, container: container)
unit_id = getValUserDetails(key: .unit_id, decoder: decoder, container: container)
company_id = getValUserDetails(key: .company_id, decoder: decoder, container: container)
visitor_id = getValUserDetails(key: .visitor_id, decoder: decoder, container: container)
session_token = getValUserDetails(key: .session_token, decoder: decoder, container: container)
gender = getValUserDetails(key: .gender, decoder: decoder, container: container)
visitor_type = getValUserDetails(key: .visitor_type, decoder: decoder, container: container)
email = getValUserDetails(key: .email, decoder: decoder, container: container)
first_name = getValUserDetails(key: .first_name, decoder: decoder, container: container)
last_name = getValUserDetails(key: .last_name, decoder: decoder, container: container)
mobile = getValUserDetails(key: .mobile, decoder: decoder, container: container)
avatar = getValUserDetails(key: .avatar, decoder: decoder, container: container)
var tmpComplexUnkeyedContainer = try container.nestedUnkeyedContainer(forKey: .complex)
var tmpComplex : Complex? = nil
let tmpComplexContainer = try tmpComplexUnkeyedContainer.nestedContainer(keyedBy: Complex.CodingKeys.self)
tmpComplex?.company_id = getValComplex(key: .company_id, container: tmpComplexContainer)
tmpComplex?.unit_id = getValComplex(key: .unit_id, container: tmpComplexContainer)
tmpComplex?.complex_name = getValComplex(key: .complex_name, container: tmpComplexContainer)
tmpComplex?.setup_steps = getValComplex(key: .setup_steps, container: tmpComplexContainer)
tmpComplex?.complex_type = getValComplex(key: .complex_type, container: tmpComplexContainer)
tmpComplex?.access_type = getValComplex(key: .access_type, container: tmpComplexContainer)
tmpComplex?.pass_type = getValComplex(key: .pass_type, container: tmpComplexContainer)
complex = tmpComplex
}
}
struct ProfileMember: Codable {
public var units: [String: ProfileUnits]
let parking: [String]
}
struct ProfileUnits: Codable {
let unit_type: String
let building_name: String
let unit_number: String
let building_unit_id: String
enum CodingKeys: String, CodingKey {
case unit_type
case building_name
case unit_number
case building_unit_id
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
unit_type = getValProfileMember(key: .unit_type, decoder: decoder, container: container)
building_name = getValProfileMember(key: .building_name, decoder: decoder, container: container)
unit_number = getValProfileMember(key: .unit_number, decoder: decoder, container: container)
building_unit_id = getValProfileMember(key: .building_unit_id, decoder: decoder, container: container)
}
}
struct Subscribed_Applications: Codable {
let app_id: String
let app_name: String
let app_version: String
let logo: String
let end_point: String
let logo_small: String
let logo_medium: String
let logo_large: String
let logo_xsmall: String
}
struct Complex: Codable {
var company_id: String
var unit_id: String
var complex_name: String
var setup_steps: String
var complex_type: String
var access_type: String
var pass_type: String
//let complex_events: [String]
enum CodingKeys: String, CodingKey {
case company_id
case unit_id
case complex_name
case setup_steps
case complex_type
case access_type
case pass_type
//case complex_events
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
company_id = getValComplex(key: .company_id, container: container)
unit_id = getValComplex(key: .unit_id, container: container)
complex_name = getValComplex(key: .complex_name, container: container)
setup_steps = getValComplex(key: .setup_steps, container: container)
complex_type = getValComplex(key: .complex_type, container: container)
access_type = getValComplex(key: .access_type, container: container)
pass_type = getValComplex(key: .pass_type, container: container)
//complex_events = getValComplex(key: .complex_events, container: container)
}
}
This is the actual Response which I am trying to parse :
{
"app": {
"version": "v1",
"name": "CHSONE Vizlog",
"time": "2019-02-07 05:31:08"
},
"status_code": 200,
"data": {
"metadata": {
"total": 64899,
"per_page": 10,
"current_page": 1,
"last_page": 6490,
"from": 1,
"to": 10
},
"results": [
{
"log_id": 64899,
"fk_visitor_id": 65103,
"fk_building_unit_id": 97,
"company_id": 7,
"pass_serial_no": null,
"card_no": null,
"number_of_people": 1,
"purpose_of_visit": "Meeting",
"in_gate": "Lobby",
"in_time": "2019-02-06 12:24:31",
"out_time": null,
"out_gate": null,
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 0,
"access_type": "card",
"created_at": "2019-02-06 12:24:31",
"updated_at": "2019-02-06 12:24:31",
"created_by": 151,
"updated_by": null,
"visitors": {
"visitor_id": 65103,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": "android",
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "praduman",
"last_name": null,
"gender": "M",
"mobile": "9080706050",
"email": null,
"image_path": null,
"visitor_type": "guest",
"coming_from": "vashi",
"image_large": null,
"image_medium": null,
"image_small": null
},
"unit": {
"building_unit_id": 97,
"fk_building_id": 1,
"unit_number": "1905",
"floor_no": "19",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
},
{
"log_id": 64898,
"fk_visitor_id": 65054,
"fk_building_unit_id": 97,
"company_id": 7,
"pass_serial_no": null,
"card_no": null,
"number_of_people": 1,
"purpose_of_visit": "Meeting",
"in_gate": "Lobby",
"in_time": "2019-02-06 12:19:06",
"out_time": null,
"out_gate": null,
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 0,
"access_type": "card",
"created_at": "2019-02-06 12:19:06",
"updated_at": "2019-02-06 12:19:06",
"created_by": 151,
"updated_by": null,
"visitors": {
"visitor_id": 65054,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": null,
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "Amit",
"last_name": "Dhawale",
"gender": "M",
"mobile": "8055954796",
"email": null,
"image_path": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054.jpg",
"visitor_type": "guest",
"coming_from": "sanpada",
"image_large": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054_large.jpg",
"image_medium": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054_medium.jpg",
"image_small": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054_small.jpg"
},
"unit": {
"building_unit_id": 97,
"fk_building_id": 1,
"unit_number": "1905",
"floor_no": "19",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
},
{
"log_id": 64897,
"fk_visitor_id": 57222,
"fk_building_unit_id": 24,
"company_id": 7,
"pass_serial_no": null,
"card_no": null,
"number_of_people": 1,
"purpose_of_visit": "Meeting",
"in_gate": "Lobby",
"in_time": "2019-02-06 12:08:08",
"out_time": null,
"out_gate": null,
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 0,
"access_type": "card",
"created_at": "2019-02-06 12:08:08",
"updated_at": "2019-02-06 12:08:08",
"created_by": 151,
"updated_by": null,
"visitors": {
"visitor_id": 57222,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": null,
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "Praduman",
"last_name": "Patil",
"gender": "M",
"mobile": "9420256819",
"email": null,
"image_path": null,
"visitor_type": "guest",
"coming_from": "Future Scape interview",
"image_large": null,
"image_medium": null,
"image_small": null
},
"unit": {
"building_unit_id": 24,
"fk_building_id": 1,
"unit_number": "1001",
"floor_no": "10",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
},
{
"log_id": 64896,
"fk_visitor_id": 65054,
"fk_building_unit_id": 96,
"company_id": 7,
"pass_serial_no": null,
"card_no": null,
"number_of_people": 1,
"purpose_of_visit": "Meeting",
"in_gate": "Lobby",
"in_time": "2019-01-31 12:34:18",
"out_time": "2019-01-31 12:40:30",
"out_gate": "Lobby",
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 1,
"access_type": "card",
"created_at": "2019-01-31 12:34:18",
"updated_at": "2019-01-31 12:40:30",
"created_by": 152,
"updated_by": 151,
"visitors": {
"visitor_id": 65054,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": null,
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "Amit",
"last_name": "Dhawale",
"gender": "M",
"mobile": "8055954796",
"email": null,
"image_path": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054.jpg",
"visitor_type": "guest",
"coming_from": "sanpada",
"image_large": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054_large.jpg",
"image_medium": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054_medium.jpg",
"image_small": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054_small.jpg"
},
"unit": {
"building_unit_id": 96,
"fk_building_id": 1,
"unit_number": "1904",
"floor_no": "19",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
},
{
"log_id": 64895,
"fk_visitor_id": 65054,
"fk_building_unit_id": 96,
"company_id": 7,
"pass_serial_no": null,
"card_no": null,
"number_of_people": 1,
"purpose_of_visit": "Meeting",
"in_gate": "Lobby",
"in_time": "2019-01-31 11:35:09",
"out_time": null,
"out_gate": null,
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 0,
"access_type": "card",
"created_at": "2019-01-31 11:35:09",
"updated_at": "2019-01-31 11:35:09",
"created_by": 151,
"updated_by": null,
"visitors": {
"visitor_id": 65054,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": null,
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "Amit",
"last_name": "Dhawale",
"gender": "M",
"mobile": "8055954796",
"email": null,
"image_path": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054.jpg",
"visitor_type": "guest",
"coming_from": "sanpada",
"image_large": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054_large.jpg",
"image_medium": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054_medium.jpg",
"image_small": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_65054_small.jpg"
},
"unit": {
"building_unit_id": 96,
"fk_building_id": 1,
"unit_number": "1904",
"floor_no": "19",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
},
{
"log_id": 64894,
"fk_visitor_id": 65102,
"fk_building_unit_id": 97,
"company_id": 7,
"pass_serial_no": null,
"card_no": null,
"number_of_people": 1,
"purpose_of_visit": "Meeting",
"in_gate": "Lobby",
"in_time": "2019-01-28 14:01:24",
"out_time": null,
"out_gate": null,
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 0,
"access_type": "card",
"created_at": "2019-01-28 14:01:24",
"updated_at": "2019-01-28 14:01:24",
"created_by": 151,
"updated_by": null,
"visitors": {
"visitor_id": 65102,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": "android",
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "hzhd",
"last_name": null,
"gender": "M",
"mobile": "8055678855",
"email": null,
"image_path": null,
"visitor_type": "guest",
"coming_from": "vashi",
"image_large": null,
"image_medium": null,
"image_small": null
},
"unit": {
"building_unit_id": 97,
"fk_building_id": 1,
"unit_number": "1905",
"floor_no": "19",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
},
{
"log_id": 64893,
"fk_visitor_id": 65101,
"fk_building_unit_id": 96,
"company_id": 7,
"pass_serial_no": null,
"card_no": null,
"number_of_people": 1,
"purpose_of_visit": "Meeting",
"in_gate": "Lobby",
"in_time": "2019-01-28 14:00:40",
"out_time": null,
"out_gate": null,
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 0,
"access_type": "card",
"created_at": "2019-01-28 14:00:40",
"updated_at": "2019-01-28 14:00:40",
"created_by": 151,
"updated_by": null,
"visitors": {
"visitor_id": 65101,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": "android",
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "test",
"last_name": "sync",
"gender": "M",
"mobile": "8056799285",
"email": null,
"image_path": null,
"visitor_type": "guest",
"coming_from": "vashi",
"image_large": null,
"image_medium": null,
"image_small": null
},
"unit": {
"building_unit_id": 96,
"fk_building_id": 1,
"unit_number": "1904",
"floor_no": "19",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
},
{
"log_id": 64892,
"fk_visitor_id": 47,
"fk_building_unit_id": 97,
"company_id": 7,
"pass_serial_no": null,
"card_no": null,
"number_of_people": 1,
"purpose_of_visit": "Meeting",
"in_gate": "Lobby",
"in_time": "2019-01-28 13:47:42",
"out_time": null,
"out_gate": null,
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 0,
"access_type": "card",
"created_at": "2019-01-28 13:47:42",
"updated_at": "2019-01-28 13:47:42",
"created_by": 151,
"updated_by": null,
"visitors": {
"visitor_id": 47,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": null,
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "KOTESHWAR",
"last_name": "DEVELOPERS",
"gender": "",
"mobile": "9819328361",
"email": "krishnaenterprises400#gmail.com",
"image_path": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_47.jpg",
"visitor_type": "member",
"coming_from": null,
"image_large": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_47_large.jpg",
"image_medium": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_47_medium.jpg",
"image_small": "http://test.prosimvizlog.s3-ap-southeast-1.amazonaws.com/7/visitor/visitor_47_small.jpg"
},
"unit": {
"building_unit_id": 97,
"fk_building_id": 1,
"unit_number": "1905",
"floor_no": "19",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
},
{
"log_id": 64891,
"fk_visitor_id": 65100,
"fk_building_unit_id": 96,
"company_id": 7,
"pass_serial_no": null,
"card_no": "V013",
"number_of_people": 1,
"purpose_of_visit": "Meeting",
"in_gate": "Lobby",
"in_time": "2019-01-22 05:00:43",
"out_time": null,
"out_gate": null,
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 0,
"access_type": "card",
"created_at": "2019-01-22 05:00:43",
"updated_at": "2019-01-22 05:00:45",
"created_by": 151,
"updated_by": null,
"visitors": {
"visitor_id": 65100,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": "android",
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "test",
"last_name": null,
"gender": "M",
"mobile": "8097679764",
"email": null,
"image_path": null,
"visitor_type": "guest",
"coming_from": "vashi",
"image_large": null,
"image_medium": null,
"image_small": null
},
"unit": {
"building_unit_id": 96,
"fk_building_id": 1,
"unit_number": "1904",
"floor_no": "19",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
},
{
"log_id": 64890,
"fk_visitor_id": 65099,
"fk_building_unit_id": 96,
"company_id": 7,
"pass_serial_no": null,
"card_no": null,
"number_of_people": 1,
"purpose_of_visit": "nnxnx",
"in_gate": "Lobby",
"in_time": "2019-01-21 13:20:07",
"out_time": null,
"out_gate": null,
"in_vehicle_no": null,
"out_vehicle_no": null,
"in_vehicle_color": null,
"out_vehicle_color": null,
"is_handed_over": 0,
"access_type": "card",
"created_at": "2019-01-21 13:20:07",
"updated_at": "2019-01-21 13:20:07",
"created_by": 151,
"updated_by": null,
"visitors": {
"visitor_id": 65099,
"visitor_company_name": null,
"designation": null,
"industry": null,
"used_promotional_channel": null,
"interested_in": null,
"platform": "android",
"iso_code": "IN",
"dial_code": "91",
"company_id": 7,
"first_name": "jznznz",
"last_name": null,
"gender": "M",
"mobile": "9767967797",
"email": null,
"image_path": null,
"visitor_type": "guest",
"coming_from": "hzbzs",
"image_large": null,
"image_medium": null,
"image_small": null
},
"unit": {
"building_unit_id": 96,
"fk_building_id": 1,
"unit_number": "1904",
"floor_no": "19",
"building": {
"building_id": 1,
"building_name": "CyberOne"
}
}
}
]
}
}
It returns with the error :
Error info: typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), CodingKeys(stringValue: "users", intValue: nil)], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))
Below is the exact line where it causes the error :
var tmpComplexUnkeyedContainer = try container.nestedUnkeyedContainer(forKey: .complex)
Can someone suggest me reason.
Thank you.

Codable structures created by you are not parsable from your given response.
Please try below structure.
// To parse the JSON, add this file to your project and do:
// var respData = try? newJSONDecoder().decode(RespData.self, from: jsonData)
import Foundation
class RespData: Codable {
var app: App?
var statusCode: Int?
var data: DataClass?
enum CodingKeys: String, CodingKey {
case app = "app"
case statusCode = "status_code"
case data = "data"
}
init(app: App?, statusCode: Int?, data: DataClass?) {
self.app = app
self.statusCode = statusCode
self.data = data
}
}
class App: Codable {
var version: String?
var name: String?
var time: String?
enum CodingKeys: String, CodingKey {
case version = "version"
case name = "name"
case time = "time"
}
init(version: String?, name: String?, time: String?) {
self.version = version
self.name = name
self.time = time
}
}
class DataClass: Codable {
var metadata: Metadata?
var results: [Result]?
enum CodingKeys: String, CodingKey {
case metadata = "metadata"
case results = "results"
}
init(metadata: Metadata?, results: [Result]?) {
self.metadata = metadata
self.results = results
}
}
class Metadata: Codable {
var total: Int?
var perPage: Int?
var currentPage: Int?
var lastPage: Int?
var from: Int?
var to: Int?
enum CodingKeys: String, CodingKey {
case total = "total"
case perPage = "per_page"
case currentPage = "current_page"
case lastPage = "last_page"
case from = "from"
case to = "to"
}
init(total: Int?, perPage: Int?, currentPage: Int?, lastPage: Int?, from: Int?, to: Int?) {
self.total = total
self.perPage = perPage
self.currentPage = currentPage
self.lastPage = lastPage
self.from = from
self.to = to
}
}
class Result: Codable {
var logID: Int?
var fkVisitorID: Int?
var fkBuildingUnitID: Int?
var companyID: Int?
var passSerialNo: JSONNull?
var cardNo: String?
var numberOfPeople: Int?
var purposeOfVisit: PurposeOfVisit?
var inGate: Gate?
var inTime: String?
var outTime: String?
var outGate: Gate?
var inVehicleNo: JSONNull?
var outVehicleNo: JSONNull?
var inVehicleColor: JSONNull?
var outVehicleColor: JSONNull?
var isHandedOver: Int?
var accessType: AccessType?
var createdAt: String?
var updatedAt: String?
var createdBy: Int?
var updatedBy: Int?
var visitors: Visitors?
var unit: Unit?
enum CodingKeys: String, CodingKey {
case logID = "log_id"
case fkVisitorID = "fk_visitor_id"
case fkBuildingUnitID = "fk_building_unit_id"
case companyID = "company_id"
case passSerialNo = "pass_serial_no"
case cardNo = "card_no"
case numberOfPeople = "number_of_people"
case purposeOfVisit = "purpose_of_visit"
case inGate = "in_gate"
case inTime = "in_time"
case outTime = "out_time"
case outGate = "out_gate"
case inVehicleNo = "in_vehicle_no"
case outVehicleNo = "out_vehicle_no"
case inVehicleColor = "in_vehicle_color"
case outVehicleColor = "out_vehicle_color"
case isHandedOver = "is_handed_over"
case accessType = "access_type"
case createdAt = "created_at"
case updatedAt = "updated_at"
case createdBy = "created_by"
case updatedBy = "updated_by"
case visitors = "visitors"
case unit = "unit"
}
init(logID: Int?, fkVisitorID: Int?, fkBuildingUnitID: Int?, companyID: Int?, passSerialNo: JSONNull?, cardNo: String?, numberOfPeople: Int?, purposeOfVisit: PurposeOfVisit?, inGate: Gate?, inTime: String?, outTime: String?, outGate: Gate?, inVehicleNo: JSONNull?, outVehicleNo: JSONNull?, inVehicleColor: JSONNull?, outVehicleColor: JSONNull?, isHandedOver: Int?, accessType: AccessType?, createdAt: String?, updatedAt: String?, createdBy: Int?, updatedBy: Int?, visitors: Visitors?, unit: Unit?) {
self.logID = logID
self.fkVisitorID = fkVisitorID
self.fkBuildingUnitID = fkBuildingUnitID
self.companyID = companyID
self.passSerialNo = passSerialNo
self.cardNo = cardNo
self.numberOfPeople = numberOfPeople
self.purposeOfVisit = purposeOfVisit
self.inGate = inGate
self.inTime = inTime
self.outTime = outTime
self.outGate = outGate
self.inVehicleNo = inVehicleNo
self.outVehicleNo = outVehicleNo
self.inVehicleColor = inVehicleColor
self.outVehicleColor = outVehicleColor
self.isHandedOver = isHandedOver
self.accessType = accessType
self.createdAt = createdAt
self.updatedAt = updatedAt
self.createdBy = createdBy
self.updatedBy = updatedBy
self.visitors = visitors
self.unit = unit
}
}
enum AccessType: String, Codable {
case card = "card"
}
enum Gate: String, Codable {
case lobby = "Lobby"
}
enum PurposeOfVisit: String, Codable {
case meeting = "Meeting"
case nnxnx = "nnxnx"
}
class Unit: Codable {
var buildingUnitID: Int?
var fkBuildingID: Int?
var unitNumber: String?
var floorNo: String?
var building: Building?
enum CodingKeys: String, CodingKey {
case buildingUnitID = "building_unit_id"
case fkBuildingID = "fk_building_id"
case unitNumber = "unit_number"
case floorNo = "floor_no"
case building = "building"
}
init(buildingUnitID: Int?, fkBuildingID: Int?, unitNumber: String?, floorNo: String?, building: Building?) {
self.buildingUnitID = buildingUnitID
self.fkBuildingID = fkBuildingID
self.unitNumber = unitNumber
self.floorNo = floorNo
self.building = building
}
}
class Building: Codable {
var buildingID: Int?
var buildingName: BuildingName?
enum CodingKeys: String, CodingKey {
case buildingID = "building_id"
case buildingName = "building_name"
}
init(buildingID: Int?, buildingName: BuildingName?) {
self.buildingID = buildingID
self.buildingName = buildingName
}
}
enum BuildingName: String, Codable {
case cyberOne = "CyberOne"
}
class Visitors: Codable {
var visitorID: Int?
var visitorCompanyName: JSONNull?
var designation: JSONNull?
var industry: JSONNull?
var usedPromotionalChannel: JSONNull?
var interestedIn: JSONNull?
var platform: String?
var isoCode: ISOCode?
var dialCode: String?
var companyID: Int?
var firstName: String?
var lastName: String?
var gender: Gender?
var mobile: String?
var email: String?
var imagePath: String?
var visitorType: VisitorType?
var comingFrom: String?
var imageLarge: String?
var imageMedium: String?
var imageSmall: String?
enum CodingKeys: String, CodingKey {
case visitorID = "visitor_id"
case visitorCompanyName = "visitor_company_name"
case designation = "designation"
case industry = "industry"
case usedPromotionalChannel = "used_promotional_channel"
case interestedIn = "interested_in"
case platform = "platform"
case isoCode = "iso_code"
case dialCode = "dial_code"
case companyID = "company_id"
case firstName = "first_name"
case lastName = "last_name"
case gender = "gender"
case mobile = "mobile"
case email = "email"
case imagePath = "image_path"
case visitorType = "visitor_type"
case comingFrom = "coming_from"
case imageLarge = "image_large"
case imageMedium = "image_medium"
case imageSmall = "image_small"
}
init(visitorID: Int?, visitorCompanyName: JSONNull?, designation: JSONNull?, industry: JSONNull?, usedPromotionalChannel: JSONNull?, interestedIn: JSONNull?, platform: String?, isoCode: ISOCode?, dialCode: String?, companyID: Int?, firstName: String?, lastName: String?, gender: Gender?, mobile: String?, email: String?, imagePath: String?, visitorType: VisitorType?, comingFrom: String?, imageLarge: String?, imageMedium: String?, imageSmall: String?) {
self.visitorID = visitorID
self.visitorCompanyName = visitorCompanyName
self.designation = designation
self.industry = industry
self.usedPromotionalChannel = usedPromotionalChannel
self.interestedIn = interestedIn
self.platform = platform
self.isoCode = isoCode
self.dialCode = dialCode
self.companyID = companyID
self.firstName = firstName
self.lastName = lastName
self.gender = gender
self.mobile = mobile
self.email = email
self.imagePath = imagePath
self.visitorType = visitorType
self.comingFrom = comingFrom
self.imageLarge = imageLarge
self.imageMedium = imageMedium
self.imageSmall = imageSmall
}
}
enum Gender: String, Codable {
case empty = ""
case m = "M"
}
enum ISOCode: String, Codable {
case isoCodeIN = "IN"
}
enum VisitorType: String, Codable {
case guest = "guest"
case member = "member"
}
// MARK: Encode/decode helpers
class JSONNull: Codable, Hashable {
public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
return true
}
public var hashValue: Int {
return 0
}
public init() {}
public required init(from decoder: Decoder) throws {
var container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}

Related

Error Code: 1241. Operand should contain 1 column(s) On Updates and Trigger

I Have a soccer database, and I have a trigger (notas) that is calculating a player rating after the insert of his stats, I am able to create the trigger, but when I update the player stats it gives me Error Code: 1241
(My update is in Table JogadoresEstatísticasBrutas, but is because there is other trigger working, and that trigger insert stats on Table JogadoresEstatísticasPorJogo, After some tests I discovered that the problem is in Trigger Notas.)
DELIMITER //
CREATE TRIGGER Notas
AFTER UPDATE ON JogadoresEstatísticasPorJogo
FOR EACH ROW
begin
set #Nome = new.Nome;
set #GolsPJN = new.GolsPJ;
set #AstPJN = new.AssistsPJ;
set #PreAstPJN = new.PréAstPJ;
set #GrandesChancesCriadasPJN = new.GrandesChancesCriadasPJ;
set #GrandesChancesErradasPJN = new.GrandesChancesErradasPJ;
set #PassesTentadosPJN = new.PassesTentadosPJ;
set #PassesCompletosPJN = new.PassesCompletosPJ;
set #PorcentagemPassesPJN = new.PorcentagemPassesPJ;
set #DriblesTentadosPJN = new.DriblesTentadosPJ;
set #DriblesCompletosPJN = new.DriblesCompletosPJ;
set #ChutesTentadosPJN = new.ChutesTentadosPJ;
set #ChutesNoGolPJN = new.ChutesNoGolPJ;
set #ChutesBloqueadosPJN = new.ChutesBloqueadosPJ;
set #PerdadePossePJN = new.PerdadePossePJ;
set #DesarmesCompletosPJN = new.DesarmesCompletosPJ;
set #TentativasSofridasdeDriblePJN = new.TentativasSofridasdeDriblePJ;
set #DriblesSofridosPJN = new.DriblesSofridosPJ;
set #BloqueiosPJN = new.BloqueiosPJ;
set #InterceptacoesPJN = new.InterceptaçõesPJ;
set #DuelosAereosGanhosPJN = new.DuelosAéreosGanhosPJ;
set #DuelosAereosPerdidosPJN = new.DuelosAéreosPerdidosPJ;
set #FaltasCometidasPJN = new.FaltasCometidasPJ;
set #GolsNotas = #GolsPJN * 25;
set #GrandesChancesErradasNotas = (#GolsPJN - #GrandesChancesErradasPJN) * 17;
set #DriblesNotas = #DriblesCompletosPJN / #DriblesTentadosPJN * 2;
set #ChutesNotas = #ChutesnoGolPJN / #ChutesTentadosPJN * 15;
set #PerdadePosseNotas = #PerdadePossePJN / (#PassesTentadosPJN + #DriblesTentadosPJN) * (-65);
set #AstNotas = #AstPJN * 25;
set #PreAst = #PreAstPJN * 50;
set #GrandesChancesCriadas = #GrandesChancesCriadasPJN / #PassesCompletosPJN * 60;
set #PorcentagemNotas = #PorcentagemPassesPJN / 10 * 1.50;
set #DesarmesNotas = #DesarmesCompletosPJN * 25;
set #DriblesSofridosNotas = (10 - (#DriblesSofridosPJN / #TentativasSofridasdeDriblePJN * 3,5)) *2;
set #FaltasCometidasNotas = #FaltasCometidasPJN * (-8);
set #BloqueiosInterceptacoesNotas = (#BloqueiosPJN * 2 + #InterceptacoesPJN * 7) *3;
set #NotaOfensiva = truncate ((#GolsNotas + #GrandesChancesErradasNotas + DriblesNotas + ChutesNotas + PerdadePosseNotas) / 10 , 2);
set #NotaCriacao = truncate ((#AstNotas + #PreAst + #GrandesChancesCriadas + #PorcentagemNotas) / 10, 2);
set #NotaDefensiva = truncate ((#DesarmesNotas + #DriblesSofridosNotas + #FaltasCometidasNotas + #BloqueiosInterceptacoesNotas) / 10 , 2);
set #NotaGeral = (#NotaOfensiva + #NotaCriacao + #NotaDefensiva) / 3;
update JogadoresNotas set NotaOfensiva = #NotaOfensiva where Nome = #Nome;
update JogadoresNotas set NotaCriação = #NotaCriacao where Nome = #Nome;
update JogadoresNotas set NotaDefensiva = #NotaDefensiva where Nome = #Nome;
update JogadoresNotas set NotaGeral = #NotaGeral where Nome = #Nome;
end //
DELIMITER ;
My Updates:
DELIMITER // begin
Update JogadoresEstatísticasBrutas SET Nome = 'R', Jogos = "7", Gols = "3", Assists = "5", PréAst = "0", GrandesChancesCriadas = "10", GrandesChancesErradas = "4", PassesTentados = "65", PassesCompletos = "55", PorcentagemPasses = "84", DriblesTentados = "18", DriblesCompletos = "11", ChutesTentados = "7", ChutesNoGol = "5", ChutesBloqueados = "1", PerdadePosse = "13", DesarmesCompletos = "6", TentativasSofridasdeDrible = "8", DriblesSofridos = "4", Bloqueios = "10", Interceptações = "4", DuelosAéreosGanhos = "1", DuelosAéreosPerdidos = "0", FaltasCometidas = "2", FaltasSofridas = "2", ChutesSofridos = "6", Defesas = "3", ChutesDifíceis = "3", DefesasDifíceis = "0" where Nome = "R";
Update JogadoresEstatísticasBrutas SET Nome = 'N', Jogos = "7", Gols = "3", Assists = "2", PréAst = "1", GrandesChancesCriadas = "5", GrandesChancesErradas = "4", PassesTentados = "37", PassesCompletos = "29", PorcentagemPasses = "78", DriblesTentados = "12", DriblesCompletos = "6", ChutesTentados = "10", ChutesNoGol = "5", ChutesBloqueados = "0", PerdadePosse = "8", DesarmesCompletos = "3", TentativasSofridasdeDrible = "11", DriblesSofridos = "7", Bloqueios = "3", Interceptações = "0", DuelosAéreosGanhos = "1", DuelosAéreosPerdidos = "0", FaltasCometidas = "4", FaltasSofridas = "2", ChutesSofridos = "9", Defesas = "7", ChutesDifíceis = "2", DefesasDifíceis = "1" where Nome = "N";
Update JogadoresEstatísticasBrutas SET Nome = 'B', Jogos = "7", Gols = "6", Assists = "3", PréAst = "1", GrandesChancesCriadas = "4", GrandesChancesErradas = "6", PassesTentados = "54", PassesCompletos = "48", PorcentagemPasses = "88", DriblesTentados = "22", DriblesCompletos = "14", ChutesTentados = "25", ChutesNoGol = "10", ChutesBloqueados = "7", PerdadePosse = "14", DesarmesCompletos = "7", TentativasSofridasdeDrible = "10", DriblesSofridos = "6", Bloqueios = "4", Interceptações = "5", DuelosAéreosGanhos = "0", DuelosAéreosPerdidos = "3", FaltasCometidas = "4", FaltasSofridas = "4", ChutesSofridos = "7", Defesas = "4", ChutesDifíceis = "5", DefesasDifíceis = "2" where Nome = "B";
Update JogadoresEstatísticasBrutas SET Nome = 'F', Jogos = "7", Gols = "8", Assists = "1", PréAst = "1", GrandesChancesCriadas = "6", GrandesChancesErradas = "3", PassesTentados = "55", PassesCompletos = "40", PorcentagemPasses = "72", DriblesTentados = "18", DriblesCompletos = "10", ChutesTentados = "17", ChutesNoGol = "7", ChutesBloqueados = "4", PerdadePosse = "10", DesarmesCompletos = "9", TentativasSofridasdeDrible = "19", DriblesSofridos = "7", Bloqueios = "14", Interceptações = "3", DuelosAéreosGanhos = "0", DuelosAéreosPerdidos = "0", FaltasCometidas = "2", FaltasSofridas = "3", ChutesSofridos = "13", Defesas = "9", ChutesDifíceis = "7", DefesasDifíceis = "3" where Nome = "F";
Update JogadoresEstatísticasBrutas SET Nome = 'G', Jogos = "7", Gols = "9", Assists = "1", PréAst = "1", GrandesChancesCriadas = "6", GrandesChancesErradas = "5", PassesTentados = "52", PassesCompletos = "44", PorcentagemPasses = "84", DriblesTentados = "8", DriblesCompletos = "1", ChutesTentados = "29", ChutesNoGol = "21", ChutesBloqueados = "6", PerdadePosse = "11", DesarmesCompletos = "5", TentativasSofridasdeDrible = "15", DriblesSofridos = "9", Bloqueios = "9", Interceptações = "5", DuelosAéreosGanhos = "1", DuelosAéreosPerdidos = "0", FaltasCometidas = "0", FaltasSofridas = "2", ChutesSofridos = "5", Defesas = "2", ChutesDifíceis = "3", DefesasDifíceis = "1" where Nome = "G";
Update JogadoresEstatísticasBrutas SET Nome = 'D', Jogos = "7", Gols = "4", Assists = "0", PréAst = "1", GrandesChancesCriadas = "6", GrandesChancesErradas = "7", PassesTentados = "55", PassesCompletos = "51", PorcentagemPasses = "92", DriblesTentados = "12", DriblesCompletos = "6", ChutesTentados = "19", ChutesNoGol = "13", ChutesBloqueados = "4", PerdadePosse = "10", DesarmesCompletos = "9", TentativasSofridasdeDrible = "22", DriblesSofridos = "12", Bloqueios = "8", Interceptações = "1", DuelosAéreosGanhos = "0", DuelosAéreosPerdidos = "0", FaltasCometidas = "3", FaltasSofridas = "0", ChutesSofridos = "3", Defesas = "1", ChutesDifíceis = "2", DefesasDifíceis = "1" where Nome = "D";
end; DELIMITER;
Tables JogadoresEstatísticasBrutas and JogadoresNotas
CREATE TABLE IF NOT EXISTS JogadoresEstatísticasBrutas (
IdJogadores INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Nome VARCHAR(40) NULL,
Jogos INT NULL,
Gols INT NULL,
Assists INT NULL,
PréAst INT NULL,
GrandesChancesCriadas INT NULL,
GrandesChancesErradas INT NULL,
PassesTentados INT NULL,
PassesCompletos INT NULL,
PorcentagemPasses INT NULL,
DriblesTentados INT NULL,
DriblesCompletos INT NULL,
ChutesTentados INT NULL,
ChutesNoGol INT NULL,
ChutesBloqueados INT NULL,
PerdadePosse INT NULL,
DesarmesCompletos INT NULL,
TentativasSofridasdeDrible INT NULL,
DriblesSofridos INT NULL,
Bloqueios INT NULL,
Interceptações INT NULL,
DuelosAéreosGanhos INT NULL,
DuelosAéreosPerdidos INT NULL,
FaltasCometidas INT NULL,
FaltasSofridas INT NULL,
ChutesSofridos INT NULL,
Defesas INT NULL,
ChutesDifíceis INT NULL,
DefesasDifíceis INT NULL);
CREATE TABLE IF NOT EXISTS JogadoresNotas (
IdJogadores INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Nome VARCHAR(40) NULL,
Jogos INT NULL,
NotaOfensiva FLOAT (3, 2) NULL,
NotaCriação FLOAT (3, 2) NULL,
NotaDefesinva FLOAT (3, 2) NULL,
NotaGeral FLOAT (4, 2) NULL);
Per reference manual, you can use set to change multiple values that are , separated.
CREATE TRIGGER Notas
AFTER UPDATE ON JogadoresEstatísticasPorJogo
FOR EACH ROW
set #Nome = new.Nome,
#GolsPJN = new.GolsPJ,
#AstPJN = new.AssistsPJ,
....

Extracting data from very nested JSON in Azure SQL

I have nested JSON file:
"vehicleStatusResponse": {
"vehicleStatuses": [
{
"vin": "ABC1234567890",
"triggerType": {
"triggerType": "TIMER",
"context": "RFMS",
"driverId": {
"tachoDriverIdentification": {
"driverIdentification": "123456789",
"cardIssuingMemberState": "BRA",
"driverAuthenticationEquipment": "CARD",
"cardReplacementIndex": "0",
"cardRenewalIndex": "1"
}
}
},
"receivedDateTime": "2020-02-12T04:11:19.221Z",
"hrTotalVehicleDistance": 103306960,
"totalEngineHours": 3966.6216666666664,
"driver1Id": {
"tachoDriverIdentification": {
"driverIdentification": "BRA1234567"
}
},
"engineTotalFuelUsed": 48477520,
"accumulatedData": {
"durationWheelbaseSpeedOverZero": 8309713,
"distanceCruiseControlActive": 8612200,
"durationCruiseControlActive": 366083,
"fuelConsumptionDuringCruiseActive": 3064170,
"durationWheelbaseSpeedZero": 5425783,
"fuelWheelbaseSpeedZero": 3332540,
"fuelWheelbaseSpeedOverZero": 44709670,
"ptoActiveClass": [
{
"label": "wheelbased speed >0",
"seconds": 16610,
"meters": 29050,
"milliLitres": 26310
},
{
"label": "wheelbased speed =0",
"seconds": 457344,
"milliLitres": 363350
It is already imported from Azure BLOB Storage to SQL DB and now I need to extract data from it to table. I've already used a T-SQL request to do that, but it returned me blank table with only headers:
SELECT response.*
FROM OPENROWSET (BULK 'response3.json', DATA_SOURCE = 'VCBI24', SINGLE_CLOB) as j
CROSS APPLY OPENJSON(BulkColumn)
WITH ( vehiclestatusResponse nvarchar (100), vehicleStatuses nvarchar (100), vin nvarchar (100), triggerType nvarchar (100), context nvarchar (100) and etc...) AS response
How can I handle it?
Thanks a lot for your attention!
You can supply a path with OPENJSON which allows you to drill in to nested JSON, eg
SELECT *
FROM OPENJSON( #json, '$.vehicleStatusResponse.vehicleStatuses' )
WITH (
vin VARCHAR(50) '$.vin',
triggerType VARCHAR(50) '$.triggerType.triggerType',
context VARCHAR(50) '$.triggerType.context',
driverIdentification VARCHAR(50) '$.triggerType.driverId.tachoDriverIdentification.driverIdentification',
cardIssuingMemberState VARCHAR(50) '$.triggerType.driverId.tachoDriverIdentification.cardIssuingMemberState',
receivedDateTime DATETIME '$.receivedDateTime',
engineTotalFuelUsed INT '$.engineTotalFuelUsed'
)
Full script example:
DECLARE #json VARCHAR(MAX) = '{
"vehicleStatusResponse": {
"vehicleStatuses": [
{
"vin": "ABC1234567890",
"triggerType": {
"triggerType": "TIMER",
"context": "RFMS",
"driverId": {
"tachoDriverIdentification": {
"driverIdentification": "123456789",
"cardIssuingMemberState": "BRA",
"driverAuthenticationEquipment": "CARD",
"cardReplacementIndex": "0",
"cardRenewalIndex": "1"
}
}
},
"receivedDateTime": "2020-02-12T04:11:19.221Z",
"hrTotalVehicleDistance": 103306960,
"totalEngineHours": 3966.6216666666664,
"driver1Id": {
"tachoDriverIdentification": {
"driverIdentification": "BRA1234567"
}
},
"engineTotalFuelUsed": 48477520,
"accumulatedData": {
"durationWheelbaseSpeedOverZero": 8309713,
"distanceCruiseControlActive": 8612200,
"durationCruiseControlActive": 366083,
"fuelConsumptionDuringCruiseActive": 3064170,
"durationWheelbaseSpeedZero": 5425783,
"fuelWheelbaseSpeedZero": 3332540,
"fuelWheelbaseSpeedOverZero": 44709670,
"ptoActiveClass": [
{
"label": "wheelbased speed >0",
"seconds": 16610,
"meters": 29050,
"milliLitres": 26310
},
{
"label": "wheelbased speed =0",
"seconds": 457344,
"milliLitres": 363350
}
]
}
}
]
}}}}}}}}'
SELECT *
FROM OPENJSON( #json, '$.vehicleStatusResponse.vehicleStatuses' )
WITH (
vin VARCHAR(50) '$.vin',
triggerType VARCHAR(50) '$.triggerType.triggerType',
context VARCHAR(50) '$.triggerType.context',
driverIdentification VARCHAR(50) '$.triggerType.driverId.tachoDriverIdentification.driverIdentification',
cardIssuingMemberState VARCHAR(50) '$.triggerType.driverId.tachoDriverIdentification.cardIssuingMemberState',
receivedDateTime DATETIME '$.receivedDateTime',
engineTotalFuelUsed INT '$.engineTotalFuelUsed'
)
My results:
Read more about OPENJSON here:
https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql?view=sql-server-ver15
A second example. With OPENJSON you can either supply the json path expression is more explicit and gives you more control particularly for nested JSON. If the JSON is relatively simple, you do not have to supply the paths, eg
DECLARE #json VARCHAR(MAX) = '{
"ptoActiveClass": [
{
"label": "wheelbased speed >0",
"seconds": 16610,
"meters": 29050,
"milliLitres": 26310
},
{
"label": "wheelbased speed =0",
"seconds": 457344,
"milliLitres": 363350
}
]
}'
SELECT *
FROM OPENJSON( #json, '$.ptoActiveClass' )
WITH (
label VARCHAR(50),
seconds INT,
meters INT,
milliLitres INT
)
SELECT *
FROM OPENJSON( #json, '$.ptoActiveClass' )
WITH (
label VARCHAR(50) '$.label',
seconds VARCHAR(50) '$.seconds',
meters VARCHAR(50) '$.meters',
milliLitres VARCHAR(50) '$.milliLitres'
)

Parsing a List in Flutter / Dart

I've a list that looks like this:
[{id: 1, user_id: 3, challenge_id: 1, created_at: 2019-06-09 06:36:39, image_caption: Enter your image caption here, image_path: https://res.cloudinary.com/dqrmgdpcf/image/upload/v1560062199/zex61jegvqwkevq6qrmd.jpg, image: null, user_upvoted: null, user_downvoted: null, score: 0}, {id: 2, user_id: 2, challenge_id: 1, created_at: 2019-06-12 09:17:07, image_caption: , image_path: https://res.cloudinary.com/dqrmgdpcf/image/upload/v1560331027/dj94sjzufx8gznyxrves.jpg, image: null, user_upvoted: null, user_downvoted: null, score: 0},
{id: 2, user_id: 3, challenge_id: 1, created_at: 2019-06-09 06:36:39, image_caption: Enter your image caption here, image_path: https://res.cloudinary.com/dqrmgdpcf/image/upload/v1560062199/zex61jegvqwkevq6qrmd.jpg, image: null, user_upvoted: null, user_downvoted: null, score: 0}, {id: 2, user_id: 2, challenge_id: 1, created_at: 2019-06-12 09:17:07, image_caption: , image_path: https://res.cloudinary.com/dqrmgdpcf/image/upload/v1560331027/dj94sjzufx8gznyxrves.jpg, image: null, user_upvoted: null, user_downvoted: null, score: 0},
{id: 3, user_id: 3, challenge_id: 1, created_at: 2019-06-09 06:36:39, image_caption: Enter your image caption here, image_path: https://res.cloudinary.com/dqrmgdpcf/image/upload/v1560062199/zex61jegvqwkevq6qrmd.jpg, image: null, user_upvoted: null, user_downvoted: null, score: 0}, {id: 2, user_id: 2, challenge_id: 1, created_at: 2019-06-12 09:17:07, image_caption: , image_path: https://res.cloudinary.com/dqrmgdpcf/image/upload/v1560331027/dj94sjzufx8gznyxrves.jpg, image: null, user_upvoted: null, user_downvoted: null, score: 0}]
So it's basically 3 objects.
The object model looks like this:
class ChallengeUpload {
int id = 0;
int userId = 0;
int challengeId = 0;
String createdAt = "";
String imageCaption = "";
String imagePath = "";
File image;
String userUpvoted = "";
String userDownvoted = "";
int score = 0;
ChallengeUpload();
ChallengeUpload.fromJson(Map<String, dynamic> json) {
id = json['id'];
userId = json['user_id'];
challengeId = json['challenge_id'];
createdAt = json['created_at'];
imageCaption = json['image_caption'];
imagePath = json['image_path'];
userUpvoted = json['user_upvoted'];
userDownvoted = json['user_downvoted'];
score = json['score'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['user_id'] = this.userId;
data['challenge_id'] = this.challengeId;
data['created_at'] = this.createdAt;
data['image_caption'] = this.imageCaption;
data['image_path'] = this.imagePath;
data['user_upvoted'] = this.userUpvoted;
data['user_downvoted'] = this.userDownvoted;
data['score'] = this.score;
return data;
}
}
I can't seem to figure out how to parse this list.
If it's just a single object that's being returned by my API I run it through this function:
currentChallenge = Challenge.fromJson(response.data);
How to do something similar but then end up with a UploadedChallengesList instead of a single object?
I've tried:
challengeUploads = json.decode(response.data).map<ChallengeUpload>((dynamic challengeUpload) => ChallengeUpload.fromJson(challengeUpload)).toList();
It'll print:
I/flutter ( 2660): type 'List<dynamic>' is not a subtype of type 'String'
My JSON:
{
id:1,
user_id:3,
challenge_id:1,
created_at:2019-06 -09 06:36:39,
image_caption:Enter your image caption here,
image_path: https://res.cloudinary.com/dqrmgdpcf/image/upload/v1560062199/zex61jegvqwkevq6qrmd.jpg,
image:null,
user_upvoted:null,
user_downvoted:null,
score:0
},
{
id:2,
user_id:2,
challenge_id:1,
created_at:2019-06 -12 09:17:07,
image_caption:,
image_path: https://res.cloudinary.com/dqrmgdpcf/image/upload/v1560331027/dj94sjzufx8gznyxrves.jpg,
image:null,
user_upvoted:null,
user_downvoted:null,
score:0
}
Edit: I found out it had to do with the library I'm using to do API calls. I use Dio and my code ended up looking like this:
Response response = await Dio().get(url,
options: Options(
headers: {"Authorization": accessToken},
responseType: ResponseType.json));
setState(() {
challengeUploads = response.data
.map<ChallengeUpload>((dynamic challengeUpload) =>
ChallengeUpload.fromJson(challengeUpload))
.toList();
});
How about this?
List<Map<String, dynamic>> jsonList = json.decode(response.data.toString()) as List;
List<ChallengeUpload> myList = jsonList.map(
(jsonElement) => ChallengeUpload.fromJson(jsonElement)
).toList();

how can i parse json weather response

this is my response from weather map api
{
"message": "accurate",
"cod": "200",
"count": 3,
"list": [
{
"id": 2641549,
"name": "Newtonhill",
"coord": {
"lat": 57.0333,
"lon": -2.15
},
"main": {
"temp": 275.15,
"pressure": 1010,
"humidity": 93,
"temp_min": 275.15,
"temp_max": 275.15
},
"dt": 1521204600,
"wind": {
"speed": 9.3,
"deg": 120,
"gust": 18
},
"sys": {
"country": ""
},
"rain": null,
"snow": null,
"clouds": {
"all": 75
},
"weather": [
{
"id": 311,
"main": "Drizzle",
"description": "rain and drizzle",
"icon": "09d"
}
]
}
how can i get the description i did get the temperature using a retrofit by seriazable object but i could'nt get the weather description
i did that to get temperature and the country
class WeatherResponse {
#SerializedName("sys")
var sys: Sys? = null
#SerializedName("main")
var main: Main? = null
#SerializedName("weather")
var weather: Weather? = null
}
class Main {
#SerializedName("temp")
var temp: Float = 0.0f
}
and i my main class im using a callback
fun getCurrentData() {
val retrofit = Retrofit.Builder()
.baseUrl(BaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
val service = retrofit.create(WeatherService::class.java)
val call = service.getCurrentWeatherData(lat, lon, AppId)
call.enqueue(object : Callback<WeatherResponse> {
override fun onResponse(call: Call<WeatherResponse>, response: Response<WeatherResponse>) {
if (response.code() == 200) {
val weatherResponse = response.body()!!
var temp = (weatherResponse.main!!.temp - 273).toString().substring(0,3) + " ºC"
tmp.text=temp
}
}
override fun onFailure(call: Call<WeatherResponse>, t: Throwable) {
}
})
}
Here is POJO class for your JSON. It now can be parsed easily.
WeatherResponse.kt
data class WeatherResponse(
#SerializedName("cod")
val cod: String? = null,
#SerializedName("count")
val count: Int? = null,
#SerializedName("list")
val list: List<X?>? = null,
#SerializedName("message")
val message: String? = null
) {
data class X(
#SerializedName("clouds")
val clouds: Clouds? = null,
#SerializedName("coord")
val coord: Coord? = null,
#SerializedName("dt")
val dt: Int? = null,
#SerializedName("id")
val id: Int? = null,
#SerializedName("main")
val main: Main? = null,
#SerializedName("name")
val name: String? = null,
#SerializedName("rain")
val rain: Any? = null,
#SerializedName("snow")
val snow: Any? = null,
#SerializedName("sys")
val sys: Sys? = null,
#SerializedName("weather")
val weather: List<Weather?>? = null,
#SerializedName("wind")
val wind: Wind? = null
)
data class Clouds(
#SerializedName("all")
val all: Int?
)
data class Coord(
#SerializedName("lat")
val lat: Double? = null,
#SerializedName("lon")
val lon: Double? = null
)
data class Main(
#SerializedName("humidity")
val humidity: Int? = null,
#SerializedName("pressure")
val pressure: Int? = null,
#SerializedName("temp")
val temp: Double? = null,
#SerializedName("temp_max")
val tempMax: Double? = null,
#SerializedName("temp_min")
val tempMin: Double? = null
)
data class Sys(
#SerializedName("country")
val country: String?
)
data class Weather(
#SerializedName("description")
val description: String? = null,
#SerializedName("icon")
val icon: String? = null,
#SerializedName("id")
val id: Int? = null,
#SerializedName("main")
val main: String? = null
)
data class Wind(
#SerializedName("deg")
val deg: Int? = null,
#SerializedName("gust")
val gust: Int? = null,
#SerializedName("speed")
val speed: Double? = null
)
}
You can get Weather description by using
var description = weatherResponse.list?.get(0)?.weather?.get(0)?.description

PostgreSQL 9.5.2 - Building a JSON object/String - Multiple 1:many relationships

I am playing with PostgreSQL building JSON objects/strings for a project.
I am new with the syntax and am looking for "best practices" in doing this.
Imagine the following tables (ignoring the design)
CREATE TABLE object (
item_id INT
,name VARCHAR(64)
,category_id INT
)
CREATE TABLE object_features (
item_id INT
,feature_1 VARCHAR(64)
,val_1 FLOAT
,feature_2 VARCHAR(64)
,val_2 FLOAT
,feature_3 VARCHAR(64)
,val_3 FLOAT
,feature_n VARCHAR(64)
,val_n FLOAT
)
CREATE TABLE category (
id INT
,name VARCHAR(64)
)
CREATE TABLE comment (
object_id INT
,name VARCHAR(64)
,date DATETIME
,score INT
)
How would you create the following JSON (or at least as close as possible)?
[{
"item_id": 1234,
"category": "category 1",
"name": "xyz",
"features": [{
"feature_1": "val_1",
"highlight": "Y"
}, {
"feature_4": "val_2",
"highlight": "Y"
}, {
"feature_3": "val_3",
"highlight": "N"
}, {
"feature_n": "val_n",
"highlight": "Y"
}],
"comments": [{
"name": "larry",
"date": "2016-04-01",
"score": 1
}, {
"name": "harry",
"date": "2016-03-01",
"score": 5
}]
}, {
"item_id": 434,
"category": "category 2",
"name": "dda",
"features": [{
"feature_1": "val_1",
"highlight": "N"
}, {
"feature_4": "val_2",
"highlight": "N"
}, {
"feature_3": "val_3",
"highlight": "N"
}, {
"feature_n": "val_n",
"highlight": "N"
}],
"comments": [{
"name": "merry",
"date": "2016-04-01",
"score": 1
}]
}]
Regards,
G