Building a simple SRI list-details application

Sri (Scalajs React interface) is a library based on react-native, that allows to use scalajs programming language to build native Android and iOS apps. In this article I’ll show You how to build a simple app using sri. This app will be a simple stack-navigation app containing list and details views. Let’s get started.

First thing you need to do is to set up your environment. Those are the things you need to get started(You need homebrew to run following commands:, If you already have those installed you can skip this part):

brew install node
brew install watchman
brew install sbt
npm install -g react-native-cli

Next you need to create a new project. To do that follow instructions on:
After you have created your project and have packager running use sbt ~ios:devand sbt ~android:devcommands to build it for both platforms. Those commands also run compiler that listen for any scala source files changes and compile it. When you’re developing You should keep one running (depending on platform you’re running) so changes you’ve made in the code are automatically builded and reflected in the app.

Using react-native run-iosor react-native run-androidyou can run your app to see if it’s working. It requires to have Xcode / Android Studio with AVD installed (for instructions on how to set up SDK and simulators see: It may be required to manually run simulator.

If you’re getting ":CFBundleIdentifier", Does Not Existerror while running on iOS, it may help to run react-native upgrade in the root directory of the project.
If you’re getting Application has not been registerederror, open src/main/scala/…/MobileApp.scala file and in line AppRegistry.registerComponent("main", () => component)make sure that in the place of “main” is the name of Your app.

At the beginning create a new scala file called ListScreen. We’ll use it to display a list of people. Class ListScreen must inherit from NavigationScreenComponentNoPS class so it can be display as a view. It should look like:

class ListScreen extends NavigationScreenComponentNoPS {
  def render() = {
    		View(style = GlobalStyles.wholeContainer)()

Right now main view in our app is AboutScreen. It’s determined in package.scala file. To change default view modify line:

registerStackScreen[AboutScreen](navigationOptions = NavigationStackScreenOptions(title = "About"))


registerStackScreen[ListScreen](navigationOptions = NavigationStackScreenOptions(title = "List"))

From now on when we run our app, it will display ListScreen view which is currently empty. To display a list, first thing we need to do is to create a model class describing a Person object. It should look like this:

trait Person extends js.Object {
 	val firstName: String
  val lastName: String
  	val description: String
  	val age: Int
  	val key: Int

Each object on the list need to have a key field unique to each object. Create an array with a example data which will be used to populate our list.

val persons = js.Array(
    	new Person {
      		override val firstName: String = "John"
      		override val lastName: String = "Smith"
      		override val description: String = "Lorem ipsum dolor sit amet, ius ad pertinax oportere accommodare, an vix civibus corrumpit referrentur."
      		override val age: Int = 30
      		override val key: Int = 0
    	new Person {
      		override val firstName: String = "Steve"
      		override val lastName: String = "Cooper"
      		override val description: String = "Te nam case ludus inciderint, te mea facilisi adipiscing."
      		override val age: Int = 28
      		override val key: Int = 1
    	new Person {
      		override val firstName: String = "Katie"
      		override val lastName: String = "Dixon"
      		override val description: String = "Sea id integre luptatum. In tota sale consequuntur nec. Erat ocurreret mei ei."
      		override val age: Int = 24
      		override val key: Int = 2

Define styles

object styles extends InlineStyleSheetUniversal {
  	import dsl._

  	val headerFooter = style(
    		height := 30,
    		width := 100,
    		alignSelf := "center",
    		alignItems := "center",
    		justifyContent := "center"
  	val separator = style(
    		height := StyleSheet.hairlineWidth,
    		backgroundColor := "gray"
  	val item = style(
    		flex := 1
  	val itemRow = style(
    		flexDirection := "row",
    		padding := 10,
    		backgroundColor := "#F6F6F6"
  	val text = style(
    		flex := 1

Create PersonComponent which will represent a single row of the list

class PersonComponent extends ComponentP[PersonComponent.Props] {
  	def render() = {
      			onPress = () => props.onPress(props.item.key),
      			style = styles.item)(
      			View(style = styles.itemRow)(
        			Text(style = styles.text,
          				numberOfLines = 2 )(
          				s"${props.item.firstName} ${props.item.lastName}\n${props.item.age}"

object PersonComponent {
  	case class Props(item: Person,
    onPress: Int => Unit)
  	def apply(props: Props) = CreateElement[PersonComponent](props)

Define separator, header and footer

val SeparatorComponent = View(style = styles.separator)(null)
val HeaderComponent = ViewC(
  View(style = styles.headerFooter)(
   		TextC("LIST HEADER")

val FooterComponent = ViewC(
    	View(style = styles.headerFooter)(
      		TextC("LIST FOOTER")

Define functions for rendering and onPress handling

private def renderItem(info: ListItem[Person]) = PersonComponent(
    	PersonComponent.Props(item = info.item, onPress = pressItem)

private def pressItem(index: Int) = {

Add a list to render method:

def render() = {
      		data = persons,
      		ListHeaderComponent = () => HeaderComponent,
      		ListFooterComponent = () => FooterComponent,
      		ItemSeparatorComponent = () => SeparatorComponent,
      		debug = false,
      		horizontal = false,
      		disableVirtualization = false,
      		renderItem = renderItem _

Now save changes, and if you’ve done all steps correctly, the app should display a list of people, but when you tap on someone, nothing happens. To add details, let’s create a new file named DetailsScreen. DetailsScreen class just like ListScreen class must inherit from NavigationScreenComponent and contains render method, but this time, we want to pass a Person which details should be displayed. You must declare, that during creation of a new instance of DetailsScreen.

class DetailsScreen extends NavigationScreenComponentP[Person] {
  	def render() = {
      			TextC(s"${params.get.firstName} ${params.get.lastName}\n${params.get.age}\n${params.get.description}")

Each view must be registered. Add below line to package.scala file, just after registration of ListScreen

registerStackScreen[DetailsScreen](navigationOptions = NavigationStackScreenOptions(title = "Details"))

To open details by clicking on a person on the list modify pressItem method like so

private def pressItem(index: Int) = {

Now your app displays a list, and when you tap on a person it shows details of that person.