0

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 $

Shweta Chauhan
  • 6,739
  • 6
  • 37
  • 57
XVallerie
  • 141
  • 2
  • 11
  • 1
    check this answer -> https://stackoverflow.com/a/38351872/6021469 – Shweta Chauhan Apr 16 '20 at 08:09
  • 1
    @ShwetaChauhan can you please check my https://stackoverflow.com/questions/61341571/how-to-post-update-and-delete-data-to-from-api-in-retrofit-with-nested-values I have a problem here :( – XVallerie Apr 23 '20 at 07:12
  • @ShwetaChauhan , I want to ask about this .-. I've been struggling on this for like 3 days https://stackoverflow.com/questions/61386053/error-400-bad-request-json-parse-error-unrecognized-token-agama-was-expec – XVallerie Apr 24 '20 at 08:27
  • ok let me check. Also, I am stuck in another issuue. – Shweta Chauhan Apr 24 '20 at 08:56
  • can you please check that in postman or insomania or what ever you using? You can check in postman that API is working with your param or not then we can check in retrofit issue – Shweta Chauhan Apr 24 '20 at 08:58
  • imgur.com/TVDkcli here's what my postman output stated – XVallerie Apr 24 '20 at 09:10
  • means it's working there right? – Shweta Chauhan Apr 24 '20 at 10:20
  • yes, it's working in postman. I also changed the datatype into JSON object especially for Magana,hubungan, and jeniskelamin, but still error – XVallerie Apr 24 '20 at 10:25

2 Answers2

1

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());
    }
});
Shweta Chauhan
  • 6,739
  • 6
  • 37
  • 57
  • I've tried this one as well, no warning but the screen is totally blank – XVallerie Apr 16 '20 at 08:51
  • yea, in onresponse you need to set that data in recylerview -> check this answer it help you more https://stackoverflow.com/a/38351872/6021469 – Shweta Chauhan Apr 16 '20 at 08:52
  • 1
    Thank you @shweta ... it works and I just need to figure out how to retrieve the details! Thank You! – XVallerie Apr 16 '20 at 09:18
  • By the way, do you know how to set value from nested POJO Class, cause I want to post data to server, I'm using this `f.setAgama(valueAgama); f.setHubungans(valueHubungan); f.setJeniskelamin(valueJenisKelamin); addFamily(f);` with my kind of JSON above, I got errors on f.setAgama(spinnerAgama) when setAgama has an Agama as its data type – XVallerie Apr 21 '20 at 09:59
0

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);
advice
  • 5,778
  • 10
  • 33
  • 60
  • I've tried this one already, and there is no warning anymore but the data didn't show up, like totally blank – XVallerie Apr 16 '20 at 08:50
  • By the way, do you know how to set value from nested POJO Class, cause I want to post data to server, I'm using this f.setAgama(valueAgama); f.setHubungans(valueHubungan); f.setJeniskelamin(valueJenisKelamin); addFamily(f); with my kind of JSON above, I got errors on f.setAgama(spinnerAgama) when setAgama has an Agama as its data type – XVallerie Apr 21 '20 at 10:15