June Hackday - Team KASX (Part 1)

Last June we had a Hackday at Kogan.com! This Hackday’s focus on displaying information and providing useful alerts using hardware and software. Teams were asked to express something they find interesting through one of the available mediums.

In this 3 part series Simon, Alec & Jake will talk a little bit about how each team went.

Team KASX

Our team was given the task of creating an app using React Native for a mobile device that could be used to display information such as Kogan’s stock price. This would then be attached behind a cutout in a poster that is displayed in one of the office meeting rooms. Below is the mockup we created for our idea - the poster cutout is in the tram route display, so space/size would be an issue!

mvp.png

Planning

Before beginning, we needed to choose a platform and framework. The first was an easy decision; we chose to build an Android app, as our team involved a mix of Mac and Linux users and so we would not all be able to have a full development setup for iOS development.

This was the first time any of our team had used React Native so we decided to use the starter package ‘create-react-native-app’ (CRNA) suggested by Facebook team in the React Native documentation.

Splitting up the tasks

We had a team of 4 and broke the work into 3 areas to avoid stepping on each others toes too much.

  • Visual layout and style - getting the look and feel of the app to match the required positioning and style of the poster

  • Data Feed - Finding suitable APIs that we could consume for different screens

  • Tooling and Deployment - Getting the build environment working and figuring out how to deploy a RN app

Create React Native App + Expo

The underlying platform used by any app based on CRNA is a tool called Expo. This is a toolchain that simplifies some of the React Native workflows such as a shared configuration file for both mobile platforms, easy code push, remote live reload and debugging during development for devices not on the same network.

Using CRNA and Expo made it very easy to get a hello world app up and running. Our visual virtuoso soon had an app running with placeholder data that looked vaguely like our simple mockup. We also found and integrated a dot-matrix font to give us a more authentic text style

image.png

However we quickly began to encounter some niggling issues as we added functionality to the app. The worst of these were related to the live reload. We found that as we made changes to the app, it was not always obvious that the app had updated correctly. The tooling was telling us that it had updated, but when we checked the physical or virtual test device, we often found it had not actually changed. This grew more frustrating as the hours passed; we found ourselves not knowing if a change didn't work due to bugs in the code or due to the app not reloading; we were constantly force closing the app and restarting it.

Despite the issues, the real benefit of Expo for our hackday challenge was the build and deployment process. When you start an Expo build, it is actually created remotely and stored in S3 (which Expo uses for code-push and other features). Once an Expo account had been created, it was simply a matter of logging in and starting the build using the CLI

exp login -u myusername -p mysupersecretpassword
exp build:android

For our purposes, we didn’t need to publish the app to an app store, so we downloaded it manually from S3 using wget and pushed to a connected device manually using adb

wget https://exp-shall-app-assets.s3-us-west-1.amazonaws.com/.apk -O my-great-app.apk
adb install my-great-app.apk

This was quite a smooth process thanks to our deployment doyen, who documented and tested this, ensuring that we were well positioned to showcase our app at the end of the day.

Berk! Feed Me!

While the front-end team toiled away, our designated data dictator began searching for a suitable API for that was publicly accessible and free. We found an NPM package asx-data but given the simplicity of our requirements ended up grabbing the underlying endpoint https://www.asx.com.au/asx/1/share/ and using it in a simple fetch call. This returned all of the information we needed, such as last price and change %, previous day price and change %, etc.

This API was integrated into a simple React container component that fetched the data, updated state and then polled for changes at a slow interval.

  componentDidMount() {
    // This will also set the initial data
    this.getStockDataAndUpdate()
    this.interval = setInterval(() => this.getStockDataAndUpdate(), POLL_TIME)
  }
  getStockDataAndUpdate = () => {
    getStockData()
      .then(res => res.json())
      .then((data) => {
        this.setState({
          price: data.last_price,
          changeInPercent: data.change_in_percent,
          previousDayPercentage_change: data.previous_day_percentage_change,
          changePrice: data.change_price,
        })
      }).catch((err) => {
        console.log(err)
      })
  }

Once this was up and running, our data feed fiend began to tackle a practical stretch-goal set by the team: Displaying the time until the next 109 tram departure from Montague St stop, a popular transport route for many Kogan employees. As it happens, Yarra Trams have their own publicly accessible API that has quite a lot of data available and was perfect for our needs.

const TRAM_SCHEDULE_API =  ‘https://yarratrams.com.au/base/tramTrackerController/TramInfoAjaxRequest’
const TRAM_STOP = 2709
export function getTramTimeAway(){
    return fetch(TRAM_SCHEDULE_API, {
        body: `StopId=${TRAM_STOP}&Route=&LowFloorOnly=False`,
        headers: {
            'content-type': 'application/x-www-form-urlencoded',
        },
        method: 'POST',
    })
}

Outcome

By the end of the day, we had been able to produce an Android app that rotated between screens displaying live ASX pricing data for the Kogan stock ticker (KGN) and upcoming 109 tram departure times. We were even able to showcase this on a real device.

Our remaining follow-up tasks from the day were:

  1. Get another copy of the chosen photo blown up to the right scale and dimensions

  2. Mount the selected device to the back of the photo frame

  3. Hang it a nearby meeting room for all to see!