I'm working on an application that fetches data from a graphql server via apollo-android.
I do a single fetch on my aws rds database. I do this fetch right at the onCreate()
of my CalendarFragment.
The thing is, at onViewCreated()
, I want to set my textview to one of the fields that is fetched, first and last name. So, I run my getBarberFullName
method which returns the String
value of mBarberFullName
. I'm trying to follow the UI controller displays while the view model handles all the logic approach. getBarberFullName
resides within my ViewModel.
public String getBarberFullName() {
if (appointmentsAreNull()) return mBarberFullName.getValue();
AppointmentModel am = mMasterAppointments.getValue().get(0);
String fullName = am.bFirstName;
fullName = fullName.concat(" " + am.bLastName);
// Get the logged in barber's full name and set it as mBarberFullName.
mBarberFullName.setValue(fullName);
return mBarberFullName.getValue();
}
where mMasterAppointments
is a MutableLiveData<List<AppointmentModel>>
. In my onViewCreated()
callback, I run
String barberName = mBarberViewModel.getBarberFullName();
mTxtv_barberName.setText(barberName);
However, mMasterAppointments
is always null so it just returns the default value of mBarberFullName which is a String
.
However, if I were to run the following code, in the same onViewCreated()
, I get the desired result where the textview is updated with the desired barber's full name.
mBarberViewModel.getAllAppointments().observe(getViewLifecycleOwner(), am -> {
if (am.isEmpty()) {
Log.d(TAG, "No barber.");
return;
}
String barberGreeting;
barberGreeting = am.get(0).bFirstName;
barberGreeting = barberGreeting.concat(" " + am.get(0).bLastName);
mTxtv_barberName.setText(barberGreeting);
});
getAllAppointments
returns an observer to mMasterAppointments
located in my ViewModel.
Although getAllAppointments
and getBarberFullName
are called within onViewCreated()
, one is able to access the pending values of mMasterAppointments
while the other is not. Why?
I don't want to do the logic in my Fragments onViewCreated
callback, so how can I wait on the pending mMasterApointmentData
in my ViewModel's getBarberFullName()
? Are there tools within LiveData
and ViewModel
that would aid me in this situation?
Use LiveData's Transformations class
when you need to perform calculations, display only a subset of the data, or change the rendition of the data.
First add a new String LiveData for BarberFullName
in the viewmdoel, and give it the value of transforming (mapping) the source LiveData mMasterAppointments
into the desired String:
val fullBarberName: LiveData<String> = Transformations.map(mMasterAppointments) { am ->
" ${am[0].bFirstName} ${am.get(0).bLastName}"
}
Now you can observe this String LiveData in your fragment, the way you in did your second snippet.
Note that the code I provided is in Kotlin, I use it nowadays. I hope you get it.