This article is part of our series of tutorials ‘Building Realtime Applications’, updated on a regular basis.

When I browse the web, there’s nothing less helpful than a progress bar that doesn’t give me any feedback on what’s actually happening. This usually happens when the application is working on a task that needs some time to process, like a data/file import or provisioning an account.

This usually leaves me, the poor user, wondering if something went wrong with the app. Should I wait 5 more minutes before I refresh the page? Did I do something wrong? As a user, this is a rather frustrating experience.

To cope with this problem and improve the user experience in your app, you should use a real-time progress bar. Luckily for you, Pusher makes it incredibly easy for your to build one!

The Problem

For this demo, we’ll use the all too common problem of creating an account and the app needs to provision the account with some kind of data. You can really use this logic everywhere in your app to improve the user experience.

Before going forward, check out end product of this tutorial. All of the code is available on Github.

Realtime progress bar

As Easy As 1, 2, 3

To keep it short and sweet, I’ll be using Sinatra for the server side logic but this will work with any kind of server side framework or language. Also, make sure to have a Pusher account handy – it is free, after all!

Setting things up on the server side is pretty trivial; you’ll need your Pusher app keys, secret (keep it that way!) and ID to instantiate Pusher on the server.

The key thing to notice in the server code below is that we are using Pusher.trigger to communicate our message and progress to the client through the pusher_channel we provided. Use this throughout your background tasks to communicate to your user and improve his/her experience. Finally, you need to trigger an event on that channel, in our case we just have one that we name update.

In our example, each account creation process needs its own channel because you don’t want to send the messages to everyone currently creating accounts. Don’t worry about creating a lot of channels: Pusher provides unlimited channels on all plans.

There are multiple ways of creating unique channels for each user. You can generate a unique string when rendering the template, use the Unique User Identifier of the metrics tool you are using (Mixpanel, Kissmetrics, Google Analytics, etc) or just generate it client side with Javascript and submit it with the form.

...

# Post endpoint that creates account with real-time magic
post '/create_account_with_realtime' do
  name = params[:name]
  uid = params[:uid]
  pusher_channel = "signup_process_#{uid}"
  fake_background_job(name, pusher_channel)
end

def fake_background_job(name, pusher_channel) # Faking a background job
  Pusher.trigger(pusher_channel, 'update', {message: "Starting provisioning your account #{name}", progress: 30 })
  sleep(3)
  Pusher.trigger(pusher_channel, 'update', {message: "Sorry #{name}, It's taking a bit of time...", progress: 30 })
  sleep(2)
  Pusher.trigger(pusher_channel, 'update', {message: "almost there, adding the demo data...", progress: 60 })
  sleep(4)
  Pusher.trigger(pusher_channel, 'update', {message: "Polishing your new account...", progress: 90 })
  sleep(3)
  Pusher.trigger(pusher_channel, 'update', {message: "Everything is ready for you #{name}! did it feels like 12 seconds?", progress: 100 })
end

Wiring It Up

Now that we have everything sorted out on the backend, we just need to wire everything up on the client side
(JShtml). Simply add the Pusher library in your view by adding
<script src="http://js.pusher.com/2.1/pusher.min.js"> in the <head>.

The main HTML components we will be interacting with are:

<div class="progress progress-striped active hide">
    <div class="progress-bar progress-bar-info" id='realtime-progress-bar' role="progressbar"style="width: 0%"></div>
</div>
<p class="messages"></p>

To finish the job, we just need to sprinkle some Javascript and Jquery on top of it.

1. Instantiate Pusher and subscribe to the unique channel

var uID = Math.floor((Math.random()*100)+1) // this unique ID will be sent through the form to the server. As stated above, there's a lot of way to do this.
var pusher = new Pusher('<Pusher App API Key>') // Change it to your Pusher APP Key
var channel = pusher.subscribe('signup_process_'+uID) // The Channel you want to subscribe to

2. Bind to the update event

channel.bind('update', function(data) {
  // data = {message: "Hello you", progress: 40}
})

3. Update the DOM with the message and progress data

In the bind callback, you can manipulate the data you sent from the server (remember the Pusher.trigger?) and update the DOM with it.

var messageBox = $('#create-account-form-with-realtime').children('.messages')
var progressBar = $('#realtime-progress-bar')

progressBar.width(data.progress+"%")
messageBox.html(data.message)

// The process is complete: do whatever you want now, maybe redirect them to their newly created account?
if (data.progress == 100) {
    messageBox.html('Was it better with this process?')
}

4. There’s no 4. That’s all you need!

Well that was easy, right?

Realtime progress bar

Going Forward

The code and example used here are pretty simple. I usually use real-time progress bars hand in hand with background task processors like Sidekiq or Kue to inform users how things are going. For extra long jobs, always use fallback emails to tell them the job is completed. If you have any questions or feedback, contact us on Twitter or leave a comment below!

For more about building realtime applications, check out our tutorials library, updated on a regular basis.
  • http://womensyellowgoldcartierlovebracelets.wordpress.com/ Cartier love bracelet 18k yellow gold

    C’mon, Larry, getting thebest environment for th elowest price should be a non-partisand goal.

  • http://cartierlovebraceletmenrosegold.blogspot.com/ Cartier love bracelet couple rose gold

    I cannot help you either. If you cannot answer the question, just be silent.

  • http://cartierlovebraceletladywhitegold.tumblr.com/ Cartier love bracelet women 18k white gold

    Aww look at those big boy words from suckoles

  • https://firstcartier.wordpress.com/ what is Cartier love jewellery lady yellow gold

    Seriously? He mentions God and everyone goes ga-ga over him? This guy is a pot head, among other vices and questionable lifestyle choices. He’s a great actor, no doubt, but just because he mentions God in a speech doesn’t make him a Christian. Are we so starved for some attention from Hollywood that we will accept any mention of God? Something to consider.

  • http://www.guestbook.mittelstaedt.de/index.php Lida

    2004 & Barling. IGF-1 Extreme Factor Deer.

    Also visit my page swats deer antler spray gnc (Lida)

  • http://www.bestsatelliteproviders.com/ satellite internet

    Good article. I definitely appreciate this
    site. Keep writing!

  • http://tinyurl.com/o6r866p tinyurl.com

    I am actually pleased to glance at this website posts which consists of tons of valuable facts, thanks for providing these data.

    Review my page :: does garcinia cambogia work (tinyurl.com)

About Sylvain Giuliani

Sylvain is Pusher's COO. He loves everything related to the SaaS world and in his spare time like to build prototypes of new ideas.