Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The retrofit call not update viewmodel or viewmodel not update the view

I try get a user from a rest api for do login in my android app for get this I have the next code

LoginActivity.java

public class LoginActivity extends AppCompatActivity {

    private   LoginViewModel loginViewModel;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityLoginBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_login);
        loginViewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
        binding.setLoginViewModel(loginViewModel);
        binding.setLifecycleOwner(this);

        loginViewModel.user.observe(this, new Observer<User>() {
            @Override
            public void onChanged(@Nullable User user) {
                Toast.makeText(getApplicationContext(), user.toString(), Toast.LENGTH_LONG).show();
            }
        });

    }
}

LoginViewModel.java

public class LoginViewModel extends ViewModel {

    private LoginRespository loginRespository = new LoginRespository();
    public MutableLiveData<User> user = new MutableLiveData<>();

    public MutableLiveData<String> email = new MutableLiveData<>();
    public MutableLiveData<String> password = new MutableLiveData<>();

    public LoginViewModel() {}

    public void onLoginClicked() {
        user = loginRespository.doLogin(email.getValue(), password.getValue());
    }

}

LoginRepository.java

@Singleton
public class LoginRespository {
    private APIInterface apiInterface;

    public LoginRespository(){
        this.apiInterface = APIClient.getClient().create(APIInterface.class);
    }

    //private final APIInterface apiInterface;
    /*@Inject
    public LoginRespository(APIInterface apiInterface) {
        this.apiInterface = apiInterface;
    }*/

    public MutableLiveData<User> doLogin(String email, String password) {
        final MutableLiveData<User> data = new MutableLiveData<>();

        Call<User> call = apiInterface.doGetLogin(email, password, APIClient.X_API_KEY, APIClient.X_CLIENT_ID);
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                User user = response.body();
                Log.d("#####0", user.toString());
                if (user.code.equals(APIClient.Codes.OK)){
                    Log.d("#####1", user.toString());
                    data.setValue(user);
                    Log.d("#####2", data.toString());
                }
            }

            @Override
            public void onFailure(Call<User> call, Throwable t) {
                call.cancel();
            }
        });

        return data;
    }
}

User.java

public class User{

    @SerializedName("code")
    @Expose
    public String code;
    @SerializedName("data")
    @Expose
    public List<Datum> data = null;
    @SerializedName("description")
    @Expose
    public String description;
    @SerializedName("datetime")
    @Expose
    public String datetime;

    /**
     * No args constructor for use in serialization
     *
     */
    public User() {
    }

    /**
     *
     * @param description
     * @param data
     * @param code
     * @param datetime
     */
    public User(String code, List<Datum> data, String description, String datetime) {
        super();
        this.code = code;
        this.data = data;
        this.description = description;
        this.datetime = datetime;
    }

    @Override
    public String toString() {
        return "User{" +
                "code='" + code + '\'' +
                ", data=" + data +
                ", description='" + description + '\'' +
                ", datetime='" + datetime + '\'' +
                '}';
    }
}

In the view, I have two EditText for do login and work perfectly because I can pass email and password into LoginRepositori.doLogin and I get the response with a user, but when I want to get the update about the user data in the activity with loginViweMode.User.observe... I never get notifications.

Then how can do it, for that the loginViewModel.User.observe... in the activity be called.

Thanks.

like image 930
Tlaloc-ES Avatar asked Jan 21 '26 23:01

Tlaloc-ES


1 Answers

You are missing out on some connections between activity and view model. Since repository returns new live data object each time user will not be able to observe since it's value is replaced by the login call.

To solve this you can either pass the user livedata to repository and update its value from repository rather creating new object in every call

or you can use switchMap() transformation function to transform the result into user variable

like image 125
Samuel Robert Avatar answered Jan 24 '26 16:01

Samuel Robert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!