Android Coder
Android Coder

Reputation: 11

parse JSON object using retrofit in kotlin

I am trying to show json data using retrofit library in kotlin

This is my Json:

[
  {
    "login": "mojombo",
    "id": 1,

  },
  {
    "login": "defunkt",
    "id": 2,
    }
]

My Main activity

 call.enqueue(object : Callback<UserResponse> {
        override fun onResponse(call: Call<UserResponse>, response: Response<UserResponse>) {
            Log.e("list","list")
            val countrylist = response.body()
            for (size in response.body()) {
                System.out.println(size.toString())
            }

            // var listOfMovies: List<UserResponse> = response.body()?.results!!
           // myCustomAdapter = UserListAdapter(applicationContext, listOfMovies)
          //  recyclerView.setAdapter(myCustomAdapter)
            progressBar.visibility = View.GONE
        }

        override fun onFailure(call: Call<UserResponse>?, t: Throwable?) {
            progressBar.visibility = View.GONE
            Log.e("list", t.toString())
        }
    })

Upvotes: 1

Views: 6233

Answers (2)

Ooguro
Ooguro

Reputation: 121

This an app that I build in kotlin using retrofit and rxjava in the best way possible using a test API.

Model

data class Post( val userID:Int, val title:String, val body: String)

Retrofit Package

IMyApi interface

interface IMyApi {

@get:GET("posts")
val posts: Observable<List<Post>>
}

RetrofitClient Object class

object RetrofitClient {


val instance: Retrofit by lazy {
    Retrofit.Builder()
        .baseUrl("https://jsonplaceholder.typicode.com/")
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build()
 }
}

Adapter Package

PostAdapter class

  class PostAdapter(private val context: Context, private val postList: List<Post>)
                :RecyclerView.Adapter<PostViewHolder>()
            {
                override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): 
   PostViewHolder {
                    val itemView = LayoutInflater.from(parent.context)
                        .inflate(R.layout.post_item, parent, false)
                    return PostViewHolder(itemView)
                }

                override fun getItemCount(): Int {
                    return postList.size
                }

                   override fun onBindViewHolder(holder: PostViewHolder, position: Int) 
    {
                    holder.userId.text = postList[position].userID.toString()
                    holder.title.text = postList[position].title
                    holder.body.text = StringBuilder(postList[position].body.substring(0,20))
                        .append("...").toString()
                }
            }

PostViewHolder class

class PostViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {

var userId = itemView.txtID
var title = itemView.txtTitle
var body = itemView.txtBody
}

MainActivity

  class MainActivity : AppCompatActivity() {

                    private lateinit var jsonApi: IMyApi
                    private var compositeDisposable: CompositeDisposable = CompositeDisposable()

                    override fun onCreate(savedInstanceState: Bundle?) {
                        super.onCreate(savedInstanceState)
                        setContentView(R.layout.activity_main)

                        // Init api
                        val retrofit = RetrofitClient.instance
                        jsonApi = retrofit.create(IMyApi::class.java)


                        // View
                        recycler_posts.layoutManager = LinearLayoutManager(this)
                        recycler_posts.setHasFixedSize(true)
                        fetchData()
                    }

                    private fun fetchData() {
                        compositeDisposable.add(jsonApi.posts
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe { posts->displayData(posts)})
                    }

                    private fun displayData(posts: List<Post>?) {
                        val adapter = PostAdapter(this, posts!!)
                        recycler_posts.adapter = adapter
                    }
                }

Using this as displayed above should help you solve your issue hopefully. Also when in the code you come across "recycler_posts". This is a id to the recycler added in activity_main. If you need me to include that let me know

Upvotes: 2

Francislainy Campos
Francislainy Campos

Reputation: 4134

That's what we have on our app

object GetFAQsAPI {

private val LOG_TAG = GetFAQsAPI.javaClass.simpleName

interface ThisCallback {

    fun onSuccess(getFAQs: GetFAQs)

    fun onFailure(failureMessage: String)

    fun onError(errorMessage: String)
}

/* POST */
fun postData(jo: JsonObject, callback: GetFAQsAPI.ThisCallback) {
    val call = Service.getService().get_faqs(jo)
    call.enqueue(object : Callback<JsonObject> {

        override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {

            //Log.e(LOG_TAG, response.body().toString());

            try {
                if (response.body()?.get("success")!!.asBoolean) {

                    val gson = GsonBuilder().setPrettyPrinting().create()
                    val getFAQs = gson.fromJson(response.body(), GetFAQs::class.java)

                    callback.onSuccess(getFAQs)

                } else {
                    Log.e(LOG_TAG, "else")

                    val error = response.body()!!.get("err").asString

                    callback.onError(error)
                }

            } catch (e: Exception) {
                Log.e(LOG_TAG, "exception" + e.localizedMessage)

                callback.onFailure(e.message!!)
            }

        }

        override fun onFailure(call: Call<JsonObject>, t: Throwable) {
            Log.e(LOG_TAG, "onFailure: " + t.message)

            callback.onFailure(t.message!!)

        }
    })

}

}

That's how we call it from our fragment - getFAQs is the object parsed.

private fun getFAQsAPI() {

    showLoading(true)

    val jo = JsonObject().apply {
        addProperty("faq_category", "admin")
    }

    GetFAQsAPI.postData(jo, object : GetFAQsAPI.ThisCallback {
        override fun onSuccess(getFAQs: GetFAQs) {
            Log.i(LOG_TAG, "onSuccess")

            showLoading(false)

            updateUI(getFAQs)
        }

        override fun onFailure(failureMessage: String) {
            Log.e(LOG_TAG, failureMessage)
        }

        override fun onError(errorMessage: String) {
            Log.e(LOG_TAG, errorMessage)
        }
    })
}

Hope that helps.

Upvotes: 1

Related Questions