Build a Chat Application with Angular Material and the Nexmo In-App JavaScript SDK

Published March 28, 2018 by Alex Lakatos

[In this tutorial, we’ll enable chat in an Angular web application using the JavaScript SDK and the In-App API so that users can communicate in our application. If you’d like to check out the source code, it lives on our community github page.

This is what we’re trying to build:

Before You Begin

Before we begin you’ll need a few things:

  • A basic understanding of Angular.
  • Node.js installed on your machine.
  • A Nexmo account – create one for free.
  • The Nexmo CLI. Install it as follows:

    Setup the CLI to use your Nexmo API Key and API Secret. You can get these from the setting page in the Nexmo Dashboard:

  • The middleware code from Github

Getting the middleware code from Github

First, we’re going to clone the middleware source code and install the dependencies for it. We’re going to write a Node.js application using Express that provides a level of abstraction between the Nexmo API and the Angular code:

Running the middleware code from Github

Before we can run the code, we’ll need to create a Nexmo RTC application within the Nexmo platform to use within this code:

The output of the above command will be something like this:

The first item is the Application ID, which you should take a note of (we’ll refer to this as APP_ID later). The last value is a private key location. The private key is used to generate JWTs that are used to authenticate your interactions with Nexmo.

Now we’ll need to make a copy of example.env and call that .env, and update the values within your Nexmo API_KEY and API_SECRET. We’ll also have to add the APP_ID we just generated and the path to your private key. After we’ve updated the values, we can run the code in debug mode with:

Create Users and Conversations

The app should be running on localhost:3000. Now that the app is running, we’re going to go ahead and create a couple of users and a conversation, and then we’ll add the users we created to the conversation.

We’ll create a couple of users by running this command twice, once with the username alice and then with jamie:

The ouput should look similar to:

We’ll make a note of the user ID and refer to it later on as USER_ID. Now let’s create a conversation via the demo API:

The ouput should look similar to:

We’ll make a note of the conversation ID and refer to it later on as CONVERSATION_ID. Now let’s join the users to the conversation. We’re going to run the following command twice—remember to replace the CONVERSATION_ID and USER_ID with IDs from the two previous steps every time you run this command:

Generate Angular App

Now that we have our middleware up and running, it’s time we created the Angular application. We are going to use the Angular CLI to generate the app, so if you don’t have it installed, you’ll need to install that first:

And then we’ll use it to generate a new application with routing. It may take a while for it to generate all the files and install the dependencies:

Add Material Design

After the previous command finished, we’ll add Angular Material and its dependencies to the project:

We’ll also have to import the NgModule for each component we want to use in our application. In order to do that, we need to open src/app/app.module.ts in our editor and import the modules at the top:

We’ll also need to update the @NgModules imports declaration to add the modules from above:

We’ll also want to add a theme to Material, so add this line to your style.css:

If we want to use the official Material Design Icons, we’ll need to load the icon font in our index.html:

Polyfill Nexmo In-App SDK

Now that we’ve got our Angular application generated and all set up with Material, we’ll install the Nexmo JavaScript SDK and add it to the bottom of polyfills.ts:

Messaging Service

We’ll need to create an Angular Service to handle the data from our middleware. Let’s generate it using the Angular CLI:

Two new files were generated in our src/app folder, messaging.service.spec.ts and messaging.service.spec.ts. We’re going to update the messaging.service.spec.ts in order to add the ConversationClient from the Nexmo In-App SDK, instantiate a client, and handle getting a user JSON Web Token from the middleware. We’re going to replace the boilerplate code with:

We need to update app.module.ts in order to import the MessagingService and register it as a provider:

Login Component

Let’s start building some UI for our app. We’ll start with a LoginComponent, and we’ll generate that with the Angular CLI:

That will generate a login folder inside the app folder, and four files, for the HTML, CSS, and TypeScript code, as well as tests. Let’s replace the code in login.component.html with a UI for logging in. I chose a <mat-grid-list> with a <mat-card> inside of it, and a form with a login button that calls onLogin() when it’s submitted. The code looks like this:

Let’s add some CSS to it for the Material spinner, in the login.component.css file:

We also need to update login.component.ts in order to add the MessagingService to it and implement the onLogin() method. The method is going to take the username, make a request via the messaging service to the middleware we are running in order to get a user JWT, and then use that to authenticate via the login method of the Nexmo In-App JavaScript SDK. The code looks like this:

Notice that I’ve imported the Router from Angular, injected it into our constructor and I’m using it at the end of the authentication flow to navigate to the next page, /conversation.

Conversation Component

We haven’t actually created the conversation component yet, so let’s go ahead and use the Angular CLI to create that:

We’re going to update the conversation.component.html file to use a material sidenav component, which lists the user conversations on the left and the conversation members on the right, leaving the middle for our main chat. We’ll add a header to the chat section to list the conversation name and member count, and add an input section at the bottom. We’ll leave the middle section for the actual conversation history to be displayed. We’ll build an empty shell for now and add to it later as we develop the ConversationComponent. The HMTL should look like this:

We’re going to update the conversation.component.ts file with the necessary boilerplate for methods we’re going to use later on:

Let’s start by implementing ngOnInit() so that it checks if we have app data before trying to getConversations using the Nexmo In-App SDK. If there is no app data, then we’ll get redirected to the login screen:

We need to implement a helper method for building a conversations array out of the conversations dictionary the Nexmo In-App JavaScript SDK provides, so we can use it with *ngFor in the UI later on:

Let’s add a method for selecting a conversation from the list. We’ll need to take the ID from the view and pass it on to the controller, and then use the Nexmo SDL to get data about the conversation. We’ll store this in a class property, so it’s available to the view later on. We’re also using Observable to create an array from the conversation.events Map, so we can recreate chat history when the user comes back to the app. We’ll also add an event listener using the SDK to listen for text events and add those to the events history as well:

Last but not least, let’s add a method that takes the input from the view and sends it to the Nexmo In-App API via the SDK:

Now that we’ve implemented all the methods we need, we can go back and start to flesh out the view some more, to use the data models we created in the controller. First, let’s update the conversations section in conversation.component.html:

Now let’s add the members section:

We’re using a pipe called keys here to transform the members dictionary object we get from the SDK into an array, so we’ll need to create that using the Angular CLI and update the generated keys.pipe.ts file:

Next, we’ll update the conversation-header section of the view to display the selected conversation name and member count:

We also need to update the conversation-history section in order to parse the events and recreate history in the chat. Events coming from the Nexmo In-App SDK have multiple types, so we’ll account for some of them, like member:joined and text:

We’ll need to update the conversation-input part in order to be able to send messages into the conversation:

Let’s add some CSS to it to make it full screen and fixed position. Add the following CSS to conversation.component.css:

Last but not least, we need to update the app routing module in app-routing.module.ts in order to have the correct routes displayed:

We also need to replace the entire app.component.html with the <router-outlet> in order to display the router on the first page:

Run Your App!

After making the app detailed in this post, run the app to see it working:

The app will run at “http://localhost:4200”. I’d suggest opening the app in two separate tabs, logging in with both alice and jamie and start talking to each other! If you’d like to see the app in its final state, you can check out the source code for this app on our community github page. If you want to see a more advanced version of this code, you can check the stitch-demo middleware code you downloaded at the beginning of the blog post. It also contains an Angular Material front-end.

What’s Next?

If you’d like to continue learning how to use the Nexmo In-App SDK for JavaScript, check out our quickstarts where we show you how to:

If you have more questions about using Nexmo In-App SDK, we encourage you to join the Nexmo community slack and check out our #stitch channel or email us directly at ea-support@nexmo.com.

Leave a Reply

Your email address will not be published.