alla
alla

Reputation: 549

RxJava: code with the condition

I search the city and if it doesn't exist I want to make an action that is different from the situation when the city exists.

public void onAddButtonClick(String cityName) {
        Subscription subscription = repository.getCity(cityName)
                .filter(city -> city != null)
                .subscribeOn(backgroundThread)
                .flatMap(city -> repository.saveCityToDb(city))
                .observeOn(mainThread)
                .subscribe(city -> view.cityExists());

        subscriptions.add(subscription);
}

getCity() method:

public Observable<City> getCity(String name){
        return fileRepository.getCityFromFile(name);
    }

and getCityFromFile()

public Observable<City> getCityFromFile(String cityName){
        try {
            InputStream is = assetManager.open(FILE_NAME);
            Scanner scanner = new Scanner(is);
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                if (line.toLowerCase().contains(cityName.toLowerCase())) {
                    String[] cityParams = line.split("\t");
                    City city = new City();
                    city.setId(Long.parseLong(cityParams[0]));
                    city.setName(cityParams[1]);
                    return Observable.fromCallable(() -> city);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return Observable.fromCallable(() -> null);
    }

So when the city is not found I want to make an alert to the user and when the city is found I want to go further (save it to DB, open main screen etc.). I use the operator filter(), but it's not exactly what I wanted, it just doesn't go further if the city == null. Can you please advice on some better idea?

Upvotes: 0

Views: 266

Answers (2)

R. Zag&#243;rski
R. Zag&#243;rski

Reputation: 20258

You could throw an an error using Observable.error() and catch it in Subsriber's onError() method.:

Subscription subscription = Observable.just("String")
            .flatMap(city -> city == null ? Observable.error(new NullPointerException("City is null")) : Observable.just(city))
            .subscribeOn(backgroundThread)
            .flatMap(city -> repository.saveCityToDb(city))
            .observeOn(mainThread)
            .subscribe(city -> view.cityExists(),
                    throwable -> view.showError());

Upvotes: 2

dwursteisen
dwursteisen

Reputation: 11515

It depends of how you design your code.

If you search a city and don't find it, maybe return an Observable.empty. or return an Observable.error instead (if it's an error case). Then, you can use another Observable in case of empty/error Observable.

for example :

    Observable<City> observableIfNoCity = /** observable with perform actions when where is no city */
    repository.getCity(wrongCity) // return an Observable.empty if no city
              .flatMap(city -> repository.saveCityToDb(city))
              .doOnNext(city -> view.cityExists())
              .switchIfEmpty(observableIfNoCity)
              .subscribe();

if you return an Observable.error, you can use onErrorResumeNext instead of switchIfEmpty.

But to behave correctly, I think you should avoid emitting a null value in getCityFromFile. Use empty or error instead

 public Observable<City> getCityFromFile(String cityName){
      return Observable.defer(() -> {
         try {
            InputStream is = assetManager.open(FILE_NAME);
            Scanner scanner = new Scanner(is);
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                if (line.toLowerCase().contains(cityName.toLowerCase())) {
                    String[] cityParams = line.split("\t");
                    City city = new City();
                    city.setId(Long.parseLong(cityParams[0]));
                    city.setName(cityParams[1]);
                    return Observable.just(city);
                }
            }
        } catch (IOException e) {
             return Observable.error(e);
        }

        return Observable.empty(); // or Observable.error(new NotFoundException());
    });
}

Upvotes: 2

Related Questions