Having Additional properties that are not on the JSON Object
plspalding opened this issue · 5 comments
I would like to add an additional property onto my objects. However this property does not exist on the json object. If I do a let property then I can set the object and everything compiles fine. However I would like to be able to change this particular property on the object later on so I changed it to a var and I get an error message.
Error Messages
Cannot convert value of type '(String, String, Bool, SortingValues) -> Restaurant' to expected argument type '() -> () -> (_) -> Restaurant'
Sample JSON
{
"restaurants": [{
"name": "Tanoshii Sushi",
"status": "open",
"sortingValues": {
"bestMatch": 0.0,
"newest": 96.0,
"ratingAverage": 4.5,
"distance": 1190,
"popularity": 17.0,
"averageProductPrice": 1536,
"deliveryCosts": 200,
"minCost": 1000
}
}, {
"name": "Tandoori Express",
"status": "closed",
"sortingValues": {
"bestMatch": 1.0,
"newest": 266.0,
"ratingAverage": 4.5,
"distance": 2308,
"popularity": 123.0,
"averageProductPrice": 1146,
"deliveryCosts": 150,
"minCost": 1300
}
}]
}
Models
struct Restaurant: Equatable {
public static func ==(lhs: Restaurant, rhs: Restaurant) -> Bool {
return lhs.name == rhs.name
}
let name: String
let status: String
var isFavorite: Bool = false // This is the property I would like to add but doesn't exist in the json.
let sortingValues: SortingValues
}
extension Restaurant: Decodable {
static func decode(_ json: JSON) -> Decoded<Restaurant> {
return curry(Restaurant.init)
<^> json <| "name"
<*> json <| "status"
<*> json <| "sortingValues"
}
}
}
Argo Version
Argo (4.1.2)
Dependency Manager
Cocoapods
Thanks.
I'm pretty sure this is because doing that changes the default initializer that Swift generates for your model. You should try creating your own init
so you can cater it to your exact needs in cases like this.
Also, this issue probably has more to do with the default value. If you remove the default value, then you'll need to specify that property in the decode
function if it's a let
or a var
. With a default value, a let
property does not generate that value in the init
since you set the constant. In the case of a var
, the generated init
will contain that property which is why you're getting the error in your decode
function.
Hi Tony, thanks for the response. I have tried adding my own custom init method inside my Restaurant struct but am still getting the same error. I have also tried having a var without a default value and with a default value. All seem to produce the same error. Please see code below:
struct Restaurant: Equatable {
public static func ==(lhs: Restaurant, rhs: Restaurant) -> Bool {
return lhs.name == rhs.name
}
let name: String
let status: String
var isFavorite: Bool
// var isFavorite: Bool = false
let sortingValues: SortingValues
var currentStatus: Double {
get {
switch status {
case "open":
return 2
case "order ahead":
return 1
default:
return 0
}
}
}
init(name: String, status: String, isFavorite: Bool = false, sortingValues: SortingValues) {
self.name = name
self.status = status
self.isFavorite = isFavorite
self.sortingValues = sortingValues
}
}
Is there something I need to do in the decode method?
Many thanks.
Did you update your decode function to have 4 properties? If your init
takes 4 properties you'll need to make sure the decode function lines up too. It looks like the decode function you have above is missing the isFavorite
key. If that isn't being parsed in the JSON, you'll still need to add it to your model. You can add a default like this <*> pure(false)
.
👍
Yes, I was missing <*> pure(false)
. Everything now works as expected.
Many thanks :-)
Good to hear!