Q: How to Retrieve Data from API in retrofit with Nested Values Android? I want to show User's family data with listview in Android.
Here's my GSON :
    {
        "id": 0022,
        "date_otor": null,
        "agama": {
            "agama": "CHRISTIAN"
            "id_Agama": "1"
        },
        "hubungans": {
            "id": "10",
            "hubungan": "FATHER"
        },
        "jeniskelamin": {
            "jenisKelamin": "1",
            "kelamin": "Pria"
        },
        "golDarah": "",
        "statusNikah": "0",
        "nama": "JACKSON WANG",
        "tgl_Lahir": "1960-12-18 00:00:00",
        "noPegawai": "111111",
        "tempatLahir": "SINGAPORE"
    },
    {
        "id": 0023,
        "date_otor": null,
        "agama": {
            "agama": "CHRISTIAN"
            "id_Agama": "1"
        },
        "hubungans": {
            "id": "21",
            "hubungan": "MOTHER"
        },
        "jeniskelamin": {
            "jenisKelamin": "2",
            "kelamin": "Wanita"
        },
        "golDarah": "",
        "statusNikah": "0",
        "nama": "TITAN LOUI",
        "tgl_Lahir": "1991-05-19 00:00:00",
        "noPegawai": "111111",
        "tempatLahir": "JAKARTA"
    },
    {
        "id": 0025,
        "date_otor": null,
        "agama": {
            "agama": "CHRISTIAN"
            "id_Agama": "1"
        },
        "hubungans": {
            "id": "22",
            "hubungan": 2nd child"
        },
        "jeniskelamin": {
            "jenisKelamin": "2",
            "kelamin": "Wanita"
        },
        "golDarah": "",
        "statusNikah": "0",
        "nama": "CHRISTY",
        "tgl_Lahir": "1994-05-16 00:00:00",
        "noPegawai": "111111",
        "tempatLahir": "SINGAPORE"
    },
    {
        "id": 0024,
        "date_otor": null,
        "agama": {
            "agama": "CHRISTIAN"
            "id_Agama": "1"
        },
        "hubungans": {
            "id": "3",
            "hubungan": 1ST CHILD"
        },
        "jeniskelamin": {
            "jenisKelamin": "1",
            "kelamin": "Pria"
        },
        "golDarah": "",
        "statusNikah": null,
        "nama": "MICHAEL",
        "tgl_Lahir": "2007-10-16 00:00:00",
        "noPegawai": "111111",
        "tempatLahir": SINGAPORE
    }
]

Here's my FamilyAdapters.java:

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;

import com.example.cobaakses.R;

import java.util.List;

import androidx.recyclerview.widget.RecyclerView;

public class FamilyAdapters extends RecyclerView.Adapter<FamilyAdapters.FamilyViewHolder>{
    private List<familylistresponse> families;
    private int rowLayout;
    private Context context;

    public static class FamilyViewHolder extends RecyclerView.ViewHolder{
        LinearLayout familyLayout;
        TextView fname;
        TextView fstatus;
        TextView fgender;
        TextView freligion;

        public FamilyViewHolder(View view){
            super(view);
            familyLayout = view.findViewById(R.id.family_layout);
            fname = view.findViewById(R.id.tv_fname);
            fstatus = view.findViewById(R.id.tv_fhubungan);
            fgender = view.findViewById(R.id.tv_fjeniskelamin);
            freligion = view.findViewById(R.id.tv_fagama);
        }
    }

    public FamilyAdapters( Context context,List<familylistresponse> families, int rowLayout) {
        this.families = families;
        this.rowLayout = rowLayout;
        this.context = context;
    }

    @Override
    public FamilyAdapters.FamilyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
        View view = LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false);
        return new FamilyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(FamilyViewHolder holder, final int position){
        holder.fname.setText(families.get(position).getNama());
        holder.fgender.setText(families.get(position).getJeniskelamin());
        holder.fstatus.setText(families.get(position).getHubungans());
        holder.freligion.setText(families.get(position).getAgama());
    }

    @Override
    public int getItemCount(){
        return families.size();
    }
}

Here's my Family.java:
package com.example.cobaakses.cobaarrayretrofit;

import com.example.cobaakses.Agama;
import com.example.cobaakses.Hubungans;
import com.example.cobaakses.Jeniskelamin;
import com.google.gson.annotations.SerializedName;

public class familylistresponse {

    @SerializedName("noPegawai")
    private String noPegawai;

    @SerializedName("date_otor")
    private Object dateOtor;

    @SerializedName("jeniskelamin")
    private Jeniskelamin jeniskelamin;

    @SerializedName("keterangan")
    private String keterangan;

    @SerializedName("hubungans")
    private Hubungans hubungans;

    @SerializedName("tgl_Lahir")
    private String tglLahir;

    @SerializedName("nama")
    private String nama;

    @SerializedName("agama")
    private Agama agama;

    @SerializedName("statusNikah")
    private String statusNikah;

    @SerializedName("tempatLahir")
    private String tempatLahir;

    @SerializedName("id")
    private int id;

    @SerializedName("golDarah")
    private String golDarah;

    public void setNoPegawai(String noPegawai){
        this.noPegawai = noPegawai;
    }

    public String getNoPegawai(){
        return noPegawai;
    }

    public void setDateOtor(Object dateOtor){
        this.dateOtor = dateOtor;
    }

    public Object getDateOtor(){
        return dateOtor;
    }

    public void setJeniskelamin(Jeniskelamin jeniskelamin){
        this.jeniskelamin = jeniskelamin;
    }

    public Jeniskelamin getJeniskelamin(){
        return jeniskelamin;
    }

    public void setKeterangan(String keterangan){
        this.keterangan = keterangan;
    }

    public String getKeterangan(){
        return keterangan;
    }

    public void setHubungans(Hubungans hubungans){
        this.hubungans = hubungans;
    }

    public Hubungans getHubungans(){
        return hubungans;
    }

    public void setTglLahir(String tglLahir){
        this.tglLahir = tglLahir;
    }

    public String getTglLahir(){
        return tglLahir;
    }

    public void setNama(String nama){
        this.nama = nama;
    }

    public String getNama(){
        return nama;
    }

    public void setAgama(Agama agama){
        this.agama = agama;
    }

    public Agama getAgama(){
        return agama;
    }

    public void setStatusNikah(String statusNikah){
        this.statusNikah = statusNikah;
    }

    public String getStatusNikah(){
        return statusNikah;
    }

    public void setTempatLahir(String tempatLahir){
        this.tempatLahir = tempatLahir;
    }

    public String getTempatLahir(){
        return tempatLahir;
    }

    public void setId(int id){
        this.id = id;
    }

    public int getId(){
        return id;
    }

    public void setGolDarah(String golDarah){
        this.golDarah = golDarah;
    }

    public String getGolDarah(){
        return golDarah;
    }

    @Override
    public String toString(){
        return
                "ListUserResponse2{" +
                        "noPegawai = '" + noPegawai + '\'' +
                        ",date_otor = '" + dateOtor + '\'' +
                        ",jeniskelamin = '" + jeniskelamin + '\'' +
                        ",keterangan = '" + keterangan + '\'' +
                        ",hubungans = '" + hubungans + '\'' +
                        ",tgl_Lahir = '" + tglLahir + '\'' +
                        ",nama = '" + nama + '\'' +
                        ",agama = '" + agama + '\'' +
                        ",statusNikah = '" + statusNikah + '\'' +
                        ",tempatLahir = '" + tempatLahir + '\'' +
                        ",id = '" + id + '\'' +
                        ",golDarah = '" + golDarah + '\'' +
                        "}";
    }
}

This one is ApiClient.java:

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {
    public static final String BASE_URL = "IPAddress/employee/family/";
    private static Retrofit retrofit = null;


    public static Retrofit getClient() {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

And this one is my ListKeluarga.java Activity that will display the family's list:

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.example.cobaakses.MainInterface;
import com.example.cobaakses.R;

import java.util.List;

public class ListKeluarga extends AppCompatActivity {
    private static final String TAG = ListKeluarga.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_keluarga);
        SharedPreferences preferences = getSharedPreferences("MyPref",0);
        String tokenShared = preferences.getString("userToken",null);

        final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.families_rv);
        recyclerView.setLayoutManager(new LinearLayoutManager(ListKeluarga.this));


        MainInterface apiService =
                ApiClient.getClient().create(MainInterface.class);

        Call<familyuserresponse> call = apiService.getFamily("010713", "Bearer "+tokenShared);
        call.enqueue(new Callback<familyuserresponse>() {
            @Override
            public void onResponse(Call<familyuserresponse>call, Response<familyuserresponse> response) {
                int statusCode = response.code();
                List<familylistresponse> familiess = response.body().getResults();
                Log.d(TAG, "Number of families received: " + familiess.size());
            }

            @Override
            public void onFailure(Call<familyuserresponse>call, Throwable t) {
                // Log error here since request failed
                Log.e(TAG, t.toString());
            }
        });
    }
}

Here is my MainInterface.java:
    @GET("http://IPAddress/employee/family/111111")
    Call<familyuserresponse> getFamily(@Query("nik") String nik, @Header("Authorization") String auth);

I already try to use Strings for every variable in Family.java. but still, it shows this :

E/RecyclerView: No adapter attached; skipping layout
  (RippleDrawable) with handle 0x8c2f8150 E/ListKeluarga:
  com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
  Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $


A: 
As, your error says Expected BEGIN_OBJECT but was BEGIN_ARRAY you're telling Gson you have an object of your type. You don't. You have an array of objects of your type. 

Call<List<familyuserresponse>> call= apiService.getFamily("010713", "Bearer "+tokenShared);
call.enqueue(new Callback<List<familyuserresponse>>() {
    @Override
    public void onResponse(Call<List<familyuserresponse>> call, Response<List<familyuserresponse>> response) {
        List<familylistresponse> dataArrayList = response.body();           
    }

    @Override
    public void onFailure(Call<List<familyuserresponse>> call, Throwable t) {
        Log.e("Error",t.getMessage());
    }
});


A: The JSON you shared actually isn't valid. First, you want it to be an Array of Objects, so wrap it with [] like this.
[
  {
    "agama": {
      "agama": "CHRISTIAN",
      "id_Agama": "1"
    },
    "date_otor": null,
    "golDarah": "",
    "hubungans": {
      "hubungan": "FATHER",
      "id": "10"
    },
    "id": 22,
    "jeniskelamin": {
      "jenisKelamin": "1",
      "kelamin": "Pria"
    },
    "nama": "JACKSON WANG",
    "noPegawai": "111111",
    "statusNikah": "0",
    "tempatLahir": "SINGAPORE",
    "tgl_Lahir": "1960-12-18 00:00:00"
  },
  {
    "agama": {
      "agama": "CHRISTIAN",
      "id_Agama": "1"
    },
    "date_otor": null,
    "golDarah": "",
    "hubungans": {
      "hubungan": "MOTHER",
      "id": "21"
    },
    "id": 23,
    "jeniskelamin": {
      "jenisKelamin": "2",
      "kelamin": "Wanita"
    },
    "nama": "TITAN LOUI",
    "noPegawai": "111111",
    "statusNikah": "0",
    "tempatLahir": "JAKARTA",
    "tgl_Lahir": "1991-05-19 00:00:00"
  }
]

Now, all you need to do is change your return type to a List.
@GET("http://IPAddress/employee/family/111111")
Call<ArrayList<familyuserresponse>> getFamily(@Query("nik") String nik, @Header("Authorization") String auth);

