Question

I'm learning SignalR and I'm getting this error in Google Chrome's debug:

Uncaught TypeError: Cannot read property 'MoveShape' of undefined

My hub class in MVC

public class MoveShapeHub : Hub
{
    public void MoveShape(int x, int y)
    {
        Clients.Caller.shapeMoved(Context.ConnectionId, x, y);
    }
}

Javascript file

$(function () {
var hub = $.connection.MoveShapeHub;
var $shape = $('#shape');

$.extend(hub, {
    shapeMoved: function (cid, x, y) {
        if (cid !== $.connection.hub.id) {
            $shape.css({ left: x, top: y });
        }
    }
});

$.connection.hub.start().done(function () {
    $shape.draggable({
        drag: function () {
            hub.MoveShape(this.offsetLeft, this.offsetTop || 0);
        }
    });
});
});

Script refences in HTML

<script src="~/Scripts/jquery-ui-1.10.4.js"></script>
<script src="~/Scripts/jquery.signalR-2.0.3.js"></script>
<script src="/signalr/hubs"></script>
<script src="~/Scripts/Application/MoveShape.js"></script>

HTML

<div id="shape" style="width: 100px; height: 100px; background-color:#f00"></div>
Was it helpful?

Solution

First of all, can you show us your startup class where you call MapSignalR()?

Assuming that you have done that correctly, the first thing that I see that is off is the following:

var hub = $.connection.MoveShapeHub;

The "/signalr/hubs" script is responsible for defining $.connection.moveShapeHub. Notice how moveShapeHub is defined using the lower camel case convention common to JavaScript instead of the Pascal case convention common to C#.

This means that the above line should be modified to use the lower camel case convention:

var hub = $.connection.moveShapeHub;

If you would prefer to use Pascal case, you can do so by using the HubName attribute.

[HubName("MoveShapeHub")]
public class MoveShapeHub : Hub

A name specified by the HubName attribute won't be re-cased by the /signalr/hubs script. http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client#getproxy


Secondly, you should be putting your client-side hub callbacks on $.connection.moveShapeHub.client object instead of directly on $.connection.moveShapeHub. This means that $.extend(hub, { //... should be $.extend(hub.client, { instead.


It is also concerning that you use an app root relative path for all your scripts except /signalr/hubs. This shouldn't be a problem if your app root is the root of the domain, but I would change the /signalr/hubs reference to also be app root relative to be safe.

OTHER TIPS

Try like this instead

var hub = $.connection.moveShapeHub;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top