Assessment Tool Web App & SPA

Client & Server In Perfect Harmony

A contact of mine recently asked me if I could help build a 'simple' assessment tool for gathering user data and generating leads for his new business venture.

The application had to enable the development and delivery of multiple tailored online assessments with multi-choice questions leading to a helpful and informative results page.

This included both the administrative application to manage and maintain these assessments as well as the public facing user interface to allow people to participate in the assessments.

Example Assessment

Before we get into the what and how, there's an example assessment that you can participate in if you want to see the tool in action on the link below.

Example Assessment Link

Key Features

The application has several key features, these include;

  • Responsive, branded, mobile first interface for participation in assessments

  • Capture of email address per participant for use in marketing communications

  • Password protected custom administration interface allowing any number of assessments, each with any number of questions and each question with any number of answers

  • Explanatory results page for participants, including;

    • Customised descriptions for each answer given by the user

    • Imagery shown per answer in desktop view

    • Optional call to action to direct participants onwards to further learning or other resources

    • Permanent link for participant to return to their results

  • Email of results summary on completion of participation, including link to view online

  • Saving of participant details to secure Google Sheet for use in marketing communications

  • Custom alerting of key events and exceptions to Slack

  • Linting, documentation, unit tests and code coverage reports executed/generated via npm scripts

  • Client and server side code written using ES6 and transpiled via babel

  • Data storage utilising a MongoDb hosted service, mLab

  • Custom images uploaded to and accessed from Cloudinary

  • Hosting of the application, including use of a pipeline, in Heroku

Design

So based on an initial idea and single wireframe (see below) I helped to form the requirements and then develop, test and deploy the application over the course of 2 months, working during evenings and the odd weekend where possible.

The 'spec' described a fairly simple app, but the devil is in the detail!

The 'spec' described a fairly simple app, but the devil is in the detail!

The Architecture

The application consisted of a Node server application written using Express to administer the assessment data as well as an SPA written using React and Redux to deliver the participation user interface.

The application has just launched and is all set to allow the generation of new leads for the client as required. Aside from the financial benefits I further improved my technical skills and now have my first real world React application under my belt and in production (I have several demos and tutorial apps in my GitHub account but you can't beat using technology in anger to really learn about it).

Server

The Express app took longer than expected due to a rewrite early on in the development process, I figured that as my React app would be using ES6 syntax I should endeavour to use this in the back end application code too, so I rebuilt the Node app to use babel, along the way I also replaced Grunt with npm as my build tool, using this approach I managed to simplify the build process and write the app using the latest hipster features of JavaScript.

Huge props to this article for helping to clarify my thoughts on the pain of build tools, this is just one part of the JavaScript fatigue described here (another great post by the way) which can so easily drain your energy and enthusiasm for getting a project running right at the very start when you should be flying through the build. 

In my opinion build tools do very well at bringing the 2/3 or 3/4 point of a project (when it can sometimes begin to feel like a bit of a slog) forwards right to the very beginning, and that is no good for anyone's productivity or state of mind, hence npm to the rescue!

But I digress, back to the project.

Client

The SPA was written using React and Redux and made use of webpack as the build tool. Yes, yes I know what I just said, but there's really no getting away from tools when developing for the client as npm isn't an option. If it isn't webpack it would be browserify and Gulp or something equally as capable yet painful to learn. Luckily I found one of the many template webpack configs out there on the web that just works and I didn't need to suffer the pain of setting it up myself from scratch.

The SPA makes use of two main routes, one to serve the assessment and allow users to participate, handled by the path 'participate/:id', the second route is to persist the results of a user's participation, so they can return to this later (via a handy email containing this link that is sent on completion by the server), this is handled by the path 'participation/:id'.

The two main routes render the Assessment component for participation and the Results component for showing the results of a previous participation, each of these components is actually a container as they have access to the store. 

The components dispatch a small set of actions, which call RESTful API endpoints on the Express server application. There are two main endpoints; '/api/assessments' and 'api/participations', the responses from these endpoints in turn are picked up by the reducers to manipulate application state.

Integration

In order to integrate the SPA and Express app I added the output bundle.js that is the SPA to the Express server app and then loaded this onto a page rendered by Express using my current view engine of choice, Pug!

This workflow was quite nice as it allowed me to focus on one area at a time and not have to worry about integrating two different build tools and processes. It also meant that I could easily host the Express app in Heroku and use this to load and serve the SPA. 

Having delivered this application if I come across a similar build in the future I will definitely move the administration functionality out of Express and into React, not only would this prevent context switching between the two different architectures it would also speed up the development process. 

There are, however, good reasons for retaining Express in the stack, firstly to use as the server to host the SPA (whether or not this includes administrative functionality as well as the public UI, see above). Secondly to facilitate my tried and tested deployment and hosting process with Heroku. And finally it allows me to use JavaScript front to back, so that there is one language (and with the help of babel the latest syntax and features of that language) in the stack, which is tidy.

On this last point, the use of MongoDb as the data store also means that the data being manipulated is also JavaScript, (well JSON, but same difference), making the whole application homogenous and much easier to reason about and understand.

Summary

To wrap things up for now, the project presented a nice opportunity to learn about React and Redux and put this into practice, the integration with Express works really well and thanks to Heroku deployment and hosting is a breeze. Moving forwards I plan to take the knowledge gained from this project into my next application and develop an even better application next time. Thanks for reading, hope you found something interesting and/or useful here, bye for now.