Showing Order Details in Eventyay Organizer Android App

In Open Event Organizer App, the organizer was not able to view the details for the Orders received from attendees for his/her events. So in this blog we’ll see how we implemented this functionality in the Orga App.

Specifications

There is a fragment showing the list of all orders for that event. The user will be able to click on order from the list which will then take the user to another fragment where Order details will be displayed. We will be following MVVM architecture to implement this functionality using REST API provided by Open Event Server. Let’s get started.

Firstly, we will create Order Model class. This contains various fields and relationship attributes to setup the table in database using RazizLabs DbFlow annotations.

Then, We will make a GET request to the server using Retrofit 2  to fetch Order object.

@GET(“orders/{identifier}?include=event”)
Observable<Order> getOrder(@Path(“identifier”) String identifier);

The server will return the Order details in form of a Order object and then we will save it in local  database so that when there is no network connectivity then also we can show data to the user and user can refresh to fetch the latest data from network. The network observable handles fetching data from network and disk observable handles saving data in local database.

@NonNull
@Override
public Observable<Order> getOrder(String orderIdentifier, boolean reload) {
Observable<Order> diskObservable = Observable.defer(() ->
repository
.getItems(Order.class, Order_Table.identifier.eq(orderIdentifier)).take(1)
);

Observable<Order> networkObservable = Observable.defer(() ->
orderApi.getOrder(orderIdentifier)
.doOnNext(order -> repository
.save(Order.class, order)
.subscribe()));

return repository
.observableOf(Order.class)
.reload(reload)
.withDiskObservable(diskObservable)
.withNetworkObservable(networkObservable)
.build();
}

Now, we will make a Fragment class that will bind the layout file to the model in the onCreateView method using DataBindingUtil. Further, we will be observing on ViewModel to reflect changes of Order, Progress and Error objects in the UI in the onStart method of the Fragment.

public class OrderDetailFragment extends BaseFragment implements OrderDetailView {

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.order_detail_fragment, container, false);

orderDetailViewModel = ViewModelProviders.of(this, viewModelFactory).get(OrderDetailViewModel.class);

return binding.getRoot();
}

@Override
public void onStart() {
super.onStart();
setupRefreshListener();

orderDetailViewModel.getOrder(orderIdentifier, eventId, false).observe(this, this::showOrderDetails);
orderDetailViewModel.getProgress().observe(this, this::showProgress);
orderDetailViewModel.getError().observe(this, this::showError);
}
}

Next, we will create OrderDetailsViewModel.This is the ViewModel class which interacts with the repository class to get data and the fragment class to show that data in UI.

Whenever the user opens Order details page, the method getOrder() twill be called which will request an Order object from OrderRepository, wrap it in MutableLiveData and provide it to Fragment.

Using MutableLiveData to hold the data makes the data reactive i.e. changes in UI are reflected automatically when the object changes. Further, we don’t have to worry handling the screen rotation as LIveData handles it all by itself.

  public LiveData<Order> getOrder(String identifier, long eventId, boolean reload) {
if (orderLiveData.getValue() != null && !reload)
return orderLiveData;

compositeDisposable.add(orderRepository.getOrder(identifier, reload)
.compose(dispose(compositeDisposable))
.doOnSubscribe(disposable -> progress.setValue(true))
.doFinally(() -> progress.setValue(false))
.subscribe(order -> orderLiveData.setValue(order),
throwable -> error.setValue(ErrorUtils.getMessage(throwable))));

if (!reload) {
getEvent(eventId);
}

return orderLiveData;
}
}

References

  1. Codebase for Open Event Orga App https://github.com/fossasia/open-event-orga-app
  2. Official documentation for LiveData Architecture Component https://developer.android.com/topic/libraries/architecture/livedata
  3. Official Github Repository of Retrofit  https://github.com/square/retrofit
  4. Official Github Repository for RxJava https://github.com/ReactiveX/RxJava