To be able to create an order we first need to create an attendee with whom we can associate an order. Let’s see how in Open Event Android App we are creating an attendee.
We are loading the event details from our local database using the id variable. Since only logged in users can create an attendee, if the user is not logged in then the user is redirected to the login screen. If any errors are encountered while creating an attendee then they are shown in a toast message to the user. When the user clicks on the register button a POST request is sent to the server with the necessary details of the attendee. In the POST request we are passing an attendee object which has the id, first name, last name and email of the attendee. The ticket id and event id is also sent.
attendeeFragmentViewModel.loadEvent(id) if (!attendeeFragmentViewModel.isLoggedIn()) { redirectToLogin() Toast.makeText(context, "You need to log in first!", Toast.LENGTH_LONG).show() } attendeeFragmentViewModel.message.observe(this, Observer { Toast.makeText(context, it, Toast.LENGTH_LONG).show() }) attendeeFragmentViewModel.progress.observe(this, Observer { it?.let { Utils.showProgressBar(rootView.progressBarAttendee, it) } })
attendeeFragmentViewModel.event.observe(this, Observer { it?.let { loadEventDetails(it) } }) rootView.register.setOnClickListener { val attendee = Attendee(id = attendeeFragmentViewModel.getId(), firstname = firstName.text.toString(), lastname = lastName.text.toString(), email = email.text.toString(), ticket = ticketId, event = eventId) attendeeFragmentViewModel.createAttendee(attendee)
We are using a method called loadEvent in the above code which is defined in the View Model let’s have a look. We are throwing an IllegalStateException if the id is equal to -1 because this should never happen. Then we are fetching the event from the database in a background thread. If we face any errors while fetching the event we report it to the user
fun loadEvent(id: Long) { if (id.equals(-1)) { throw IllegalStateException("ID should never be -1") } compositeDisposable.add(eventService.getEvent(id) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ event.value = it }, { Timber.e(it, "Error fetching event %d", id) message.value = "Error fetching event" })) }
This method is used to create an attendee. We are checking if the user has filled all the fields if any of the fields is empty a toast message is shown. Then we send a POST request to the server in a background thread. The progress bar starts loading as soon as the request is made and then finally when the attendee has been created successfully, the progress bar stops loading and a success message is shown to the user. If we face any errors while creating an attendee, an error message is shown to the user.
fun createAttendee(attendee: Attendee) { if (attendee.email.isNullOrEmpty() || attendee.firstname.isNullOrEmpty() || attendee.lastname.isNullOrEmpty()) { message.value = "Please fill all the fields" return } compositeDisposable.add(attendeeService.postAttendee(attendee) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe { progress.value = true }.doFinally { progress.value = false }.subscribe({ message.value = "Attendee created successfully!" Timber.d("Success!") }, { message.value = "Unable to create Attendee!" Timber.d(it, "Failed") })) }
This function sends a POST request to the server and stores the attendee details in the local database.
fun postAttendee(attendee: Attendee): Single<Attendee> { return attendeeApi.postAttendee(attendee) .map { attendeeDao.insertAttendee(it) it }
This is how the attendee details are inserted into the local database. In case of a conflict the attendee object gets replaced.
@Insert(onConflict = OnConflictStrategy.REPLACE) fun insertAttendee(attendee: Attendee)
Resources
- ReactiveX official documentation : http://reactivex.io/
- Vogella RxJava 2 – Tutorial : http://www.vogella.com/tutorials/RxJava/article.html
- Androidhive RxJava Tutorial : https://www.androidhive.info/RxJava/