Over a million developers have joined DZone.

Implementing a SignalR Stock Ticker Using AngularJS: Part1

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

In my last post, we saw how to use ASP.NET SignalR and AngularJS together using a "Hello World" type of example. Now that we have some idea of how to use both technologies together, we will take a look at a more advanced scenario in order to make the frameworks work better together.

I assume that you have already seen the SignalR Stock ticker sample. If not, download it from GitHub or add the NuGet Package to an existing ASP.NET web application. Make sure that you take some time to run the sample at least once on multiple browsers and have a glance at the code before you proceed any further.

I hope you had a look at the code on both the server and the client side of the stock ticker sample. We will not make any modification to the server code and the layout of the page, but we will rewrite the JavaScript part using features of AngularJS. Since there is a lot of client-side code to convert, let’s do it in a two-part series:

  1. Creating a custom service to communicate with the hub on the server and using the service in a controller (this post)
  2. Performing UI changes on the page, like enabling/disabling buttons, scrolling stock values in a list, and adding animation effect to values in a table and list (next post)

Make a copy of the StockTicker.html file and give it a name of your choice. Add two JavaScript files, controller.js and factory.js, to the project. We will add script to these files soon. Modify the script reference section of the page to include the following script files:

<script src="../../bundles/jquery"></script>
<script src="../../bundles/jquerycolor"></script>
<script src="../../Scripts/jquery.signalR-1.0.1.js"></script>
<script type="text/javascript" src="../../Scripts/angular.js"></script>
<script type="text/javascript" src="factory.js"></script>
<script type="text/javascript" src="controller.js"></script>
Let’s start implementing the SignalR part inside a custom service. To keep the controller free from doing anything other than providing data to the view and handling view events, we are creating a custom service to handle the hub communication logic. The service is responsible for:
  1. Creating objects needed for communication
  2. Configuring client functions to proxy and to respond when a market is opened, closed, or reset, or when a stock value is updated
  3. Starting a hub connection
  4. Getting the current values of stocks and the current market statuses of the stocks once the connection is started
  5. Opening, closing or resetting markets on demand
Following is the module and the factory that handles the functionality mentioned above:
var app = angular.module('app', []);
app.value('$', $);
app.factory('stockTickerData', ['$', '$rootScope', function ($, $rootScope) {
    function stockTickerOperations() {
        //Objects needed for SignalR
        var connection;
        var proxy;
        //To set values to fields in the controller
        var setMarketState;
        var setValues;
        var updateStocks;
 //This function will be called by controller to set callback functions
        var setCallbacks = function (setMarketStateCallback, setValuesCallback, updateStocksCallback) {
            setMarketState = setMarketStateCallback;
            setValues = setValuesCallback;
            updateStocks = updateStocksCallback;
        var initializeClient = function () {
            //Creating connection and proxy objects
            connection = $.hubConnection();
            proxy = connection.createHubProxy('stockTicker');
        var configureProxyClientFunctions = function () {
            proxy.on('marketOpened', function () {
                //set market state as open
            proxy.on('marketClosed', function () {
                //set market state as closed
            proxy.on('marketReset', function () {
                //Reset stock values
            proxy.on('updateStockPrice', function (stock) {
        var initializeStockMarket = function () {
            //Getting values of stocks from the hub and setting it to controllers field
            proxy.invoke('getAllStocks').done(function (data) {
            }).pipe(function () {
                //Setting market state to field in controller based on the current state
                proxy.invoke('getMarketState').done(function (state) {
                    if (state == 'Open')
        var start = function () {
            //Starting the connection and initializing market
            connection.start().pipe(function () {
        var openMarket = function () {
        var closeMarket = function () {
        var reset = function () {
        return {
            initializeClient: initializeClient,
            openMarket: openMarket,
            closeMarket: closeMarket,
            reset: reset,
            setCallbacks: setCallbacks
    return stockTickerOperations;
} ]);
We need a controller to start the work. The controller will have the following components:

  1. An array to store the current stock values and a Boolean value to store the current market state
  2. Setters to assign values to the fields 
  3. A function to modify the value of an entry in the stocks array
  4. Functions to handle open, close and reset operations when the corresponding button is clicked
  5. Set callbacks to the service and ask the service to kick off the communication

Following is the code in the controller:

var StockTickerCtrl = function ($scope, stockTickerData) {
    $scope.stocks = [];
    $scope.marketIsOpen = false;
    $scope.openMarket = function () {
    $scope.closeMarket = function () {
    $scope.reset = function () {
    function assignStocks(stocks) {
        $scope.stocks = stocks;
    function replaceStock(stock) {
        for (var count = 0; count < $scope.stocks.length; count++) {
            if ($scope.stocks[count].Symbol == stock.Symbol) {
                $scope.stocks[count] = stock;
    function setMarketState(isOpen) {
        $scope.marketIsOpen = isOpen;
    var ops = stockTickerData();
    ops.setCallbacks(setMarketState, assignStocks, replaceStock);

The layout of the HTML page will remain unchanged. But we need to change the way data is rendered on the screen. The stock ticker sample uses a poor man’s template technique to render content in the table and in the scrolling list. Since we are using AngularJS, let’s replace it with expressions. Following is the mark-up on the page in Angular’s style:
<div data-ng-app="app" data-ng-controller="StockTickerCtrl">
            ASP.NET SignalR Stock Ticker Sample</h1>
        <input type="button" id="open" value="Open Market" data-ng-click="openMarket()" />
        <input type="button" id="close" value="Close Market" data-ng-click="closeMarket()" />
        <input type="button" id="reset" value="Reset" data-ng-click="reset()" />
            Live Stock Table</h2>
        <div id="stockTable">
            <table border="1">
                    <tr class="loading" data-ng-show="stocks.length==0">
                        <td colspan="7">
                    <tr data-ng-repeat="stock in stocks">
                            {{stock.Price | number:2}}
                            {{stock.DayOpen | number:2}}
                            {{stock.DayHigh | number:2}}
                            {{stock.DayLow | number:2}}
            Live Stock Ticker</h2>
        <div id="stockTicker">
            <div class="inner">
                    <li class="loading" data-ng-show="stocks.length==0">loading...</li>
                    <li data-ng-repeat="stock in stocks" data-symbol="{{stock.Symbol}}"><span class="symbol">
                        {{stock.Symbol}}</span> <span class="price">{{stock.Price | number:2}}</span><span
                            class="change">{{stock.Change}} ({{stock.PercentChange}})</span>

Open this page on a browser and the original stock ticker page on another browser window and play with the buttons. You will see that both screens have the same data at any given point in time. The only difference would be the state of the buttons, their color and a scrolling list. We will fix them in the next post.

Happy coding!

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.


The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}