3

I am calling one api which gives Http status code 400

This is my NetworkBoundResourceNoDb

public abstract class NetworkBoundResourceNoDb<RequestType> {

    private Observable<Resource<RequestType>> result;

    @MainThread
    protected NetworkBoundResourceNoDb() {
        Observable<Resource<RequestType>> source;
        source = createCall()
            .subscribeOn(Schedulers.io())
            .doOnError(t -> onFetchFailed())
            .observeOn(AndroidSchedulers.mainThread());

        result = Observable.ambArray(source);
    }


    public Observable<Resource<RequestType>> getAsObservable() {return result;}

    protected boolean onFetchFailed() {
        return false;
    }


    @NonNull
    @MainThread
    protected abstract Observable<Resource<RequestType>> createCall();
}

This is API code

@GET("api/content/count")
Observable<List<WordCountData>> wordCount();

This is repository Function

    fun wordCount(): Observable<Resource<List<WordCountData>>>? {
    return object : NetworkBoundResourceNoDb<List<WordCountData>>() {

        override fun createCall(): Observable<Resource<List<WordCountData>>> {
            return courseApi.wordCount()
                .flatMap { learntWords ->
                    Observable.just(
                        if (learntWords == null) Resource.error("", emptyList())
                        else Resource.success(learntWords)
                    )
                }
        }

    }.asObservable
}

This is viewmodel Code

private var wordCount = MutableLiveData<Resource<List<WordCountData>>>()

fun getWordCountLiveData() = wordCount

fun getWordCountList() {
    courseRepository.wordCount()?.subscribe { resource -> getWordCountLiveData().postValue(resource) }
}

This is my view code

private fun loadWordCount() {
    crViewModel = ViewModelProviders.of(this, viewModelFactory).get(CrViewModel::class.java)
    crViewModel.getWordCountLiveData().observe(this, androidx.lifecycle.Observer {
        resource -> when {
        resource.isLoading -> println("loading")
        resource.data != null -> {
            drawChart(resource.data)
        }
        else -> handleErrorResponse()
    }
    })
    crViewModel.getWordCountList()
}

I need to pass Http Status code to view. i am able to get the error in onFetchfailed in repository while implementing it with throwable parameter but not able to handle it after that

it gives me "io.reactivex.exceptions.OnErrorNotImplementedException: HTTP 400 " Error

please help me thanks in advance

1 Answers1

1

man, you're asking for many questions in 1.

fun getWordCountList() {
courseRepository.wordCount()?.subscribe { resource -> getWordCountLiveData().postValue(resource) }
}

This is the chunk of code that triggers all of your other network code. However, this lambda only has a success param, not an error param. Add a second lambda, and surround it by paranthesis, in order to account for both success and failure:

.subscribe({
    successResponse -> // handle success
}, 
{ error -> // handle error
})

so, that should take care of at least the "OnErrorNotImplementedException"

Error 400 usually means that your request is invalid, and/or you're passing the wrong set of parameters to your request. I can't help you there with the amount of info you gave us, and without knowing anything about your server.

Finally: "I need to pass Http Status code to view". What?? why? Your title even mentions architecture! Why does your view layer even care about the response code from a network call??

Don't do that. Sure, your view "can" know about the response code, but this is something the view layer should not know about at all.

I hope this helps.

TooManyEduardos
  • 4,206
  • 7
  • 35
  • 66
  • Thanks man i am new in rx, i will try this ...... for that "http status code in view" i need that in few cases for not authorized and some other behaviour which user need to know.... if there is any other way to handle that from viewmodel itself that will very helpful .. thanks again – Pankaj Joshi Feb 11 '20 at 05:12
  • 1
    well..there are many ways, and they depend heavily on how much you want to do, how much you understand the circle you may possibly leave the users, and what UX you want to present to your user. The basis of software architecture is that each layer of code can be swapped, and it wouldn't affect the rest of the layers. In your example, think of changing the data source from being the network to being database...now you no longer have 200s and 404s, so your UI shouldn't have to change because of that. For unauthorized cases, look into http interceptors, and make them trigger on 401s – TooManyEduardos Feb 11 '20 at 22:36