Firepoll – Real time poll app sample


2014 is going to be the year of the real time web and the combination of AngularJs and Firebase gonna be the shoehorn that will bring in to it a lot of developers.

While discussing this subject IRL last week, I realized I need to have a nice sample for a classic-basic web feature – with a real time twist. So I set down for a whole two hours and wrote this little sample app for real time polls.
What do you need real time polls for? Well, it can be really nice in a high traffic site, lets say a news site during the elections, and it can be a nice widget in any site, since it can take as little as 10 minutes to turn a poll app into a real time poll app.

Working sample @
Download code @



Concept of Angularfire

Angularfire is your firebase service for AngularJs. After linking the required files, basically what you do is:
create a firebase object

    var myObject = new Firebase("");

and your object is automagically linked to any other connected user at the same time. That’s all (well, basically).
So, if you have a poll object with the poll options, you just need to connect it to the firebase database, and you have a real time poll!

In this sample, there are a few minor complications due to the google charts api. Check out the remarks in the code to see what it took.

It's Alive!


So what do we have here?

I took an angularJs google charts directive, and built a controller that turns it real time. In a real app the Firebase connection should be in a service, as such the poll creation methods, but here i flattened the architecture to make it simpler to read and understand (hopefully).

The dependencies are:

In the sample there are two parts – poll creation, and poll voting. Both are on the same view.
You can use any, and read the remarks in the code for the full info.

please note – since it’s a sample, there are no limitations, authentication or any other obstacle. In a real app you will add authentication and voting limitations. Both are done both in the clients side and on the server side using the firebase security rules. I may add a part about toughening and security rules, if there will be a demand.

HTML code for sample

Create a poll

<h3>Create a poll</h3>

                            <h4>poll's question</h4>

                            <input type="text" ng-model="" placeholder="Poll's name" class="w200"><br>

                            <h4>Poll's answers</h4>

                            <div ng-repeat="option in pollForm.options track by $index">
                                Option {{ $index+1 }} <input type="text" placeholder="option"
                                <button class="btn" ng-click="removeOption($index)"> - </button>
                            <button class="btn blue" ng-click="addPollOption()">+ Add answer</button>
                            <button class="btn green" ng-click="pollCreate()"> << Create the poll >> </button>

Select a poll from the list

 <h3>Select an existing poll</h3>
                        <div ng-show="load">
                            ... Loading
                        <div ng-show="!load">
                        <button ng-repeat="(key, value) in polls track by $index" ng-click="selectPoll(key)"
                                class="pollSelectBtn btn yellow">
                            {{ }}

Show the selected poll

   <div ng-if="selectedPoll">
                        <div google-chart chart="chart">


                            <span class="voteDiv" ng-repeat="data in selectedPollOptions">
                                <button class="btn btn-primary" ng-click="vote($index)">{{ data[0] }}</button>
                                Other: <input ng-minlength="1" type="text" ng-model="vote.optionOther" class="w200"><button class="btn green" ng-click="addOther()">Add and Vote</button>


App Controller – where the job is done

angular.module('firepollapp').controller('mainCtrl',function($scope, $firebase){

    // firebase
   // Set YOURAPP - to your firebase address
    var ref = new Firebase("");
    // Automatically syncs everywhere in realtime
    $scope.polls = $firebase(ref);

    // create basic objects
    $scope.selectedPoll = '';
    $scope.selectedPollOptions = [];
    $scope.load = true;

    Select a poll from the poll's list
    moveing the poll data to a separate object from the firebase object
    It gives more flexibility with it's construct and data types
    (for example - firebase will return values as string type, while google charts has to have them as numbers
        - note the parseInt on the values)
    It does adds a need to create a watcher for any incoming changes.

    Also, used a separate object for poll voting options ($scope.selectedPollOptions) for some more flexibility

    // Loading poll from the list (in the firebase object)
    $scope.selectPoll = function(id){
        if (id){ // don't run on initial watch
            // hold selected polls id
            $scope.selectedPoll = id;
            // clean poll options object
            $scope.selectedPollOptions = [];
            // clean chart data
   = [];
            // populate chart's title from the firebase object
            chart1.options.title = $scope.polls[id].name;
            // google charts require column names in the first dataset row.
            // will give some little pain later
            // populate with the values from firebase
            // don't forget to parseInt the values or it will not draw the chart
            for (i=0; i&lt;$scope.polls[id].options.length; i++)
                if ($scope.polls[id].options[i][0] &amp;&amp; $scope.polls[id].options[i][1])
                    // if you don't have a numeric value - reset the value
                    var val = parseInt($scope.polls[id].options[i][1]);
                    var option = [$scope.polls[id].options[i][0], val];
                    // push data from the firebase object to the chart data object
                    // push the options from the firebase object to the poll options object
            $scope.chart = chart1;

    // deep watch for the firebase object, to have the chart update in real time, when the object updates
    // needed to handle the object separation
    $scope.$watch('polls', function(){

    // data loaded from firebase - angularfire event
    // use to switch the loader off
    $scope.polls.$on("loaded", function() {
           $scope.load = false;

    // vote on poll
    $ = function(index){
        // calc new total
        // add +1 to index to compensate for first row in chart data not being poll options
        index ++;
        if (angular.isNumber([index][1] ))
            newTotal = parseInt([index][1]) + 1;
            newTotal = 1
        // move index one back
        // update value in the firebase object
        $scope.polls[$scope.selectedPoll].options[index][1] = newTotal;
        // save changes to the object and the remote firebase

    // Add "other" option to selected poll
    $scope.addOther = function(){
        if (${
            // add new option to the firebase object with 1 vote
            $scope.polls[$scope.selectedPoll].options.push([$, 1]);
            // save the firebase object - update firebase remote
            // clear the "other" form field
            $ = '';

    //////   google chart basic object
    var chart1 = {};
    chart1.type = "PieChart";
    // chart options. use google chart reference for more info
    // pie chart:
    chart1.options = {
        title: '',
        displayExactValues: true,
        pieSliceText: 'percentage',
        width: 400,
        height: 300,
        is3D: true,
        slices: {}

    ///  create poll - form methods
    // reset the form
    $scope.resetForm = function(){
        $scope.pollForm = {};
        $scope.pollForm.options = [];
    // call one reset on load for object declaration
    // Add a poll option to the creation form
    $scope.addPollOption = function(){
        $scope.pollForm.options.push(['', '0']);
    // remove pull option from the form
    $scope.removeOption = function(index){

    // Create a new poll
    $scope.pollCreate = function(){
        // add to poll to the Firebase object - this will update it at the server
        // check for empty options
        for (i=0; i&lt;$scope.pollForm.options.length; i++){ // make sure no empty options if (angular.isUndefined($scope.pollForm.options[i][0]) || $scope.pollForm.options[i][0]=='') {$scope.pollForm.options.splice(i,1)} } if ($ &amp;&amp; ($scope.pollForm.options.length&gt;0))
            // add the new form to the firebase object. it will be updated automagically in firebase
            // reset the poll creation form


Working sample @
Download code @


Leave a Reply

Your email address will not be published. Required fields are marked *