Convert all wrong type return JSON to specific type
wongzigii opened this issue · 6 comments
Say I am facing this situation: The server might somehow return a wrong type, eg, Int,
How can I force cast the wrong Int
type into the correct String
type?
In my case, I will get an typeMismatch
error, when running into the second decoded object.
Error Messages
List all the error messages or warnings you are seeing, if any.
Sample JSON
{"result":
[
{
"title": "Title1",
"balance": "1234" // or somehow might be 1234
},
{
"title": "Title2",
"balance": 1234
}
]}
Models
All models involved, including their Decodable
implementations.
struct User {
title: String,
balance: String
}
extension User: Decodable {
// ...
}
Argo Version
_example: Argo 4.1.2
Dependency Manager
examples: Carthage, Cocoapods, git submodules, copied code, etc.
Ideally this shouldn't happen. If you control the API you should definitely try to ensure that objects are sent back with a consistent type for a specific key.
That being said: You can handle this on the client side by leveraging Alternative. In your case, if you want to store the result as a String, it's fairly straightforward because you don't need to handle potential failures when converting to Int. Maybe something like:
// this can be put wherever you want, based on preference
extension Int {
static func toString(_ int: Int) -> String {
return "\(int)"
}
}
extension User: Argo.Decodable {
static func decode(_ json: JSON) -> Decoded<User> {
return curry(User.init)
<^> json <| "title"
<*> (json <| "balance") <|> (json <| "balance).map(Int.toString)
}
}
FWIW, you could use String.init(describing:)
too:
(json <| "balance").map(String.init)
oh yeah right sure
Closing now. Thanks!
@gfontenot Oh I just figure out the alternative operator <|>
need to wrap a parenthesis to work around. 👍
Ah, yeah, I still don't have a great mental-model for the operator precedence (which is why I'm proposing removing some of them)