Hey all, I have an issue where I have a Parcelable...
# android
m
Hey all, I have an issue where I have a Parcelable object that I want to pass to an activity. Let’s say this object is a
Conversation
and it also contains a list of
ConversationMembers
. The thing is, my ConversationMember model has a
conversationId
property, that is declared as not null -> In the backend, it doesn’t make sense for a
ConversationMember
to have a null
conversationId
. But the thing is, the API doesn’t always send me every fields serialized (it avoids serializing useless fields depending on the situation). So I have this place where I get the
Conversation
(containing a list of
conversationMembers
) from the backend, but the field
conversationId
is not present at this place for the
conversationMembers
. So when I try to pass this object to the activity and start it, it throws a
java.lang.RuntimeException: Unable to start activity java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter conversationId
How do you deal with that use case? I don’t want to mark this field as nullable, cause at the base it doesn’t make sense, but in the context of api responses with fields restricted to the minimum, the property that I mark as not null could end up being null (not present) in some context.
m
if the field is not present in ALL API responses, it is nullable
I’m going out on a limb and suggest that your server is being too smart for its own good 😛 if the
id
is so relevant, why would it be omitted?
m
I was pretty sure I would get that response 🙂. The thing is, in the example I gave, I agree I could just add the field to the api response, but in a general thinking, this will probably happen again with other fields that the API won’t send in a certain context, and that will be less evident than a foreign key (conversationId in this case). So, I was expecting there was maybe another solution. I’ll think about it, maybe I should mark the field as nullable, even if it won’t be in harmony with the backend/db.
m
It really all depends on the layer that handles the communication with your server
the safest is definitely marking it as nullable
but then, how do you know what to mark as nullable and what not? Couldn’t it be the case (eventually) that “everything” will be marked nullable because “everything” at some point might be omitted?
m
The thing is, I thought about it, and in the example I gave, it doesn’t look that bad, but let’s say I have a
Message
model, with like 4 foreign keys, and that in a context, the api just return me a
Message
with just the field “id” and “content” cause that’s just what is needed at that place, then the same problem happens again.
m
exactly
m
Yeah, exactly what you said. I will end up that everything will be nullable.
I’m wondering, I must not be alone in that situation. It must be standard for APis to not always return all fields
We do this for performance, sometimes the models are big and it doesn’t make sense that the apis return, eg a Member with its 15 fields, when only 2-3 fields are useful for that context.
m
I completely see the point… one non-scalable solution is local models based on each response
but then it becomes messy really fast since you end up with several models that are just a bigger set of another model 😖
m
Haha, that’s exactly what I was discussing about with a coworker. 😕
m
I have had this issue as well with APIs that implement “patch” semantics by only sending fields that have changed or are invalidated. This kind of thing seems more common in the javascript community (where people don’t care about types at all, much less nullable ones). Typescript was able to resolve the issue somewhat by introducing
Partial<T>
in particular and mapped types in general (https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html).
I think the notion of type operators or mapped types are really neat, but they really rely on “types as a bag of fields” and structural typing, which means we’ll probably never see them in kotlin 🙁
r
You can create a custom delegate that sets the id with a placeholder if its not specified