Solution 1 :
Have 3 variables in MyMapFragment keeping track of each view model request. Make all 3 variables null at fragment creation. When each viewModel request completes, change the corresponding variable.
Then make a helper method
private void setupData(){
if(variable1 == null || variable2 == null || variable3 == null){
return;
}
plotRoute(xxxxxx);
}
Then call setupData() in each of your viewmodel responses in place of the triple nested if statement checks
Problem :
I have an MVVM setup, with two fragments interacting via a ViewModel. My SourceFragment
is updating two MutableLiveData
LatLngs in the VM. My second is a MapFragment
in which I am drawing a route with the two LatLng LiveData. Both fragments are loaded as the Activity starts up. The SourceFragment updates the LatLngs. I need to wait for the map to load before requesting the route being plotted and I have a third MutableLiveData
Boolean that I update once the map is loaded. Currently the way I achieve this is by setting up three separate viewModel Observers for the three MutableLiveData
in my MapFragment
with a set of if statements to check when all three MutableLiveData
are set. I have a feeling that this could be done way better with something like MediatorLiveData
but I have not managed to find an example I can work off. Is MediatorLiveData
or something else applicable here?
My Source Fragment
viewModel.setPickupLocation(pickupLatLng);
viewModel.setDestinationLatLng(destinationLatLng());
My Map Fragment
@Override
public void onActivityCreated(@NonNull Bundle savedInstanceState) {
Log.d(TAG, "onActivityCreated: called");
super.onActivityCreated(savedInstanceState);
getCustomerOrDriverViewModel();
}
private void initViewModels() {
viewModel.getPickupLocation().observe(getViewLifecycleOwner(), new Observer<LatLng>() {
@Override
public void onChanged(@NonNull LatLng pickupLocation) {
Log.d(TAG, "onChanged: from onActivityCreated: called for getPickupLocation");
if(viewModel.getMapReady().getValue() != null) {
if(viewModel.getMapReady().getValue()) {
resetRoute();
setSingleMarker(pickupLocation);
if(viewModel.getDestinationLatLng().getValue() != null) {
plotRoute(viewModel.getDestinationLatLng().getValue(), pickupLocation);
}
}
}
}
});
viewModel.getDestinationLatLng().observe(getViewLifecycleOwner(), new Observer<LatLng>() {
@Override
public void onChanged(@NonNull LatLng destinationLatLng) {
Log.d(TAG, "onChanged: from onActivityCreated: called for getPickupLocation");
if(viewModel.getMapReady().getValue() != null) {
if(viewModel.getMapReady().getValue()) {
resetRoute();
if(viewModel.getPickupLocation().getValue() != null) {
plotRoute(destinationLatLng, viewModel.getPickupLocation().getValue());
}
}
}
}
});
viewModel.getMapReady().observe(getViewLifecycleOwner(), new Observer<Boolean>() {
@Override
public void onChanged(@NonNull Boolean ready) {
Log.d(TAG, "onChanged: from onActivityCreated: called for getMapReady");
if(ready) {
if(viewModel.getPickupLocation().getValue() != null && viewModel.getDestinationLatLng().getValue() != null) {
Log.d(TAG, "onChanged: from onActivityCreated: called for getMapReady: plotting route");
resetRoute();
plotRoute(viewModel.getDestinationLatLng().getValue(), viewModel.getPickupLocation().getValue());
}
}
}
});
}
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
viewModel.setMapReady(true);
}
});
My ViewModel
private MutableLiveData<LatLng> pickupLocation = new MutableLiveData<>();
private MutableLiveData<LatLng> destinationLatLng = new MutableLiveData<>();
private MutableLiveData<Boolean> mapReady = new MutableLiveData<>();
public void setPickupLocation(LatLng input) {
Log.d(TAG, "setPickupLocation: ");
pickupLocation.setValue(input);
}
public void setDestinationLatLng(LatLng input) {
Log.d(TAG, "setPickupLocation: ");
destinationLatLng.setValue(input);
}
public void setMapReady(Boolean input) {
Log.d(TAG, "setPickupLocation: ");
mapReady.setValue(input);
}
public MutableLiveData<LatLng> getPickupLocation() {
Log.d(TAG, "getPickupLocation: ");
return pickupLocation;
}
public MutableLiveData<LatLng> getDestinationLatLng() {
Log.d(TAG, "getDestinationLatLng: ");
return destinationLatLng;
}
public MutableLiveData<Boolean> getMapReady() {
Log.d(TAG, "getMapReady: ");
return mapReady;
}