0

I tried to send data from android to my MySQL database using retrofit, but the data that was sent from android won't parsed into a php supported object so it doesn't inputted into the database. Turns out the api said that all of the parameters missing. So i presume the android sent the unsupported java object into my rest api. Here is my code :

Retrofit addBooking method :

private void addBooking(HashMap<String, String> booking){
        Call<HashMap<String, String>> call = userService.addBooking(booking);
        call.enqueue(new Callback<HashMap<String, String>>() {
            @Override
            public void onResponse(Call<HashMap<String, String>> call, Response<HashMap<String, String>> response) {
                Log.i("RESPONSE", response.toString());
                if(response.isSuccessful()){
                    //Toast.makeText(FormRuanganActivity.this, "Success!", Toast.LENGTH_SHORT).show();
                    Log.i("API RESPONSE", response.body().toString());
                    Snackbar.make(scrollViewForm, "Data successfully inputted", Snackbar.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<HashMap<String, String>> call, Throwable t) {
                Log.e("ERROR: ", t.getMessage());
                Toast.makeText(FormRuanganActivity.this, "ERROR: " + t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

and here is my php api code :

case 'createBooking':
                isParametersAvailable(array('title', 'start', 'end', 'nama', 'alamat', 'nohp', 'image', 'dosen',
                    'ruang', 'organisasi', 'alasan', 'mulai', 'selesai'));

                $db = new dboperation();

                $result = $db->createBooking(
                    $_POST['title'],
                    $_POST['start'],
                    $_POST['end'],
                    $_POST['nama'],
                    $_POST['alamat'],
                    $_POST['nohp'],
                    $_POST['image'],
                    $_POST['dosen'],
                    $_POST['ruang'],
                    $_POST['organisasi'],
                    $_POST['alasan'],
                    $_POST['mulai'],
                    $_POST['selesai']);

                if($result){
                    $response['error'] = false;
                    $response['message'] = "Booking added!";
                    $response['bookings'] = $db->getBookings();
                }
                else{
                    $response['error'] = true;
                    $response['message'] = "Error occured!";
                }
                break;

Before using HashMap, i tried using my Booking object (i created from the model class), but it doesn't input the data to my database either. My question is how do i parse the object that the android send to the php rest api so the api can input the data to my database? thank you for your help

Here's the response i get in the log cat :

07-22 17:16:09.472 12761-12761/com.telkomuniversity.iflab.spriflab I/RESPONSE: Response{protocol=http/1.1, code=200, message=OK, url=xxxx}
07-22 17:16:09.472 12761-12761/com.telkomuniversity.iflab.spriflab I/HTTP RESPONSE: {message=Parameters title,start,end,nama,alamat,nohp,image,dosen,ruang,organisasi,alasan,mulai,selesai missing, error=true}

Editted ==

RetrofitCLient class :

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

public class RetrofitClient {

    private static Retrofit retrofit = null;

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

        return retrofit;
    }

}

UserService interface :

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.FieldMap;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Path;

public interface UserService {

    @GET("api.php?apicall=getBookings")
    Call<List<BookingInfo>> getBookings();

    @POST("api.php?apicall=createBooking")
    Call<HashMap<String, String>> addBooking(@Body HashMap<String, String> booking);

    @PUT("api.php?apicall=updateStatus")
    Call<BookingInfo> updateStatus(@Path("status") String status, @Body BookingInfo booking);

    @DELETE("api.php?apicall=deleteBooking&={id}")
    Call<BookingInfo> deleteBooking(@Path("id") int id);

}

and the create of the HashMap :

HashMap<String, String> params = new HashMap<>();
        params.put("title", nim);
        params.put("start", "10/16/2018");
        params.put("end", "10/17/2018");
        params.put("nama", name);
        params.put("alamat", alamat);
        params.put("nohp", hp);
        params.put("image", "test.jpg");
        params.put("dosen", dosen);
        params.put("ruang", ruang);
        params.put("organisasi", organisasi);
        params.put("alasan", alasan);
        params.put("mulai", waktuMulai);
        params.put("selesai", waktuSelesai);

FormRuanganActivity class :

import android.app.DatePickerDialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.Toast;

import com.telkomuniversity.iflab.spriflab.ApiUtils.APIProperties;
import com.telkomuniversity.iflab.spriflab.ApiUtils.UserService;
import com.telkomuniversity.iflab.spriflab.Model.BookingInfo;
import com.telkomuniversity.iflab.spriflab.R;

import java.util.Calendar;
import java.util.HashMap;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class FormRuanganActivity extends AppCompatActivity implements View.OnClickListener{

    // item dari layout
    private EditText etNama, etNIM, etAlamat,etHP, etAlasan, etDosen, etOrganisasi;
    private EditText etDate; // not editable
    private Spinner spinnerRuangan, spinnerWaktuMulai, spinnerWaktuSelesai;
    private Button btnDate, btnSubmit;
    private ProgressBar progressBar;
    private ScrollView scrollViewForm;

    // isi spinner
    private static final String[] itemSpinnerRuangan = {"IFLAB1", "IFLAB2", "IFLAB3",
            "IFLAB4", "IFLAB5", "IKLAB1", "IKLAB2",};
    private static final String[] itemSpinnerWaktuMulai = {"--Waktu Mulai--", "18:00:00", "18:30:00", "19:00:00",
            "19:30:00", "20:00:00", "20:30:00", "21:00:00", "21:30:00", "22:00:00"};
    private static final String[] itemSpinnerWaktuSelesai = {"--Waktu Selesai--", "18:00:00", "18:30:00", "19:00:00",
            "19:30:00", "20:00:00", "20:30:00", "21:00:00", "21:30:00", "22:00:00"};

    // datepicker variabel
    private DatePickerDialog.OnDateSetListener dateListener;

    // api properties
    public static final int CODE_GET_REQUEST = 1024;
    public static final int CODE_POST_REQUEST = 1025;
    private UserService userService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_form_ruangan);

        scrollViewForm = findViewById(R.id.scrollViewForm);

        setTitle("Booking Form");

        userService = APIProperties.getUserService();

        progressBar = findViewById(R.id.progressBar);

        etNama = findViewById(R.id.etNama);
        etNIM = findViewById(R.id.etNIM);
        etAlamat = findViewById(R.id.etAlamat);
        etHP = findViewById(R.id.etHP);
        etAlasan = findViewById(R.id.etAlasan);
        etDosen = findViewById(R.id.etDosen);
        etOrganisasi = findViewById(R.id.etOrganisasi);

        etDate = findViewById(R.id.etDate);

        btnDate = findViewById(R.id.btnDate);
        btnSubmit = findViewById(R.id.btnSubmit);
        btnDate.setOnClickListener(this);
        btnSubmit.setOnClickListener(this);

        spinnerRuangan = findViewById(R.id.spinnerRuangan);
        ArrayAdapter<String> arrayAdpt =  new ArrayAdapter<String>(FormRuanganActivity.this,
                android.R.layout.simple_spinner_item, itemSpinnerRuangan);
        arrayAdpt.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerRuangan.setAdapter(arrayAdpt);
        spinnerRuangan.setSelection(0);
        spinnerRuangan.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                // on progress
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
                // on progress
            }
        });

        spinnerWaktuMulai = findViewById(R.id.spinnerWaktuMulai);
        ArrayAdapter<String> arrayAdptMulai = new ArrayAdapter<String>(FormRuanganActivity.this,
                android.R.layout.simple_spinner_item, itemSpinnerWaktuMulai);
        arrayAdptMulai.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerWaktuMulai.setAdapter(arrayAdptMulai);
        spinnerWaktuMulai.setSelection(0);
        spinnerWaktuMulai.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                //on progress
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
                //on progress
            }
        });

        spinnerWaktuSelesai = findViewById(R.id.spinnerWaktuSelesai);
        ArrayAdapter<String> arrayAdptSelesai = new ArrayAdapter<String>(FormRuanganActivity.this,
                android.R.layout.simple_spinner_item, itemSpinnerWaktuSelesai);
        arrayAdptSelesai.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerWaktuSelesai.setAdapter(arrayAdptSelesai);
        spinnerWaktuSelesai.setSelection(0);
        spinnerWaktuSelesai.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                //on progress
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
                //on progress
            }
        });

        dateListener = new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker datePicker, int year, int month, int day) {
                try {
                    month = month + 1;
                    String date = day + "-" + month + "-" + year;

                    etDate.setText(date);
                }
                catch(Exception e){
                    Toast.makeText(FormRuanganActivity.this, "Error Occurred", Toast.LENGTH_SHORT).show();
                }
            }
        };


    }


    @Override
    public void onClick(View view) {
        if(view == btnSubmit){
            try {
                //Toast.makeText(FormRuanganActivity.this, "Under Maintenance", Toast.LENGTH_SHORT).show();
                createBooking();

            } catch(Exception e){
                e.printStackTrace();
                Toast.makeText(FormRuanganActivity.this, "Exception detected" , Toast.LENGTH_SHORT).show();
            }
        }
        else if(view == btnDate){
            try {
                Calendar cal = Calendar.getInstance();
                int year = cal.get(Calendar.YEAR);
                int month = cal.get(Calendar.MONTH);
                int day = cal.get(Calendar.DAY_OF_MONTH);

                DatePickerDialog dialog = new DatePickerDialog(FormRuanganActivity.this,
                        android.R.style.Theme_Holo_Light_Dialog_MinWidth,
                        dateListener,
                        year, month, day);
                dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
                dialog.show();
            } catch (Exception e){
                Toast.makeText(FormRuanganActivity.this, "Exception detected!", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void createBooking(){
        String name = etNama.getText().toString().trim();
        String nim = etNIM.getText().toString().trim();
        String alamat = etAlamat.getText().toString().trim();
        String hp = etHP.getText().toString().trim();
        String alasan = etAlasan.getText().toString().trim();
        String dosen = etDosen.getText().toString().trim();
        String organisasi = etOrganisasi.getText().toString().trim();

        String ruang = spinnerRuangan.getSelectedItem().toString();
        String waktuMulai = spinnerWaktuMulai.getSelectedItem().toString();
        String waktuSelesai = spinnerWaktuSelesai.getSelectedItem().toString();

        String tanggal = etDate.getText().toString().trim();

        int spn1 = spinnerWaktuMulai.getSelectedItemPosition();
        int spn2 = spinnerWaktuSelesai.getSelectedItemPosition();

        if(TextUtils.isEmpty(name)){
            etNama.setError("Silahkan masukkan nama anda.");
            etNama.requestFocus();
            return;
        }
        else if(TextUtils.isEmpty(nim)){
            etNIM.setError("Silahkan masukkan NIM anda.");
            etNIM.requestFocus();
            return;
        }
        else if(TextUtils.isEmpty(alamat)){
            etAlamat.setError("Silahkan masukkan alamat anda.");
            etAlamat.requestFocus();
            return;
        }
        else if(TextUtils.isEmpty(hp)){
            etHP.setError("Silahkan masukkan Nomor HP anda.");
            etHP.requestFocus();
            return;
        }
        else if(TextUtils.isEmpty(alasan)){
            etAlasan.setError("Silahkan masukkan alasannya.");
            etAlasan.requestFocus();
            return;
        }
        else if(TextUtils.isEmpty(dosen)){
            etDosen.setError("Silahkan masukkan nama dosen penanggung jawabnya.");
            etDosen.requestFocus();
            return;
        }
        else if(TextUtils.isEmpty(organisasi)){
            etOrganisasi.setError("Silahkan masukkan nama organisasi anda.");
            etOrganisasi.requestFocus();
            return;
        }
        else if(TextUtils.isEmpty(tanggal)){
            etDate.setError("Silahkan masukkan tanggal peminjaman.");
            etDate.requestFocus();
            return;
        }
        else if(spn1 == 0){
            Toast.makeText(FormRuanganActivity.this, "Waktu Mulai harap diisi", Toast.LENGTH_SHORT).show();
            spinnerWaktuMulai.requestFocus();
        }
        else if(spn2 == 0){
            Toast.makeText(FormRuanganActivity.this, "Waktu Selesai harap diisi", Toast.LENGTH_SHORT).show();
            spinnerWaktuSelesai.requestFocus();
        }

        // tanggal start sama end nya masih fix di tanggal ini belom dirubah jadi editable
        HashMap<String, String> params = new HashMap<>();
        params.put("title", nim);
        params.put("start", "10/16/2018");
        params.put("end", "10/17/2018");
        params.put("nama", name);
        params.put("alamat", alamat);
        params.put("nohp", hp);
        params.put("image", "test.jpg");
        params.put("dosen", dosen);
        params.put("ruang", ruang);
        params.put("organisasi", organisasi);
        params.put("alasan", alasan);
        params.put("mulai", waktuMulai);
        params.put("selesai", waktuSelesai);


        BookingInfo b = new BookingInfo();
        b.setNim(nim);
        b.setTanggalmulai("10/16/2018");
        b.setTanggalselesai("10/17/2018");
        b.setNama(name);
        b.setAlamat(alamat);
        b.setNohp(hp);
        b.setImage("image.jpg");
        b.setDosen(dosen);
        b.setRuangan(ruang);
        b.setOrganisasi(organisasi);
        b.setAlasan(alasan);
        b.setWaktumulai(waktuMulai);
        b.setWaktuselesai(waktuSelesai);

        addBooking(params);

    }


    private void addBooking(HashMap<String, String> booking){
        Call<HashMap<String, String>> call = userService.addBooking(booking);
        call.enqueue(new Callback<HashMap<String, String>>() {
            @Override
            public void onResponse(Call<HashMap<String, String>> call, Response<HashMap<String, String>> response) {
                Log.i("RESPONSE", response.toString());
                if(response.isSuccessful()){
                    //Toast.makeText(FormRuanganActivity.this, "Success!", Toast.LENGTH_SHORT).show();
                    Log.i("API RESPONSE", response.body().toString());
                    Snackbar.make(scrollViewForm, "Data successfully inputted", Snackbar.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<HashMap<String, String>> call, Throwable t) {
                Log.e("ERROR: ", t.getMessage());
                Toast.makeText(FormRuanganActivity.this, "ERROR: " + t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

error log :

07-22 18:54:55.142 14250-14250/com.telkomuniversity.iflab.spriflab E/ERROR:: Expected a string but was BEGIN_ARRAY at line 1 column 55 path $.
10
  • Please post your Retrofit code as well as code from where you call addBooking(HashMap<String, String> booking) and create HashMap of Booking. Make sure your are sending values in the key which set in your PHP code in isParametersAvailable(array(..)); Commented Jul 22, 2018 at 10:57
  • @VirajPatel i have added the code Commented Jul 22, 2018 at 11:06
  • @IIehcram Try @FieldMap instead of @Body once and check. Commented Jul 22, 2018 at 11:23
  • @VirajPatel it showed an exception, it said "java.lang.IllegalArgumentException: @ FieldMap parameters can only be used with form encoding." Commented Jul 22, 2018 at 11:40
  • Add @FormUrlEncoded above @POST("api.php?apicall=createBooking") and check Commented Jul 22, 2018 at 11:46

1 Answer 1

1

@llehcram following code solve your problem

@FormUrlEncoded
@POST("api.php?apicall=createBooking")
Call<BookingInfo> addBooking(@FieldMap HashMap<String, String> booking);

Note: If you get error in handling BookingInfo response then you have to create POJO/Model class which is able to handle your response. You can create POJO class from response here and here

You can read more about @FieldMap here and here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.