Source Code on Git Hub


Summary

A frontend chat room ‘style’ application.

Welcome to Chit Chat, an application that sends and receives messages in real time using Firebase and AngularJS.

       Spec:

       HTML(5)
       CSS(3)
       UI Bootstrap
       JavaScript
       AngularJS
       Firebase
       AngularFire API
       Git & Git Hub

This is not supposed to be a finished product but was part of the learning process of my web development course with Bloc covering core programming topics.


My Role

To create this application as a sole developer, working remotely, completing specific tasks outlined by Bloc.

I was provided with User Stories 1 that I had to comprehend and complete.

  • As a user, I want to see a list of available chat rooms
  • As a user, I want to create chat rooms
  • As a user, I want to see a list of messages in each chat room
  • As a user, I want to set my username to display in chat rooms
  • As a user, I want to send messages associated with my username in a chat room

After studying the user stories, I was able to sketch out some wireframes2 of the overall vision I had for the look of the application.

I used Git to maintain a local repository of the project and a remote repository on GitHub, and used feature branches to ensure a smooth workflow and secure version control.


Problems

Naturally, there were numerous challenges throughout this project, including infuriating rewarding debugging sessions. Whilst impossible to list them all, I will document a few to give you an idea of some of the problems I faced and how I set about solving them.

  1.   The user would like to see a list of available chat rooms when they visit the site, can I query        these chat rooms from Firebase and display them on the frontend to the user?

  2.  Initiate a modal on the frontend, using UI Bootstrap, for a user to create a new chat room.

          alt text

  3.  Efficiently store a users username so you can display it every time they visit the site and write something in a chat room.


Solutions

  1.  In my opinion the crux of this problem was the querying of Firebase. I felt that once I had that in place, to actually display the information on the frontend would be relatively straightforward.

In order to thoroughly test whether I was making a successful query from Firebase, I manually added some rooms to the Firebase database. (At a later stage the user would be adding these rooms via the frontend).

The data structure looked like this:

bloc-chat-1482f
|__rooms
    |__1:"room1"
    |__2:"room2"
    |__3:"room3"

With this out the way I was ready to start building my query.

I created a Room factory in Angular that would define all Room-related API queries. I created a reference to my Firebase database inside, and injected the $firebaseArray service provided by AngularFire:

  function Room($firebaseArray) {
    var Room = {};
    var ref = firebase.database().ref().child("rooms");
    var rooms = $firebaseArray(ref);

    Room.all = rooms;

    return Room;
  }

Using the $firebaseArray service ensured the data returned would be an array and therefore easier to manipulate using JavaScript.

The Room factory within my application:

(function() {
  function Room($firebaseArray) {
    var Room = {};
    var ref = firebase.database().ref().child("rooms");
    var rooms = $firebaseArray(ref);

    Room.all = rooms;

    return Room;
  }

  angular
    .module('blocChat')
    .factory('Room', ['$firebaseArray', Room]);
})();

Now I was able to query the rooms I went on to create a template and controller to display the rooms to the user.


2.  Initially, this seemed like one of the more straightforward tasks of the whole project. After all I’ve used bootstrap before, but it turned out to be far from it! (welcome to web development).

This one left me stumped for days.

I trawled through the doccumentation time and time again, attempted to use every resource I had at my disposal but for one reason or another I couldn’t get my modal to work.

I would later understand that the reason I found this so difficult was because I didn’t know what a JavaScript promise was and once this concept was understood, that filled in (nearly) all the missing gaps.

However, at the time, I reached out to a code mentor on the course and together we pair-programmed to get the modal up and running.

The reason I wanted to write about this, is because this actually became a really helpful learning curve for me in the end (but more on that later in the conclusion).

The generic steps I did take to get this done were:

  • I included the UI Bootstrap library via a <script> tag on index.html.
  • I injected the module into my Angular app’s dependency array
  • I created a separate controller for the modal
  • I injected the proper dependencies for using the modal (see the UI Bootstrap documentation)
  • I added methods to open, close and submit data to Firebase from the modal

    3.  My approach to this was to store the username on the clients browser using cookies (insert token joke about cookies).

This is by far not the only approach and arguably not the best. In my Ruby on Rails applications I store this type of data in the database and utilise browser sessions with users signing in.

However, this was part of learning and getting to grips with cookies and how they can be used to good affect.

Thankfully, Angular has an external module for including the services and methods associated with cookies.

Most importantly, I would have to be able to check if the user had a cookie which included a current username, if they did, I would use that username, if not I would need to prompt them to enter a username and create a cookie to store that in. Welcome back to the dreaded modal:

(function(){

    function BlocChatCookies($cookies, $uibModal){ //this function will fire when angular app runs (user opens site)
        var currentUser = $cookies.get('blocChatCurrentUser'); //returns the value of this cookie key
        if(!currentUser||currentUser===""){ 
            var modalInstanceObject = $uibModal.open({
                animation: false,
                keyboard: false,
                templateUrl: '/templates/usernameModalInstance.html',
                controller: 'UsernameModalInstanceCtrl',
                controllerAs: 'UsernameModalInstance'
            });

            modalInstanceObject.result.then(function(username){
                $cookies.put("blocChatCurrentUser", username);
            });
        }
    }

    angular
        .module("blocChat")
        .run(["$cookies", "$uibModal", BlocChatCookies]); //on the ngCookies module there is a $cookies service to help us interact with cookies

})()




Results

Given the frontend nature of the project I was able to test thoroughly using the browser, chrome dev tools and the DOM.

I was able to achieve the desired outcomes of the course project. However, given this was only for learning purposes there are naturally things that were not required, which for production purposes would need to be implemented.

Feedback from my code mentor was positive.


Conclusion

This was the final frontend project with Bloc and with this in mind I was given very little support to complete the tasks at hand and was challenged to draw on my own initiative and external resources.

What surprised me the most whilst working through this project was the rigidity of the framework AngularJS. In full honesty I did not find the framework to be intuitive and although it ships with some great features, as a beginner user I would be less inclined to pursue a project using Angular.

This has, however, given me the desire to learn a different framework called React which thankfully is becoming very popular and I have access to great learning materials through Bloc. Hopefully, in the near future I can add this to my skill set and I will find React to be far more efficient and user friendly.

The biggest learning curve for me on this whole project was hitting a brick wall. I must have spent days trying to get UI Bootstraps modal to work on my site and shouting at inanimate objects (such as my pc) were becoming common place. However, what I did learn, was that it’s really important to reach out to others and sometimes problem-solving with someone else can help you to learn someting new or see something from a different angle. In this instance the code mentor introduced me to a new concept in JavaScript promises, and I would definetly collaborate far quicker in the future.

Moving forward, I would like to learn React in the future, especially as I have access to the learning material through my Bloc curriculum. And even though I do work remotely I think that I would be far more inclined to pair-programme with others to enhance collaboration and problem-solving.









1: A user story is a tool used in Agile software development to capture a description of a software feature from an end-user perspective. The user story describes the type of user, what they want and why. A user story helps to create a simplified description of a requirement.

2: Wireframing is a way to design a website service at the structural level. A wireframe is commonly used to lay out content and functionality on a page which takes into account user needs and user journeys. Wireframes are used early in the development process to establish the basic structure of a page before visual design and content is added.