0

I have converted the following Swift code:

struct FooModel: Decodable {
    public let id: String
public let bars: [[BarModel]]
}

to this Kotlin code:

data class FooModel (val id: String, val bars: List<List<BarModel>>)

The issue I am encountering, is my id is coming in null for the Kotlin code (via gson). Everything else in the Kotlin conversion is working fine and the entire JSON is populating all data classes, except for this tiny piece (the id variable).

I suspect my conversion here is the cause, any ideas?

Keith Kowalski
  • 115
  • 2
  • 11
  • @keith, the variable **id** is in int in server response ? – Nirav Bhavsar Aug 26 '18 at 06:28
  • DEBUG at first. – IntelliJ Amiya Aug 26 '18 at 06:29
  • Your server response please? – Shaon Aug 26 '18 at 06:35
  • For your swift version, had your id variable value? – Shaon Aug 26 '18 at 06:37
  • I have used the debug tool heavily in both Xcode and Android Studio. That is how I narrowed down the issue to my id constant not being set (Android Studio shows it as NULL currently). In Xcode, the ID constant is set without issue, based on the fooModel structure. There are no errors I am aware of. – Keith Kowalski Aug 26 '18 at 07:16
  • can you show your json tree ? – r3dm4n Aug 26 '18 at 07:57
  • @KeithKowalski what i got from your comment is the 'id' property you are trying to set is not in actual JSON you are parsing. Am I right? – Rahul Aug 26 '18 at 08:06
  • Are you trying to pass this 'id' object from one class to another ? Please be more clear .. – r3dm4n Aug 26 '18 at 08:13
  • The 'id' constant is merely just a data class I am trying to populate from JSON values. I have about half a dozen classes similar to this, which are all populating just fine from GSON (I can see all values being set properly from the debugger). It's just this one particular value that seems to not accept the string provided by the JSON. The good news, is that it DOES recognize the variable is an 'id'... it just doesn't recognize the input for it. Very odd. – Keith Kowalski Aug 27 '18 at 14:46
  • Could you please try to add those annotations with the id variable ```@SerializedName("id_ FooModel") @Expose``` and with the ```SerializedName``` try to put the exact same name that you have in the JSON data for the id – Lilia Jan 25 '21 at 12:53

3 Answers3

0

If the id should be nullable do it like this:

data class FooModel (
    val id: String?, 
    val bars: List<List<BarModel>>
)

The question mark makes this property nullable.

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
  • I appreciate it, but this just allows it to accept a 'null' input (or handle it however I tell it to when I check for the value). The issue is that an actual input value that does exist, refuses to populate the id variable. The strange thing, is that all other data classes involved (about 4-5) ARE populating just fine. It's only this particular embedded one that is not. That said, it's probably is not a bad idea to go ahead and make this value nullable regardless. It's safer. :) – Keith Kowalski Aug 27 '18 at 14:42
0

If the JSON you are getting is correct (the id value is there and coming to you as a string), your code should work. It's unclear what could be going wrong here if that's the case.

However, it is worth knowing that there is a big potential "gotcha" with Gson that you should be aware of: it's possible to declare a variable of a data class as non-nullable but still get a null after conversion. This can happen when an expected value is missing from the JSON response. In these cases Gson does not throw an error and I only found out later when I got a crash trying to access the non-nullable variable that should never have made it to me as null. I discovered this is a consequence of Gson using something like Class.newInstance() instead of a regular constructor when it creates these data classes, and then uses reflection to populate the data. More is written about this in another answer here: Why Kotlin data classes can have nulls in non-nullable fields with Gson?

Depending on your use case you might consider this to be a design flaw and a reason to avoid Gson in favor of other JSON serialization libraries. My personal favorite at the moment is Square's Moshi.

Mel Stanley
  • 375
  • 2
  • 8
0

You can check if the value type you are getting from server matches with your variable id i.e. String on both the sides. Secondly you can try using SerializedName("id") included in library:

implementation 'com.google.code.gson:gson:2.9.0'
Vraj Shah
  • 31
  • 5