1

I'm making a simple recyclerview list with items returned from an API. I have my retrofit client

open class CoinListRetroFit {

val httpLoggingInterceptor = HttpLoggingInterceptor()
val okHttpClient = OkHttpClient.Builder()
        .readTimeout(1000, TimeUnit.SECONDS)
        .addInterceptor(httpLoggingInterceptor)
        .build()


private val retroFit: Retrofit = Retrofit.Builder()
        .baseUrl(" https://api.coinmarketcap.com/v2/")
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .client(okHttpClient)
        .build()

val coinList: LuckyCoinApiService = retroFit.create(LuckyCoinApiService::class.java)

I have an Api Service and Client which make the call

interface LuckyCoinApiService {

@GET("listings/")
fun getCoinListing() : Observable<CoinListResponse>

}

class LuckyCoinApiClient : CoinListRetroFit() {

fun getCoins(): Observable<List<CoinListItem>> =
        coinList.getCoinListing().map { response ->
            response.cryptoList
        }

}

Now below is where im subscribing to the observable and populating my list, however it returns null and when I go to debug it crashes in the Client class on coinList.getCoinListing. I am given no information relating to the network calls which is what I thought the OkHttpClient Interceptor was for. This is where I subscribe to the observable...

  addDisposable(LuckyCoinApiClient()
            .getCoins()
            .compose(ObservableTransformer { upstream: Observable<List<CoinListItem>> ->
                upstream
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
            })
            .subscribe({ response ->
                list = response
                adapter.addItems(list!!)
            },
                    { _ ->
                        Log.e("CoinListController", "Error retrieving list!!")
                    }))
}



    fun addDisposable(disposable: Disposable) {
    if (compositeDisposable == null) {
        compositeDisposable = CompositeDisposable(disposable)
    } else {
        compositeDisposable!!.add(disposable)
    }
}

I must be misunderstanding something about how making these requests works. As well as how to properly set up a logging interceptor

EDIT:

After adding internet permissions and making some changes to my observable and doing .setLevel() on my interceptor. I can now see the network call in LogCat and I'm getting the expect 200 OK response with the list..

However now the response stops at

    08-30 15:06:25.446 5214-5238/com.example.luckycoins D/OkHttp:             "id": 3238, 
08-30 15:06:25.446 5214-5238/com.example.luckycoins D/OkHttp:             "name": "ABCC Token", 
08-30 15:06:25.446 5214-5238/com.example.luckycoins D/OkHttp:             "symbol": "AT", 
08-30 15:06:25.446 5214-5238/com.example.luckycoins D/OkHttp:             "website_slug": "abcc-token"
08-30 15:06:25.446 5214-5238/com.example.luckycoins D/OkHttp:         }, 
08-30 15:06:25.446 5214-5238/com.example.luckycoins D/OkHttp:         {
08-30 15:06:25.446 5214-5238/com.example.luckycoins D/OkHttp:             "id": 3239, 

it stops at that id without reading in its attributes. There is also 2-3 list items remaining that it does not reach.

Kyle
  • 695
  • 6
  • 24
  • Is there any error logging from retrofit or gson? Possibilities are maybe your gson converter cannot parse your json response correctly since your pojo does not matches the response. Just my guess. Maybe you can provide more info such as your model and your implementation of the adapter. – Kit Mak Aug 31 '18 at 04:32
  • I'm setting your answer as correct. I am able to populate the list. The issue was that the observable call would move on before the observable was complete..adding to the adapter 0 items. Then about 15 seconds later when observable call completes it then fills the List object but I was not calling `notifyDatasetChanged()` so the view was never updated. My design is poor and I will have to figure out a better way to restructure but it works for now! – Kyle Aug 31 '18 at 13:11

1 Answers1

1

Your adapter.addItems(list!!) is outside of the stream block. You should not update your ui by a side effect. Since your api request will be on other threads from the io thread pool, your adapter will very possibly update itself with a null list before your api calls complete.

What you should do is update your adapter inside the subscribe({}) block.

Also, you should not force unwrap a nullable list. What you should do in kotlin is either wrap it with a null check like you would do it in Java, or use let operator like this list?.let{ list ->}

Kit Mak
  • 231
  • 2
  • 4
  • Would you please mark the answer as correct if it solves your problem? – Kit Mak Aug 30 '18 at 09:11
  • What you said makes sense but it did not solve my problem. My list is still null and there is no log of the network calls being output to the LogCat – Kyle Aug 30 '18 at 13:41