{"action":"created","issue":{"url":"https://api.github.com/repos/weichx/cerialize/issues/16","labels_url":"https://api.github.com/repos/weichx/cerialize/issues/16/labels{/name}","comments_url":"https://api.github.com/repos/weichx/cerialize/issues/16/comments","events_url":"https://api.github.com/repos/weichx/cerialize/issues/16/events","html_url":"https://github.com/weichx/cerialize/issues/16","id":124573403,"number":16,"title":"OnDeserialized hook is not called when a class have no @deserialize field","user":{"login":"1ambda","id":4968473,"avatar_url":"https://avatars.githubusercontent.com/u/4968473?v=3","gravatar_id":"","url":"https://api.github.com/users/1ambda","html_url":"https://github.com/1ambda","followers_url":"https://api.github.com/users/1ambda/followers","following_url":"https://api.github.com/users/1ambda/following{/other_user}","gists_url":"https://api.github.com/users/1ambda/gists{/gist_id}","starred_url":"https://api.github.com/users/1ambda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/1ambda/subscriptions","organizations_url":"https://api.github.com/users/1ambda/orgs","repos_url":"https://api.github.com/users/1ambda/repos","events_url":"https://api.github.com/users/1ambda/events{/privacy}","received_events_url":"https://api.github.com/users/1ambda/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2016-01-02T03:42:34Z","updated_at":"2016-01-04T15:58:12Z","closed_at":null,"body":"Assume that we have models deserializing Github API responses like\r\n\r\n```typescript\r\nexport class GithubEvent {\r\n  @deserializeAs(\"id\") public event_id: string;\r\n  @deserializeAs(\"type\") public event_type: string;\r\n  @deserializeAs(\"created_at\") public created_at: string;\r\n  public actor: string; /** actor.login */\r\n  public repo: string; /** owner/repo_name */\r\n\r\n  public static OnDeserialized(instance : GithubEvent, json : any) : void {\r\n    if (!_.isEmpty(json) && !_.isEmpty(json.actor))\r\n      instance.actor = json.actor.login;\r\n\r\n    if (!_.isEmpty(json) && !_.isEmpty(json.repo))\r\n      instance.repo = json.repo.name;\r\n  }\r\n}\r\n\r\n@inheritSerialization(GithubEvent)\r\nexport class GithubRepositoryEvent extends GithubEvent {\r\n  public static EVENT_TYPE = \"RepositoryEvent\";\r\n}\r\n\r\nexport class GithubForkEventPayload {\r\n  /** even if ForkEventPayload doesn't need to have action field,\r\n   *  we need it otherwise `OnDeserialized` is not called\r\n   */\r\n  @deserializeAs(\"action\") public action: string;\r\n  public forkee_id: string;\r\n  public forkee_name: string;\r\n  public forkee_full_name: string;\r\n  public forkee_url: string;\r\n  public forkee_language: string;\r\n\r\n  public static OnDeserialized(instance: GithubForkEventPayload, payload: any): void {\r\n    if (_.isEmpty(payload)) return;\r\n\r\n    if (!_.isEmpty(payload.forkee)) {\r\n      let forkee = payload.forkee;\r\n      instance.forkee_id = forkee.id;\r\n      instance.forkee_name = forkee.name;\r\n      instance.forkee_full_name = forkee.full_name;\r\n      instance.forkee_url = forkee.html_url;\r\n      instance.forkee_language = forkee.language;\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n```typescript\r\n// spec\r\nlet forkEvent1 = {\r\n  \"id\": \"3475819128\",\r\n  \"type\": \"ForkEvent\",\r\n  \"actor\": {\r\n    \"login\": \"1ambda\",\r\n  },\r\n  \"repo\": {\r\n    \"id\": 41002005,\r\n    \"name\": \"weichx/cerialize\",\r\n    \"url\": \"https://api.github.com/repos/weichx/cerialize\"\r\n  },\r\n  \"payload\": {\r\n    \"forkee\": {\r\n      \"id\": 48599725,\r\n      \"name\": \"cerialize\",\r\n      \"full_name\": \"1ambda/cerialize\",\r\n      \"private\": false,\r\n      \"html_url\": \"https://github.com/1ambda/cerialize\",\r\n      \"language\": \"TypeScript\",\r\n    }\r\n  },\r\n  \"created_at\": \"2015-12-26T04:47:20Z\"\r\n};\r\n\r\ndescribe(\"ForkEvent\", () => {\r\n  it(\"should be deserialized\", () => {\r\n    let raw = forkEvent1;\r\n    let forkEvent = GithubForkEvent.deserialize(GithubForkEvent, raw);\r\n\r\n    expect(forkEvent.event_id).toEqual(raw.id);\r\n    expect(forkEvent.event_type).toEqual(raw.type);\r\n    expect(forkEvent.event_type).toEqual(GithubForkEvent.EVENT_TYPE);\r\n    expect(forkEvent.actor).toEqual(raw.actor.login);\r\n    expect(forkEvent.repo).toEqual(raw.repo.name);\r\n    expect(forkEvent.created_at).toEqual(raw.created_at);\r\n\r\n    let payload = forkEvent.payload;\r\n\r\n   // the below tests fail if we remove `@deserialize` field in `GithubForkEvenyPayload`\r\n    expect(payload.forkee_id).toEqual(raw.payload.forkee.id);\r\n    expect(payload.forkee_name).toEqual(raw.payload.forkee.name);\r\n    expect(payload.forkee_full_name).toEqual(raw.payload.forkee.full_name);\r\n    expect(payload.forkee_url).toEqual(raw.payload.forkee.html_url);\r\n    expect(payload.forkee_language).toEqual(raw.payload.forkee.language);\r\n  });\r\n});\r\n```\r\n\r\nIn this case, if we remove `@deserializeAs(\"action\") public action: string;` field, `OnDeserialized` hook in `GithubForkEventPayload` class will be not called because [metadataArray](https://github.com/weichx/cerialize/blob/a45c93190ca488848474734e8242a9c37bfbecfd/src/serialize.ts#L408) is empty. \r\n\r\nSo I think `OnDeserialized` hook logic should be called before checking  [metadataArray](https://github.com/weichx/cerialize/blob/a45c93190ca488848474734e8242a9c37bfbecfd/src/serialize.ts#L408) in [deserializeObject](https://github.com/weichx/cerialize/blob/a45c93190ca488848474734e8242a9c37bfbecfd/src/serialize.ts#458) and [desrializedObjectInto](https://github.com/weichx/cerialize/blob/a45c93190ca488848474734e8242a9c37bfbecfd/src/serialize.ts#L458) functions. \r\n\r\nI already created PR for `OnDeserialized` in https://github.com/weichx/cerialize/pull/15. If you don't mind, I would like to fix this bug on another PR after #15 is merged as this is the different issue.\r\n"},"comment":{"url":"https://api.github.com/repos/weichx/cerialize/issues/comments/168715057","html_url":"https://github.com/weichx/cerialize/issues/16#issuecomment-168715057","issue_url":"https://api.github.com/repos/weichx/cerialize/issues/16","id":168715057,"user":{"login":"weichx","id":1365953,"avatar_url":"https://avatars.githubusercontent.com/u/1365953?v=3","gravatar_id":"","url":"https://api.github.com/users/weichx","html_url":"https://github.com/weichx","followers_url":"https://api.github.com/users/weichx/followers","following_url":"https://api.github.com/users/weichx/following{/other_user}","gists_url":"https://api.github.com/users/weichx/gists{/gist_id}","starred_url":"https://api.github.com/users/weichx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/weichx/subscriptions","organizations_url":"https://api.github.com/users/weichx/orgs","repos_url":"https://api.github.com/users/weichx/repos","events_url":"https://api.github.com/users/weichx/events{/privacy}","received_events_url":"https://api.github.com/users/weichx/received_events","type":"User","site_admin":false},"created_at":"2016-01-04T15:58:12Z","updated_at":"2016-01-04T15:58:12Z","body":"Interesting use case, I think you are right that the hook should be called but I would like to find a nice way to do so at parse-time instead of run time. Since we use `@inheritSerialization` anyway, perhaps the right time for this check is inside the `@inheritSerialization` attribute function body. I'll play with this and see what I can come up with."}}