2016-09-23 10 views
0

都市を検索し、存在しない場合は、都市が存在する状況とは異なる行動をしたい。RxJava:条件付きコード

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()方法:

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

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); 
    } 

だから、都市が見つからない場合、私は、ユーザーにアラートを作りたいと都市が発見されたときに私が欲しいですさらに進む(DBに保存し、メイン画面を開くなど)。私は演算子filter()を使用しますが、正確には私が望むものではありません。 いくつか良いアイデアを教えていただけますか?

答えて

2

それはあなたのコードを設計する方法に依存。

都市を検索しても見つからない場合は、おそらくObservable.emptyを返してください。代わりにObservable.errorを返してください(エラーの場合)。空/エラーの場合はObservableの場合は、別のObservableを使用することができます。例えば

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(); 

あなたがObservable.errorを返す場合は、onErrorResumeNextの代わりswitchIfEmptyを使用することができます。

正しく動作するには、nullの値をgetCityFromFileに書き込まないでください。私は都市が発見された場合にはview.cityExists()メソッドを入れないとき

に代わり
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()); 
    }); 
} 
+0

emptyerrorを使用しますか?それは同じ方法で別のオブザーバブルになるのだろうか? – alla

+0

その結果、switchIfEmpty()の使用方法がわかりませんでした(詳細はこの記事を読んでいます)が、Observable.error(e)を返すという考えが好きでした。 Observable.empty();したがって、onAddButtonClick()では、subscribe()メソッドで次のコードを追加しました。 'throwable - > view.showCouldNotFindCity()'、 '() - > view.showCouldNotFindCity()' – alla

2

あなたはObservable.error()を使用してエラーを投げるとSubsriberonError()方法でそれをキャッチすることができ:

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());