Solution 1 :
First I will suggest you to Add data binding in your App
now in your Activity XML
do something like this
<!--here it is 2 way binding-->
<EditText
...
android_text="@={viewmodel.key}
... />
<!--here it is single way binding-->
<Button
...
android_onClick="@{() -> viewmodel.doneClicked()}"
... />
Now in your ViewModel
//value in key will be same as value in the EditText as it is bidirectional data binding
public MutableLiveData<String> key = new MutableLiveData<>();
//update this MutableLiveData accordingly
private MutableLiveData<Boolean> isDataAvailable = new MutableLiveData<>();
//observe this LiveData
LiveData<Boolean> isDataAvailable(){
return isDataAvailable;
}
public void doneClicked(){
//here you can get value of your "key"
//this method will call when clicking on the button
//you can call your custom method from here,
//also update data in "isDataAvailable"
}
In your Activity
viewModel.isDataAvailable().observe(this, aBoolean -> {
//here you will receive change in value of isDataAvailable
}
PS
Your question is not clear at all, and your code is not helpful
Do you want to observe change in mutableLiveData
of getLicenseData(...)
inside your viewModel
?
mutableLiveData = manualLicenseRepository.getLicenseData(licenseKey, macAddress, productId);
Please also change the name of this variable to something related the data it is getting, mutableLiveData is not a good variable name
Edit 1
try this to observe changes in the data, it is recommended to observe LiveData
but you can observer MutableLiveData
as you have not provided sufficient information I m using your mutableLiveData
variable
In your Activity
try this
viewModel.mutableLiveData.observe(this, license -> {
//here you can observe changes in your mutableLiveData when It receives data from Repo
//here license is the object of data inserted into mutableLiveData from repo
});
Please explain more.
Hope this will help!
Solution 2 :
I assume the methods you posted are from your Activity. Merely adding a method named onClick
doesn’t do anything at all; you need to attach a click listener to your button. For example, something like this in your onCreate
method:
findViewById(R.id.btn_submit).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
getLicenseData(key.getValue(), "null", FIXED_PRODUCT_ID);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
});
Solution 3 :
You have LiveData defined inside the method which is wrong. LiveData is something that’s constantly observed by View(Activity) and therefore it needs to be held in ViewModel/Repository in a member variable.
Also, your repository looks redundant (does not do anything). I suggest redefining LiveData as a member variable of your ViewModel, making the request inside the ViewModel and posting the value to LiveData.
If you just need to send request and receive result then you don’t need to even use LiveData, just use some Listener/Callback interface instead.
Problem :
The problem is if I’ll write observe statement in onCreate, it won’t observe based on user click event. Because I want to only call repository API when user fill value in edit text and submit button, then only I can get value which I have to pass in repository to make API call and pass that value to API.
repository
public MutableLiveData<License> getLicenseData(String licenseKey, String macAddress, int productId) {
final MutableLiveData<License> licenseData = new MutableLiveData<>();
apiCall.getLicenseData(licenseKey, macAddress, productId).enqueue(new Callback<License>() {
@Override
public void onResponse(Call<License> call, Response<License> response) {
licenseData.setValue(response.body());
}
@Override
public void onFailure(Call<License> call, Throwable t) {
licenseData.setValue(null);
}
});
return licenseData;
}
ViewModel class
private void getLicenseData(String licenseKey, String macAddress, int productId) {
mutableLiveData = manualLicenseRepository.getLicenseData(licenseKey, macAddress, productId);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_submit:
try {
getLicenseData(key.getValue(), "null", FIXED_PRODUCT_ID);
} catch (NullPointerException e) {
e.printStackTrace();
}
break;
}
}
Activity – onCreate:
protected void init() {
manualLicenseKeyViewModel.init();
manualLicenseKeyViewModel.getLicenseRepository().observe(this, this);
}
Comments
Comment posted by Rahul Gaur
If you are using
Comment posted by Pooja Singh
@RahulGaur the problem is onClick is my own method, and I’m doing in viewmodel class, not activity. after user click in submit button, my onclick will fire inviewmodel class, from that I’ll get some edit text value, and call the repository where retrofit callback is there. so in all this, where to put observe in activity?
Comment posted by Pooja Singh
Can you please post code with repository? Also, I want to observe getLicenseData() method, but in that method licenseKey parameter which I need to take input from user. so how can I observe? And I clearly want to observe in Activity only.
Comment posted by Rahul Gaur
You want data
Comment posted by Pooja Singh
true! I want to observe data which will coming from API. But API call only possible when user submit the button, and user only can submit the button when user input license key in edit text. and I need that license key in API parameter.
Comment posted by Rahul Gaur
And where are you stuck? I guess you are stuck at observing the data afterwards, you can observe
Comment posted by Pooja Singh
onChanged method is not called at all!
Comment posted by Petter Hesselberg
Can you show how it is hooked up to your UI? This is not clear from the code you posted. My understanding of your problem is that you want your
Comment posted by Pooja Singh
Nope, if you know about MVVM with observer design pattern, then you can understand my question. onClick is getting called and also it hit the API, after that Observer overridden method onChanged should be fired with the API response result that is already set.
Comment posted by Pooja Singh
solve my question, and I’ll give you a green tick mark, if you can
Comment posted by Petter Hesselberg
I don’t understand the question. I’m not saying the question is improper, only that more information (that is, code) is needed.
Comment posted by Pooja Singh
sorry Petter, I deleted that comment
Comment posted by Pooja Singh
So many things may come in future. Also I want to exactly follow MVVM. Also your suggestion is correct as of now, but still I want to learn that how this things can be done, for that please post your answer with code, and explain me what’s wrong am I doing?
Comment posted by developer.android.com/topic/libraries/architecture/livedata
Having repository does not make your architecture more or less MVVMish. It’s just an extension which can be used for mapping/caching/abstracting data source/simpler callbacks etc. You dont use that. Therefore as a start, you can ditch the repository for now and implement it later when you understand more about the architecture. The core of MVVM is View observing a Model and reacting to it. Just define your liveData as a member variable inside ViewModel. Just like it is done in all the basic tutorials like this one:
Comment posted by Pooja Singh
Anyhow, I’ll change it. But if I’ll skip the problems like this, then how can I learn? Atleast give me the complete answer.
Comment posted by Singed
I suggest you make it work without repository first. It’s easier to learn MVVM when you have plain MVVM without extra stuff. Then you can add repository later.
Comment posted by Pooja Singh
I respect your suggestion, but I why don’t you’re teaching me with repository?