This is a small web app that was created as part of applying to the MBTA software team. You can view it live at https://lourd.github.io/mbta-trains.
The requirements were minimal:
- Using the data at http://developer.mbta.com/lib/gtrtfs/Departures.csv
- Display it on a webpage, ideally using React
Pre-requisites: Git, Node.js, and npm installed on your machine.
git clone https://github.com/lourd/mbta-trains
cd mbta-trains
npm install
npm start
This project was bootstrapped with Create React App. This initialized the config/
and scripts/
directories, setting up the scaffolding and solid defaults for Babel, Webpack, linting with ESLint, and testing with Jest. I "ejected" from the core create-react-app
CLI so that I could bundle the CSV data file (see more below), as well add support for decorators and hot module reloading.
I initially tried to do requirement 1 dynamically, fetching the data when the page loaded. Unfortunately this wasn't possible because the origin server isn't configured to serve resources across origins. The 'Access-Control-Allow-Origin'
of the server is set to 'mbta.com'
, so any sites not hosted from there aren't able to fetch its resources. I did leave the implementation of this work in place though in fetchTrainData.js
.
My second attempt with the data was keeping it in a local file and importing it as a simple string. To do so I had to add to the webpack configuration, seen here.
I decided to write a simple CSV parser instead of using an open source library. Normally I wouldn't do that, but I decided that the context warranted doing so. I wrote a couple tests to verify its correctness, which you can run with npm test
after installing this program.
The app consists of 2 main components, TrainStatusBoard
and TrainStatus
. TrainStatusBoard
is decorated with 2 Higher-order components, withData
and withTime
. These provide encapsulation for fetching and managing state over time.
The layout of the board uses div
elements and flexbox positioning. An alternative would have been to use a table.
You may also notice that much of the styling is done in Javascript, applying object literals directly to the style
property of HTML elements. There's been a lively debate going on within the React community for some time about the tradeoffs of doing this. If I were to use CSS, or another CSS pre-processor, I would apply a className
property to the HTML components and write the styling in an external stylesheet that I could import
in the Javascript module.
I used the Moment.js library to do some date formatting. Aside from that, React, and ReactDOM, Babel, and Webpack there are no other top-level, 3rd party dependencies.