Step #4: Creating the Report

Now, we can work on some code to use Handlebars for converting our to-do items into a simple Web page.

First, let’s create a new package to hold our report code, since it is neither part of the UI nor part of the repository. Right-click over the com.commonsware.todo package in the java/ directory, choose “New” > “Package” from the context menu, fill in com.commonsware.todo.report for the package name, and press Enter or Return.

Then, right-click over the new com.commonsware.todo.report package in the java/ directory and choose “New” > “Kotlin File/Class” from the context menu. For the name, fill in RosterReport, and choose “Class” for the kind. Press Enter or Return to create the class, giving you:

package com.commonsware.todo.report

class RosterReport {
}

Next, open up res/values/strings.xml again and add this odd-looking string resource:

  <string name="report_template"><![CDATA[<h1>To-Do Items</h1>

<h2></h2>
<p><b>COMPLETED</b> &mdash; Created on: </p>
<p></p>

]]></string>

Handlebars uses syntax to indicate parts of a template that should be replaced at runtime with dynamic data. The dynamic data is represented by what Handlebars calls the “context” (which has nothing to do with Android’s Context class). In our case, the “context” will be a List of ToDoModel objects, representing the filtered items. Given that context:

Therefore, this template will create a chunk of HTML for each ToDoModel, with the <h1> heading at the top. We need the CDATA stuff so that Android does not try interpreting the HTML tags inside of this string resource.

Next, add a constructor to RosterReport that gives us a Context, our Handlebars object, and the appScope that we used in ToDoRepository:

class RosterReport(
  private val context: Context,
  engine: Handlebars,
  private val appScope: CoroutineScope
) {

Handlebars compiles a template like the one from our string resource into a Template object. So, add this property to RosterReport:

  private val template =
    engine.compileInline(context.getString(R.string.report_template))

This retrieves the string resource and has the Handlebars object compile it for us. We still need some code to actually use this template, which we will work on shortly.

Finally, add another line to koinModule in ToDoApp to allow us to inject our RosterReport where needed:

    single { RosterReport(androidContext(), get(), get(named("appScope"))) }

Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.