{"action":"created","issue":{"url":"https://api.github.com/repos/Nike-Inc/Elevate/issues/8","repository_url":"https://api.github.com/repos/Nike-Inc/Elevate","labels_url":"https://api.github.com/repos/Nike-Inc/Elevate/issues/8/labels{/name}","comments_url":"https://api.github.com/repos/Nike-Inc/Elevate/issues/8/comments","events_url":"https://api.github.com/repos/Nike-Inc/Elevate/issues/8/events","html_url":"https://github.com/Nike-Inc/Elevate/issues/8","id":172933670,"number":8,"title":"How to parse array of polymorphic objects?","user":{"login":"rehsals","id":892176,"avatar_url":"https://avatars.githubusercontent.com/u/892176?v=3","gravatar_id":"","url":"https://api.github.com/users/rehsals","html_url":"https://github.com/rehsals","followers_url":"https://api.github.com/users/rehsals/followers","following_url":"https://api.github.com/users/rehsals/following{/other_user}","gists_url":"https://api.github.com/users/rehsals/gists{/gist_id}","starred_url":"https://api.github.com/users/rehsals/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rehsals/subscriptions","organizations_url":"https://api.github.com/users/rehsals/orgs","repos_url":"https://api.github.com/users/rehsals/repos","events_url":"https://api.github.com/users/rehsals/events{/privacy}","received_events_url":"https://api.github.com/users/rehsals/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Nike-Inc/Elevate/labels/decoder","name":"decoder","color":"69B805"},{"url":"https://api.github.com/repos/Nike-Inc/Elevate/labels/question","name":"question","color":"FF7E00"}],"state":"closed","locked":false,"assignee":{"login":"cnoon","id":169110,"avatar_url":"https://avatars.githubusercontent.com/u/169110?v=3","gravatar_id":"","url":"https://api.github.com/users/cnoon","html_url":"https://github.com/cnoon","followers_url":"https://api.github.com/users/cnoon/followers","following_url":"https://api.github.com/users/cnoon/following{/other_user}","gists_url":"https://api.github.com/users/cnoon/gists{/gist_id}","starred_url":"https://api.github.com/users/cnoon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cnoon/subscriptions","organizations_url":"https://api.github.com/users/cnoon/orgs","repos_url":"https://api.github.com/users/cnoon/repos","events_url":"https://api.github.com/users/cnoon/events{/privacy}","received_events_url":"https://api.github.com/users/cnoon/received_events","type":"User","site_admin":false},"assignees":[{"login":"cnoon","id":169110,"avatar_url":"https://avatars.githubusercontent.com/u/169110?v=3","gravatar_id":"","url":"https://api.github.com/users/cnoon","html_url":"https://github.com/cnoon","followers_url":"https://api.github.com/users/cnoon/followers","following_url":"https://api.github.com/users/cnoon/following{/other_user}","gists_url":"https://api.github.com/users/cnoon/gists{/gist_id}","starred_url":"https://api.github.com/users/cnoon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cnoon/subscriptions","organizations_url":"https://api.github.com/users/cnoon/orgs","repos_url":"https://api.github.com/users/cnoon/repos","events_url":"https://api.github.com/users/cnoon/events{/privacy}","received_events_url":"https://api.github.com/users/cnoon/received_events","type":"User","site_admin":false}],"milestone":null,"comments":2,"created_at":"2016-08-24T12:03:02Z","updated_at":"2016-08-24T19:24:33Z","closed_at":"2016-08-24T18:57:52Z","body":"Hi! Thanks for wonderful framework.\r\nI've encountered one issue, I can't figure out.\r\nLet's say I have:\r\n```\r\nclass A {\r\n    let type: String\r\n    /*lots of properties*/\r\n }\r\n```\r\nand\r\n ```\r\nfinal class B: A {\r\n    /*some other properties*/\r\n}\r\n```\r\nIn my response I have JSON-array of objects and some of them turn out to be `B`'s. The type of object determined by `type` field. Is it possible to use Elevate in this situation? How should I organise my decoding? "},"comment":{"url":"https://api.github.com/repos/Nike-Inc/Elevate/issues/comments/242179703","html_url":"https://github.com/Nike-Inc/Elevate/issues/8#issuecomment-242179703","issue_url":"https://api.github.com/repos/Nike-Inc/Elevate/issues/8","id":242179703,"user":{"login":"AtomicCat","id":270624,"avatar_url":"https://avatars.githubusercontent.com/u/270624?v=3","gravatar_id":"","url":"https://api.github.com/users/AtomicCat","html_url":"https://github.com/AtomicCat","followers_url":"https://api.github.com/users/AtomicCat/followers","following_url":"https://api.github.com/users/AtomicCat/following{/other_user}","gists_url":"https://api.github.com/users/AtomicCat/gists{/gist_id}","starred_url":"https://api.github.com/users/AtomicCat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AtomicCat/subscriptions","organizations_url":"https://api.github.com/users/AtomicCat/orgs","repos_url":"https://api.github.com/users/AtomicCat/repos","events_url":"https://api.github.com/users/AtomicCat/events{/privacy}","received_events_url":"https://api.github.com/users/AtomicCat/received_events","type":"User","site_admin":false},"created_at":"2016-08-24T19:24:33Z","updated_at":"2016-08-24T19:24:33Z","body":"This is eating at my brain...\r\n\r\nAlternative approach with fewer optionals:\r\n```swift\r\nimport Elevate\r\n\r\nclass A: Decodable {\r\n    let type: String\r\n    let thing: String\r\n\r\n    required init(json: AnyObject) throws {\r\n        let typePath = \"type\"\r\n        let thingPath = \"thing\"\r\n        let properties = try Parser.parseProperties(json: json) { make in\r\n            make.propertyForKeyPath(typePath, type: .String)\r\n            make.propertyForKeyPath(thingPath, type: .String)\r\n        }\r\n\r\n        self.type = properties <-! typePath\r\n        self.thing = properties <-! thingPath\r\n    }\r\n}\r\n\r\nfinal class B: A {\r\n    let other: String\r\n\r\n    required init(json: AnyObject) throws {\r\n        let otherPath = \"other\"\r\n\r\n        let properties = try Parser.parseProperties(json: json) { make in\r\n            make.propertyForKeyPath(otherPath, type: .String)\r\n        }\r\n\r\n        self.other = properties <-! otherPath\r\n        try super.init(json: json)\r\n    }\r\n}\r\n\r\nclass PolyDecoder: Decoder {\r\n    func decodeObject(object: AnyObject) throws -> Any {\r\n        let typePath = \"type\"\r\n        let properties = try Parser.parseProperties(json: object) { make in\r\n            make.propertyForKeyPath(typePath, type: .String)\r\n        }\r\n\r\n        let type: String = properties <-! typePath\r\n\r\n        if type == \"ClassA\" {\r\n            return try A(json: object)\r\n        } else if type == \"ClassB\" {\r\n            return try B(json: object)\r\n        } else {\r\n            throw ParserError.Validation(failureReason: \"Unknown type\")\r\n        }\r\n    }\r\n}\r\n\r\nlet json = [\r\n    [ \"type\": \"ClassA\", \"thing\": \"foo\" ],\r\n    [ \"type\": \"ClassB\", \"thing\": \"bar\", \"other\": \"whatever\" ],\r\n]\r\n\r\ndo {\r\n    let data = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted)\r\n    let objects: [AnyObject] = try Parser.parseArray(data: data, withDecoder: PolyDecoder())\r\n\r\n    // Show me\r\n    objects.forEach { print($0) }\r\n} catch {\r\n    print(\"Error occurred: \\(error)\")\r\n}\r\n```\r\n\r\nIf you don't need B to be a subclass of A, one option would be to put the extra properties that B has in an optional struct in A and handle it in a single decoder.\r\n\r\nIf they don't need to be classes, you might have additional options by using structs."}}
{"actor":{"display_login":"AtomicCat"}}