0

I need to post data with nested Json as screen below (see "user" and then the data )

{
  "user" : 
  {
    "email": "xxxxx",
    "password" : "surabaya1234"
  }
}

currently my retrofit is working with this format

{
  "email": "xxxxx",
  "password" : "surabaya1234"  
}

this is my retrofitClient

object RetrofitClient {
    private const val BASE_URL = "http://X.X.X.X"

    private val okHttpClient = OkHttpClient.Builder()
        .addInterceptor { chain ->
            val original = chain.request()
            val requestBuilder = original.newBuilder()
                .addHeader("Authorization", token)
                .method(original.method(), original.body())
            val request = requestBuilder.build()
            chain.proceed(request)
        }.build()

    val instance: Api by lazy {
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()

        retrofit.create(Api::class.java)
    }
}

this is my buttonListener, it send the data when it pressed

binding.buttonSignUp.setOnClickListener {
  val email = editTextEmail.text.toString().trim()
  val phoneNumber = editTextPhone.text.toString().trim()
  val password = editTextPassword.text.toString().trim()
  val passwordConfirmation = editTextPassword.text.toString().trim()
  if (email.isEmpty()) {
      editTextEmail.error = "Email Required"
      editTextEmail.requestFocus()
      return@setOnClickListener
  }
  RetrofitClient.instance.createUser(email, password, phoneNumber).enqueue(object: Callback<User>{
      override fun onFailure(call: Call<User>, t: Throwable) {
          toast = Toast.makeText(activity,"Not OK",Toast.LENGTH_LONG)
      }
      override fun onResponse(call: Call<User>, response: Response<User>) {
          toast = Toast.makeText(activity,"Sukses",Toast.LENGTH_LONG)
      }

  })

this is Interface

interface Api {
    @FormUrlEncoded
    @POST("users")
    fun createUser(
        @Field("email") email:String,
        @Field("password") password:String
    ):Call<User>
}

how do I change my code probably Interface so it can send the data in nested json format like sample above, this probably simple answer, but I'm new in kotlin / java

2 Answers 2

1

You can create a model also and pass the model to retrofit it will get the work done for you automatically.

Create model accordingly the json structure.

public class UserLogin {

 @SerializedName("user")
 @Expose
 private User user;

 public User getUser() {
 return user;
 }

 public void setUser(User user) {
 this.user = user;
 }

}

public class User {

 @SerializedName("email")
 @Expose
 private String email;
 @SerializedName("password")
 @Expose
 private String password;

 public String getEmail() {
 return email;
 }

 public void setEmail(String email) {
 this.email = email;
 }

 public String getPassword() {
 return password;
 }

 public void setPassword(String password) {
 this.password = password;
 }

}

Change your api interface

interface Api {
    @POST("users")
    fun createUser(
        @Body userLogin : UserLogin
    ):Call<User>
}

and while making api call just call like this.

//create a user login model and set the data, and pass it in below method
 RetrofitClient.instance.createUser(userLogin).enqueue(object: Callback<User>{
      override fun onFailure(call: Call<User>, t: Throwable) {
          toast = Toast.makeText(activity,"Not OK",Toast.LENGTH_LONG)
      }
      override fun onResponse(call: Call<User>, response: Response<User>) {
          toast = Toast.makeText(activity,"Sukses",Toast.LENGTH_LONG)
      }

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

2 Comments

thank you, I followed all your instructions above and already and compile success, but when I test and send the data it show and error as follow "java.lang.IllegalArgumentException: @Body parameters cannot be used with form or multi-part encoding. (parameter #1) for method Api.createUser",
try removing the @FormUrlEncoded tag then check again
1

If you want to send data as you want, try this.

interface Api {
    @FormUrlEncoded
    @POST("users")
    fun createUser(
        @FieldMap HashMap<String, Object> param
    ):Call<User>
}

and add map where you send retrofit.

val hashMap = HashMap()
hashMap.put("user", sendData) //make sendData String from json
val responseBodyCall = RetrofitConnectionAPI.setConnect().createUser(hashMap)

ps. making JSONObject

val jsonData = JSONObject()
jsonData.put("email", email)   // inputed email
jsonData.put("password", password) // inputed password
val sendDate = jsonData.toString()

2 Comments

thank you, based with my data (email and password) can you give sample "make sendData String from json" , sorry I'm new with kotlin
I added making JSON

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.