# When decoding a Codable struct from JSON, how do you initialize a property not present in the JSON?

**URL:** <https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594>\
**Category:** Using Swift\
**Created:** [May 26, 2022, 5:03am UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594 "2022-05-26T05:03:04Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Austin\_Conlon](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Austin\_Conlon](https://forums.swift.org/u/Austin_Conlon)\
**Post date:** [May 26, 2022, 5:03am UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594/1 "2022-05-26T05:03:04Z")

</div>

Say that in [this example here](https://developer.apple.com/tutorials/app-dev-training/making-reminders-identifiable), this struct

```
struct Reminder: Identifiable {
    var id: String = UUID().uuidString
    var title: String
    var dueDate: Date
    var notes: String? = nil
    var isComplete: Bool = false
}

```

is instead decoded from JSON array values (rather than constructed like in the linked example). If each JSON value were to be missing an "id", how would `id` then be initialized? When trying this myself I got an error `keyNotFound(CodingKeys(stringValue: "id", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"id\", intValue: nil) (\"id\").", underlyingError: nil))`.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [May 26, 2022, 5:09am UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594/2 "2022-05-26T05:09:33Z")

</div>

> [@Austin\_Conlon](#):
>
> If each JSON value were to be missing an "id"

But why?!

---

<div class="post-metadata">

**Author:** ![wowbagger](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wowbagger/32/13847_2.png) [@wowbagger](https://forums.swift.org/u/wowbagger)\
**Post date:** [May 26, 2022, 5:13am UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594/3 "2022-05-26T05:13:05Z")

</div>

I think these 2 tutorials/documentation can help you with this problem (and other related problems too):

[https://developer.apple.com/documentation/foundation/archives\_and\_serialization/using\_json\_with\_custom\_types](https://developer.apple.com/documentation/foundation/archives_and_serialization/using_json_with_custom_types)

[https://developer.apple.com/documentation/foundation/archives\_and\_serialization/encoding\_and\_decoding\_custom\_types](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types)

---

<div class="post-metadata">

**Author:** ![Austin\_Conlon](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Austin\_Conlon](https://forums.swift.org/u/Austin_Conlon)\
**Post date:** [May 26, 2022, 5:14am UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594/4 "2022-05-26T05:14:26Z")

</div>

The sample code is broken for me (FB10028043), but I'll take a look at the article.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [May 26, 2022, 10:08am UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594/5 "2022-05-26T10:08:00Z")

</div>

I still don't get why you want complicate things by not providing ids in json (e.g. "1", "2", "3", could do). If that's still a problem here's a possible simple solution:

```swift
struct Reminder: Identifiable, Codable {
    var id: String { _id! }
    private var _id: String?
    var title: String
    var dueDate: Date
    var notes: String? = nil
    var isComplete: Bool = false
    
    mutating func prepare() {
        _id = _id ?? UUID().uuidString
    }
}

func test(_ data: Data) {
    var reminders = try! JSONDecoder().decode([Reminder].self, from: data)
    for i in 0 ..< reminders.count {
        reminders[i].prepare()
    }
    print(reminders)
    model.state.reminders = reminders // safe to use as all ID's are in there
}

```

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [May 26, 2022, 1:13pm UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594/6 "2022-05-26T13:13:04Z")

</div>

If you do actually want to follow that example exactly and default to having `id` be generated as `UUID().uuidString` every time (which, keep in mind, will give you a new UUID every single time you decode a `Reminder` struct — even the same one repeatedly) then this can be achieved as easily as leaving out `id` from `Reminder`'s `CodingKey`s:

```swift
struct Reminder: Identifiable, Decodable {
    var id: String = UUID().uuidString
    var title: String
    var dueDate: Date
    var notes: String? = nil
    var isComplete: Bool = false
    
    private enum CodingKeys: String, CodingKey {
        case title, dueDate, notes, isComplete
    }
}

```

This will avoid attempting to decode `id` from a `Decoder` at all, which will always give it the assigned default value.

If you'd prefer `id` to be assigned `UUID().uuidString` only if `id` is not found in the JSON, you can achieve this by overriding `init(from:)`:

```swift
struct Reminder: Identifiable, Codable {
    var id: String = UUID().uuidString
    var title: String
    var dueDate: Date
    var notes: String? = nil
    var isComplete: Bool = false
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
        title = try container.decode(String.self, forKey: .title)
        dueDate = try container.decode(Date.self, forKey: .dueDate)
        notes = try container.decodeIfPresent(String.self, forKey: .notes)
        isComplete = try container.decode(Bool.self, forKey: .isComplete)
    }
}

```

Two things to note:

1. In this second example, I made `Reminder` `Codable` instead of just `Decodable` so the compiler would synthesize `CodingKey`s for us (since it's synthesizing `encode(to:)`). If you want it to just be `Decodable` and you implement `init(from:)` manually, you'll need to also define `CodingKeys` manually
2. Both in the original example, and here, `isComplete` will also throw an error if not found in the JSON, since it's not optional — even though it has a default value. If you want to fall back to `false` if not present, you'll similarly need to change `isComplete = ...` to use `decodeIfPresent` and fall back to `false`

---

<div class="post-metadata">

**Author:** ![krilnon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/krilnon/32/276_2.png) [@krilnon](https://forums.swift.org/u/krilnon)\
**Post date:** [May 26, 2022, 5:47pm UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594/7 "2022-05-26T17:47:50Z")

</div>

Huh, I wonder how it got wrapped in an extra `.playground` package. Thanks for reporting it. In the mean time... you can get at the original with 'Show Package Contents' and opening the nested playground.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [May 27, 2022, 1:41am UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594/9 "2022-05-27T01:41:10Z")

</div>

Right direction but as written it won't work: decoder won't call the init: for starters it doesn't know which init (of possibly few) to call. You want this:

```swift
struct Reminder: Identifiable, Codable {
    let id: UUID = UUID() // Warning, see below
    var title: String
    var dueDate: Date
    var notes: String? = nil
    var isComplete: Bool = false
}

```

which has an added benefit of not having the boilerplate, yet at the same time with a drawback of this new warning: _"Immutable property will not be decoded because it is declared with an initial value which cannot be overwritten."_ with a fix-it: _"Fix: Make the property mutable instead"_, which fix-it if you use ... would actually break the thing... no idea how to silence it.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [May 27, 2022, 12:45pm UTC](https://forums.swift.org/t/when-decoding-a-codable-struct-from-json-how-do-you-initialize-a-property-not-present-in-the-json/57594/10 "2022-05-27T12:45:18Z")

</div>

> [@tera](#):
>
> decoder won't call the init: for starters it doesn't know which init (of possibly few) to call.

_On the second thought there's no ambiguity in the call of the form `T()`, whether the corresponding init is `init()` or `init(a: Int = 0)`, etc, so in theory decoder could have called it.... (it doesn't)._
