node.js - Response body is null even though server is sending a non null response - Stack Overflow
I am trying to make an android app using jetpack compose + kotlin for client side and nodejs + express.js for server side to make my RESTApi.
For one of my endpoint:
@POST /getUserIdAndName
My server expects a request body as:
{
"id": Int
}
And gives response in the format:
{
"code": Int,
"body": [
{
"id": Int,
"name": String,
"photo": String
},
{
"id": Int,
"name": String,
"photo": String
},
... so on
]
}
For my client side I modeled the response in this way:
My main response class :
data class DetailsResponseDto<T:ResponseBody>( val code: Int, val body: T?, val message: String )
My Response Body for this endpoint:
import com.example.hola.core.domain.utils.ResponseBody import com.squareup.moshi.Json import com.squareup.moshi.JsonClass data class UserIdAndNameResponse( val id : Int?, val name : String?, val photo: String? ) @JsonClass(generateAdapter = true) data class UsersList( @Json(name = "body") val body : List<UserIdAndNameResponse> ) : ResponseBody
Endpoint:
@POST("/getUserIdAndName") suspend fun getUserIdAndName(@Body myUserId: Map<String, Int>) : DetailsResponseDto<UsersList>
"ResponseBody" is just a marker interface, that I used in my app's architechture so that all different types of response body can have same identity.
interface ResponseBody
When I used it to fetch the data from api it is giving as my response body is null. But at the same time When I checked my server logs, it is giving the correct output. I asked ChatGPT too about this problem but I can't get any solution that should also respect my app's architectural constraints.
Constraints are as follows:
I can't remove "ResponseBody" marker interface to simplify my response data class (ChatGPT suggested this already), because as I said it will break my architecture.
I can't change my server side request/response format, because in other cases where this same endpoint is used I need data in this format only.
How can I solve this problem?
My client side implementation of the endpoint is as follows:
interface GetOtherUsersDetailAbstract {
suspend fun <D>getUserIdAndNames(myUserId: Int) : Result<D, Error>
}
class EstablishNewConversations : GetOtherUsersDetailAbstract {
private val TAG = "EstablishNewConversations"
//Use retrofit to send the request
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
val api : HolaAppRestApi = Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
.create()
override suspend fun <D> getUserIdAndNames(myUserId: Int): com.example.hola.core.domain.utils.Result<D, Error> {
Log.d(TAG,"Get user id and names called")
val requestBody = mapOf("id" to myUserId)
return try{
val response = api.getUserIdAndName(requestBody)
Log.d(TAG, "Raw API Response: ${response}")
if (response.body != null){
detailResponseToResult(api.getUserIdAndName(requestBody))
.mapAResult { usersList: UsersList? ->
if (usersList == null) {
Log.d(TAG,"Users list is null")
UsersList(emptyList()) as D
}
Log.d(TAG,"Users list is not null: $usersList")
usersList as D
}
} else{
Log.d(TAG,"Response body is null")
Result.Error(ConversationError.NO_CONVERSATION_FOUND)
}
}catch (e:Exception){
Log.e(TAG,"Error fetching user ID and names: ${e.message}",e)
Result.Error(ConversationError.UNEXPECTED_ERROR)
}
}
}
Logs are like this:
2025-01-04 04:52:19.179 17837-17862 EstablishN...versations com.example.hola D Get user id and names called
2025-01-04 04:52:19.998 17837-17862 EstablishN...versations com.example.hola D Raw API Response: DetailsResponseDto(code=1, body=null, message=Success)
2025-01-04 04:52:19.998 17837-17862 EstablishN...versations com.example.hola D Response body is null
My server side implementation is:
exports.getUserIdAndName = async (req, res, next) => {
const body = req.body;
console.log("Got id as : ", body.id);
console.log("Type is : ", typeof body.id);
//Constructing base url
const baseUrl = `${req.protocol}://${req.get("host")}`;
if (!body.id) {
return res.status(400).json({
code: 0,
body: null,
error: "Invalid request. 'id' is required.",
});
}
console.log("id is correct");
try {
const userIdAndNameList = await UserDetails.getUserIdAndNameList(
body.id,
baseUrl
);
if (userIdAndNameList.code !== 1) {
console.log(`returning userList as ${JSON.stringify(userIdAndNameList)}`);
return res.status(500).json({
code: userIdAndNameList.code,
body: null,
message: userIdAndNameList.message,
});
}
console.log(`returning userList as ${JSON.stringify(userIdAndNameList)}`);
return res.status(200).json({
code: 1,
body: userIdAndNameList.data,
message: userIdAndNameList.message,
});
} catch (err) {
return res.status(500).json({
code: mapError("remoteDatabaseErr", "crudOperationErr", "unknownError"),
body: null,
message: "Some Unknown Internal error happened",
});
}
};
- 芯片缺货严重,真凶或是ABF产能不足
- 微软要逆天!SurfacePhone能运行exe程序
- 思科宣布27亿美元收购安全软件厂商Sourcefire
- 软件定义存储VS硬件定义存储
- 网络视频两大阵营形成 将引导行业良性发展
- python - DeltaTable map type - Stack Overflow
- open source - Langgraph State not being passed properly with Ollama - Stack Overflow
- reactjs - Why can't AWS Amplify find my components from a working version of my React App? - Stack Overflow
- apache spark - Can't save pyspark ML model :py4j.protocol.Py4JJavaError: An error occurred while calling o577.save. : ja
- java - I am using spring boot to create an application, my application is running when I hit the end point but it is showing me
- math - How do I rotate sprites by using polar coordinates in Godot 4.3? - Stack Overflow
- c# - Is there a way to fill scriptable object field with a child class? - Stack Overflow
- android - Unity Ads fail to initialize - Stack Overflow
- react native - Views are still shifted when the keyboard opens, even though they are not wrapped in a KeyboardAvoidingView - Sta
- eclipse - Floodlight debug Exception in thread "main" java.lang.Error - Stack Overflow
- javascript - useState rerenders bindings increment when key added to object but not removed - Stack Overflow
- next.js - Update Server Component via a Client Component - Stack Overflow