How to implelement this on retrofit?

Issue

Hello I am an android developer and i have never before faced this problem before "Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $" i am suspecting the issue is in my model.

this is the postman response as is

{
  "Status": 200,
  "Message": "OK",
  "Data": {
    "ServiceTypes": [
      {
        "Id": 1,
        "ServiceTypeNameAr": "صيانة",
        "ServiceTypeNameEn": "Maintenance",
        "MainServices": [
          {
            "Id": 11,
            "ServiceTypeId": 1,
            "MainServiceNameAr": "تكييفات\r\n",
            "MainServiceNameEn": "Air conditioning\r\n",
            "SubServices": null
          },
          {
            "Id": 12,
            "ServiceTypeId": 1,
            "MainServiceNameAr": "كهرباء\r\n",
            "MainServiceNameEn": "Electricity\r\n",
            "SubServices": null
          },
          {
            "Id": 14,
            "ServiceTypeId": 1,
            "MainServiceNameAr": "سباكة",
            "MainServiceNameEn": "Plumbing\r\n",
            "SubServices": null
          },
          {
            "Id": 15,
            "ServiceTypeId": 1,
            "MainServiceNameAr": "اجهزة منزلية\r\n",
            "MainServiceNameEn": "Home appliances\r\n",
            "SubServices": null
          }
          
        ]
     }
      
    ]
    
  }
  
}

i want to implement this as a pojo(model) in my code this is my try (Edited)
ResponseModel

public class ResponseModel {
    @SerializedName("Status")
    public int Status;
    @SerializedName("Message")
    public String Message;
    @SerializedName("Data")

    public DataModel Data;

    public int getStatus() {
        return Status;
    }

    public void setStatus(int status) {
        Status = status;
    }

    public String getMessage() {
        return Message;
    }

    public void setMessage(String message) {
        Message = message;
    }

    public DataModel getData() {
        return Data;
    }

    public void setData(DataModel data) {
        this.Data = data;
    }

}

DataModel

public class DataModel {
    @SerializedName("Country")
    private List<CountryModel> countryModels;
    @SerializedName("Users")
    private List<UserModel> users;
    @SerializedName("Cities")
    private List<CityItem> cityItems;
    @SerializedName("ServiceTypes")
    private List<ServiceTypeModel> serviceTypeModels;
    private Map<String, Object> additionalProperties = new HashMap<String,
                Object>();

    public List<CityItem> getCityItems() {
        return cityItems;
    }

    public void setCityItems(List<CityItem> cityItems) {
        this.cityItems = cityItems;
    }

    public List<UserModel> getUsers() {
        return users;
    }

    public void setUsers(ArrayList<UserModel> users) {
        this.users = users;
    }

    public List<CountryModel> getCountryModels() {
        return countryModels;
    }

    public void setCountryModels(ArrayList<CountryModel> countryModels) {
        this.countryModels = countryModels;
    }
    public List<ServiceTypeModel> getServiceTypeModels() {
        return serviceTypeModels;
    }

    public void setServiceTypeModels(List<ServiceTypeModel> serviceTypeModels) {
        this.serviceTypeModels = serviceTypeModels;
    }

    public void setCountryModels(List<CountryModel> countryModels) {
        this.countryModels = countryModels;
    }

    public void setUsers(List<UserModel> users) {
        this.users = users;
    }

    public Map<String, Object> getAdditionalProperties() {
        return additionalProperties;
    }

    public void setAdditionalProperties(Map<String, Object> additionalProperties) {
        this.additionalProperties = additionalProperties;
    }
}

ServiceTypeModel

public class ServiceTypeModel {
    @SerializedName("Id")
    private int id;
    @SerializedName("ServiceTypeNameAr")
    private String serviceTypeNameAr;
    @SerializedName("ServiceTypeNameEn")
    private String serviceTypeNameEn;
    @SerializedName("MainServices")
    private List<MainServicesModel> mainServicesList;

    public List<MainServicesModel> getMainServicesList() {
        return mainServicesList;
    }

    public void setMainServicesList(List<MainServicesModel> mainServicesList) {
        this.mainServicesList = mainServicesList;
    }

    public int getId() {
        return id;
    }

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

    public String getServiceTypeNameAr() {
        return serviceTypeNameAr;
    }

    public void setServiceTypeNameAr(String serviceTypeNameAr) {
        this.serviceTypeNameAr = serviceTypeNameAr;
    }

    public String getServiceTypeNameEn() {
        return serviceTypeNameEn;
    }

    public void setServiceTypeNameEn(String serviceTypeNameEn) {
        this.serviceTypeNameEn = serviceTypeNameEn;
    }
}

The Interface:

public interface ServiceTypeInterface {

    @GET("ServiceType")
    public Call<ResponseModel> GetServicesType(@Header("authorization") String token);

    @GET("ServiceType/{id}")
    public Call<ResponseModel> GetServiceTypeById(@Path("id") int Id, @Header("authorization") String token);
}

Adapter

public class ServiceTypeAdapter extends RecyclerView.Adapter<ServiceTypeAdapter.ServiceTypeHolder> {
    private List<ResponseModel> serviceTypeModels = new ArrayList<>();
    private final ServiceTypeListener listener;
    private Context context;

    public ServiceTypeAdapter(ServiceTypeListener listener, Context context, List<ResponseModel> serviceTypeList) {
        this.listener = listener;
        this.context = context;
        this.serviceTypeModels = serviceTypeList;
    }

    @NonNull
    @Override
    public ServiceTypeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_sub_service, parent, false);
        return new ServiceTypeHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull ServiceTypeHolder holder, int position) {
        final ResponseModel ServiceType = serviceTypeModels.get(position);
        holder.TxtServiceTypeName.setText(ServiceType.getData().getServiceTypeModels().get(0).getServiceTypeNameEn());
    }

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

    public long getItemId(int position) {
        return position;
    }

    public void  setList(List<ResponseModel> serviceTypeModels) {
//        serviceTypeModels = new List<ResponseModel>(serviceTypeModels.get(0).getData().getServiceTypeModels().get(0).getServiceTypeNameEn());
        this.serviceTypeModels = serviceTypeModels;
        notifyDataSetChanged();
    }

    public class ServiceTypeHolder extends RecyclerView.ViewHolder {
        TextView TxtServiceTypeName;
        public ServiceTypeHolder(@NonNull View itemView) {
            super(itemView);
            TxtServiceTypeName = itemView.findViewById(R.id.ServiceTypeName);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    listener.onServiceTypeSelected(serviceTypeModels.get(getAdapterPosition()));
                }
            });
        }
    }

    public interface ServiceTypeListener {
        void onServiceTypeSelected(ResponseModel serviceTypeModel);
    }
}

i tried to separate them as well into two models the status, message and data which calls for the services type which is in another model.
if anything else or more clarification is needed pls don’t hesitate to ask me for code or anything.
any help is really appreciated.
Thanks in advance.

Solution

I knew where i was wrong i was missing a small part in my main for calling the list itself here is the main for anyone who needs it or anyone facing the same issue

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_categories);
//
        TestTxt = findViewById(R.id.TestTxt);
        serviceTypeViewModel = ViewModelProviders.of(this).get(ServiceTypeViewModel.class);
        serviceTypeViewModel.GetServiceType();
        serviceTypeRecycler = findViewById(R.id.ServiceTypeRV);
//        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
//        serviceTypeRecycler.setLayoutManager(layoutManager);
//        serviceTypeRecycler.setItemAnimator(new DefaultItemAnimator());
//        serviceTypeRecycler.setAdapter(serviceTypeAdapter);
        FillListServices();

    }

    private void FillListServices() {
        serviceTypeViewModel.ServiceTypeMutableLiveData.observe(this, new Observer<ResponseModel>() {
//          Here i was trying to call the ServiceTypeModel instead
            @Override
            public void onChanged(ResponseModel responseModel) {
                Utilities.dismissLoadingDialog();

                serviceTypeModelArrayList = new ArrayList<>();
                serviceTypeModelArrayList = responseModel.getData().getServiceTypeModels();
                TestTxt.setText(responseModel.getData().getServiceTypeModels().get(0).getServiceTypeNameAr());
                serviceTypeAdapter = new ServiceTypeAdapter(responseModel.getData().getServiceTypeModels());
                LinearLayoutManager layoutManager = new LinearLayoutManager(MainCategories.this, LinearLayoutManager.HORIZONTAL, false);

                serviceTypeRecycler.setLayoutManager(layoutManager);
                serviceTypeRecycler.setAdapter(serviceTypeAdapter);

            }
        });
    }

Answered By – Mohammad khaled

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published