Angular 2 TypeScript using SignalR

15,260

Solution 1

Here's a startup code you can use.

C#

//create an interface that contains definition of client side methods
public interface IClient
{
    void messageReceived(string msg);
}

//create your Hub class that contains implementation of client methods
public class ChatHub : Hub<IClient>
{
    public void sendMessage(string msg)
    {
        //log the incoming message here to confirm that its received

        //send back same message with DateTime
        Clients.All.messageReceived("Message received at: " + DateTime.Now.ToString());
    }
}

HTML

Add reference to script files of jQuery and signalR.

<script src="path/to/jquery.min.js"></script>
<script src="path/to/jquery.signalR.min.js"></script>

<!--this is the default path where SignalR generates its JS files so you don't need to change it.-->
<script src="~/signalr/hubs"></script>

JS

You need to install TypeScript definition file for SignalR and jQuery. If you're using TypeScript 2, you don't need to add reference to index.d.ts file while using it. Just install the typings using following commands.

npm install --save @types/jquery
npm install --save @types/signalr

With all the setup done, you can write a simple TypeScript class to handle the logic for sending and receiving messages.

export class MessageService {
    //signalR connection reference
    private connection: SignalR;
    
    //signalR proxy reference
    private proxy: SignalR.Hub.Proxy;


    constructor() {
        //initialize connection
        this.connection = $.connection;
        
        //to create proxy give your hub class name as parameter. IMPORTANT: notice that I followed camel casing in giving class name
        this.proxy = $.connection.hub.createHubProxy('chatHub');

        //define a callback method for proxy
        this.proxy.on('messageReceived', (latestMsg) => this.onMessageReceived(latestMsg));

        this.connection.hub.start();
    }
    
    private onMessageReceived(latestMsg: string) {
        console.log('New message received: ' + latestMsg);
    }

    //method for sending message
    broadcastMessage(msg: string) {
        //invoke method by its name using proxy 
        this.proxy.invoke('sendMessage', msg);
    }
}

I'm using the above code, obviously modified to my needs, and it works fine.


Update 1: This is a pretty old answer and things have changed a lot since then. Install jQuery and SignalR using npm and then load them using angular.json file, like this:

1- Install npm install jquery signalr

2- Load in angular.json -> projects -> your-app -> architect -> build -> options

scripts: [
  "./node_modules/jquery/dist/jquery.min.js", 
  "./node_modules/signalr/jquery.signalR.min.js"
]

Thanks and credits to Robert's answer for update.

Solution 2

@Syed Ali Taqi's answer is basically OK but not perfect(even not working if you miss configuring ts compiler). Here's my steps for newest Angular(version 8 as of my writing):

  1. Install jquery and signalr run time libs: npm install jquery signalr
  2. Tell Angular to load the libs at run time as if they were in the <script></script> tag by configuring angular.json :

    projects:
      <your-app>:
        architect:
          build:
            options:
              ...
              scripts: [
                "./node_modules/jquery/dist/jquery.min.js",
                "./node_modules/signalr/jquery.signalR.min.js"
              ]
          ...
          test:
            options:
              ...
              scripts: [
                "./node_modules/jquery/dist/jquery.min.js",
                "./node_modules/signalr/jquery.signalR.min.js"
              ]
    
  3. Install types for jquery and signalr so that the ts compiler can recognize them: npm install @types/jquery @types/signalr --save-dev

  4. Tell the ts compiler to load the types by default by editing the types section of tsconfig.app.json and tsconfig.spec.json:
    compilerOptions:
      types: [..., "jquery", "signalr"]
    

OK, all done! Happy SignalR coding!

let conn = $.hubConnection("<base-path>");
let proxy = conn.createHubProxy("<some-hub>");
...

Note: never try to import ... from jquery explicitly in your code, as said by https://angular.io/guide/using-libraries#using-runtime-global-libraries-inside-your-app

For more info on angular.json configuration, see https://angular.io/guide/workspace-config

Share:
15,260
Daniel Grima
Author by

Daniel Grima

Updated on July 17, 2022

Comments

  • Daniel Grima
    Daniel Grima almost 2 years

    I'm trying to set up an Angular 2 application to use Microsoft's SignalR. I've been following this tutorial, which although it's good I don't like the fact that jQuery and SignalR are loaded into the application via script tags in the index.html file and also the fact that both libraries do not use their respective Type Definitions.

    So with that in mind I've been trying to include jQuery and SignalR in my application using node modules and the respective Type Definitions. I've searched the correct type definition files to use through Microsoft's TypeSearch.

    I'm only including jQuery in my application because of SignalR's dependency on jQuery.

    jQuery

    I first started with installing the jQuery module in my application which I've had to add in the Webpack configuration as well. After this was set up I'm being faced with a "conflict" issue because of Protractor. This is described on Aurelia JS Rocks' website. Although it suggests uninstalling the protractor typings I tried our another solution for now described in this answer. I don't know if this is the best solution.

    SignalR

    With regards to SignalR I'm a bit stuck - so far it seems there's no "official" node module provided for SignalR. I'm not sure whether I should include Microsoft's SignalR Javascript Library by downloading the file and including it in my application.

    The issue is that I have installed the Type Definitions for SignalR. But now I'm not sure how to go about actually using SignalR since when I type $ or jQuery I'm not being suggested .connections for example - which makes sense as this is not part of the jQuery library.

    I'm sure that I might be misunderstanding something with regards to getting it "set up". What's the best way to go about using SignalR in an Angular2 TypeScript application?

  • Daniel Grima
    Daniel Grima over 7 years
    That's very helpful! Thanks a lot... one thing is that even though I'm using TypeScript 2.0.9 it seems that I still have to use the refer to the index.d.ts file. Without the reference I'm getting errors when I try to call SignalR for example.
  • Syed Ali Taqi
    Syed Ali Taqi over 7 years
    @DanielGrima: sounds strange n you're welcome. if this solved your problem, please mark it as answer so that it is helpful for somebody else in future.
  • Daniel Grima
    Daniel Grima over 7 years
    Yeah it is strange.. I'll investigate further and see what happens
  • Daniel Grima
    Daniel Grima over 7 years
    I managed to solve the issue I had with the type definition reference... I had to add "signalr" in the types array in the tsconfig.json file, once I did that problem was solved :) Not sure if it's supposed to be added automatically.. anyway for now all okay :)
  • jaypman
    jaypman about 7 years
    i'm getting this error: Type 'SignalR' is not assignable to type 'Connection'. Property 'proxies' is missing in type 'SignalR'. for this.connection = $.connection; Any ideas? I already installed the typings via npm.
  • Syed Ali Taqi
    Syed Ali Taqi about 7 years
    @jaypman: try changing the line private connection: SignalR.Hub.Connection to this private connection: SignalR
  • jaypman
    jaypman about 7 years
    Thank you @SyedAliTaqi :) It works now with your suggestion.
  • Pankaj
    Pankaj almost 7 years
    After TypeScript definition file for SignalR and jQuery, I start getting lots of error TS1005: Build:',' expected. errors in \node_modules\@types\jquery\index.d.ts File.
  • Syed Ali Taqi
    Syed Ali Taqi almost 7 years
    @Pankaj: which version of @types/jquery are you using? try this solution.
  • Pankaj
    Pankaj almost 7 years
    Just downloaded the latest ones, I am using @types/jquery version 3.2 and my jquery is version 3.2.1
  • Majid ALSarra
    Majid ALSarra over 6 years
    I'm getting an error on this line this.proxy = $.connection.hub.createHubProxy('myhub'); it says: Error TS2322 Type 'HubProxy' is not assignable to type 'Proxy'. any clue?
  • Majid ALSarra
    Majid ALSarra over 6 years
    Changing the definition private proxy: SignalR.Hub.Proxy; to private proxy: HubProxy; solved it partially but I'm still getting errors elsewhere that doesn't seem related
  • Syler
    Syler over 6 years
    guys I am getting $.connection is undefined in typescript only, works ok in index.cshtml. any ideas?
  • Vasanth
    Vasanth about 6 years
    I'm getting these errors when I use above code. Cannot find name 'SignalR'.Cannot find namespace 'SignalR' Cannot find name '$'. What should I do ?
  • Syed Ali Taqi
    Syed Ali Taqi about 6 years
    @Vasanth: have you installed the typings for jQuery and SignalR?
  • Ibanez1408
    Ibanez1408 almost 6 years
    If I have a console application as server, where should I put the url to the server in my client side? Thank you.
  • Syed Ali Taqi
    Syed Ali Taqi almost 6 years
    @Ibanez1408: didn't try that yet. I believe all of the config is inside generated js file of SignalR. for a console application, this might help.
  • Lex Li
    Lex Li over 3 years
    At least for me, 1) private connection: SignalR; should be private connection: SignalR.Hub.Connection; 2) all .hub should be removed. 3) declare var $: any; is needed ahead. 4) The HTML section is not applicable and can be ignored.