简体   繁体   中英

Retrofit response from view-model to observe in fragment using RxJava

I have a Login Fragment which uses API call to login. I use mvvm and databinding to bind views with viewmodel. In viewmodel Login Response via retrofit is observed in viewmodel which uses RxJava.

I need to observe the retrofit response in the loginFragment, which is not get observed when retrofit response came. Following are the fragment and viewmodel code. I need retrofit response to pass to fragment or fragment get automatically observe response.

public class LoginFragment extends Fragment {

    private LoginViewModel mLoginViewModel;
    private Observable<LoginResult> dataObservable;
    public static String TAG = LoginFragment.class.getSimpleName();
    public Disposable disposable;
    public static Fragment LoginFragmentInstance() {
        Log.e(TAG, "LoginFragmentInstance: " );
        Fragment fragment = new LoginFragment();
        return fragment;
    }

    public LoginFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        FragmentLoginBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false);
        mLoginViewModel = new LoginViewModel(getActivity());
        //setViewModel method name changes based on variable name declared in XML

        //mLoginViewModel.loginResult.observeO
        dataObservable= mLoginViewModel.loginResult;

        disposable = dataObservable.subscribe(new Consumer<LoginResult>() {
            @Override
            public void accept(LoginResult result) throws Exception {
                Log.d("TAG", result.toString());
            }
        });

        binding.setViewModel(mLoginViewModel);
        return binding.getRoot();
    }

    @Override
    public void onDestroy() {
        mLoginViewModel.destroy();
        disposable.dispose();
        super.onDestroy();
    }

}

ViewModel File

public class LoginViewModel {
    private static final String TAG = "LoginViewModel";
    public ObservableField<String> userName  = new ObservableField<>();
    public ObservableField<String> password  = new ObservableField<>();
    public ObservableField<String> email  = new ObservableField<>();
    public ObservableField<String> userNameErr  = new ObservableField<>();
    public ObservableField<String> passwordErr  = new ObservableField<>();
    public ObservableField<String> emailErr  = new ObservableField<>();
    public Observable<LoginResult> loginResult = new Observable<LoginResult>() {
        @Override
        protected void subscribeActual(Observer<? super LoginResult> observer) {

        }
    };
    public ObservableField<Boolean> enableLogin;
    private CompositeDisposable myCompositeDisposable = new CompositeDisposable();
    private HashMap<String, String> loginApiParams;

    public Action signIn;
    public Context context;

    public LoginViewModel(final Context context) {

        this.context = context;
        Observable result =  Observable.combineLatest(FieldUtils.toObservable(userName), FieldUtils.toObservable(password),
                new BiFunction() {
                    @Override
                    public Object apply(Object userName, Object password) throws Exception {
                        int failCount = 0;
                        if (!InputValidator.validateMobileno(userName.toString())) {
                            ++failCount;
                            userNameErr.set(context.getResources().getString(R.string.mobileno_incorrect));
                        } else {
                            userNameErr.set("");
                        }
                        if (!InputValidator.validatePassword(password.toString())) {
                            ++failCount;
                            passwordErr.set(context.getResources().getString(R.string.password_incorrect));
                        } else {
                            passwordErr.set("");
                        }
                        return failCount == 0;
                    }
                });
        enableLogin = FieldUtils.toField(result);
        signIn = new Action() {
            @Override
            public void run() throws Exception {
                Log.d(TAG, "signIn button clicked");
                loginCall();
            }
        };
     }

    private void loginCall()  {

        loginApiParams =  new HashMap<>();
       // loginApiParams.put(, paymentType.toString())
        loginApiParams.put(ApiParameterKeyConstants.MOBILE,userName.get());
        loginApiParams.put(ApiParameterKeyConstants.PASSWORD, password.get());
        UserApi usersService = ApiService.INSTANCE.apiCall();

        Disposable disposable = usersService.getLogin(loginApiParams)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<LoginResult>() {
                    @Override
                    public void accept(LoginResult result) throws Exception {
                        loginResult = Observable.just(result);
                        //loginResult.subscribe()
                        //loginResult = result  ;
                        //Log.d(TAG, "Login Successfull");
                    }
                    }, new Consumer<Throwable>()
                    {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            Log.d(TAG, "Login Failed");
                        }
                    });
        myCompositeDisposable.add(disposable);
    }
}

It seems like you are re-assigning the loginResult an Observable in your loginCall method of the ViewModel instead of passing the result to its Observers.

You should try calling loginResult.onNext(result) or loginResult.onComplete(result) instead of loginResult = Observable.just(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM