Retrofit doesn't return data from API in Kotlin

52 Views Asked by At

I am using Retrofit in Android Studio (Kotlin) to get data from the Open Food Facts API for a school project. The program connects with the API and returns the code and the status successfully but every other variable is returned as 0 or null (depending on the datatype). I haven't found any solution on the internet and I don't know where the problem is, because the connection to the API seems to work without any problems, but the variable data isn't returned.

Link to the data set I am testing with: https://world.openfoodfacts.org/api/v2/product/737628064502.json

This is the class where the @GET-function is called:

package com.example.commandercalorie.ui.dashboard

import ApiClient
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.commandercalorie.Food
import com.example.commandercalorie.MyAdapter
import com.example.commandercalorie.Post
import com.example.commandercalorie.databinding.FragmentDashboardBinding
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class DashboardFragment : Fragment() {

// some other code

        searchButton.setOnClickListener {
            val codeId = 737628064502 // the variable for the barcode/id of the product

            val call = ApiClient.apiService.getPostById(codeId)

            call.enqueue(object : Callback<Post> {
                override fun onResponse(call: Call<Post>, response: Response<Post>) {
                    if (response.isSuccessful) {
                        val post = response.body()
                        val productName = post?.product_name

// some other code

                    } else {
                        // some other code
                    }
                }

                override fun onFailure(call: Call<Post>, t: Throwable) {
                    // Handle failure}

// some other code

This is the Retrofit-Client and API-Client:

import com.example.commandercalorie.ApiService
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitClient {
    private const val BASE_URL = "https://world.openfoodfacts.org/api/v2/"

    val retrofit: Retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
}

object ApiClient {
    val apiService: ApiService by lazy {
        RetrofitClient.retrofit.create(ApiService::class.java)
    }
}

this is the API-Service interface:

package com.example.commandercalorie

import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path

interface ApiService {
    @GET("product/{code}")
    fun getPostById(@Path("code") codeId: Long): Call<Post>
}

And this is the data class with the required variabels:

package com.example.commandercalorie


data class Post (
    val code: String,
    val origins: String,
    val energy_100g: Int,
    val product_name: String,
    val status: Int
)

The output of the API in Logcat:

output API

The output of the variables origins, energy_100g and product_name shouldn't be 0 and null, because these variables have an assigned value in the dataset. Android Studio displays no error message and status + code are returned correctly.

I would be very grateful for any help regarding this problem.

1

There are 1 best solutions below

0
Rafael Moreira On

Maybe this will help, I'm not the most experienced in Android Dev. It's a nested JSON, maybe you are going to need to access the nested fields.

Update your models' data class for something like this.

data class Post (
    val code: String,
    val product: Product,      
    val status: Int
)

data class Product (
    val origins: String,
    @SerializedName("product_name")
    val productName: String,
    val nutriments: Nutriments,
)

data class Nutriments (
    @SerializedName("energy_100g")
    val energy100g: Int,
)

Good luck mate.