How to build a chat into an Angular app with TalkJS
Tags: webdev, angular, tutorial, typescript
Published: 2021-10-01 10:03:15

In today’s tutorial, we will take a look at how we can integrate the [TalkJS Chat API](https://talkjs.com/) into an existing Angular application. AllParts is an imaginary e-commerce website that specializes in automobile spare parts and accessories. They have an Angular application that is integrated with Firebase. It allows users to authenticate themselves using Google and then purchase spare parts and essentials for automobiles.

With TalkJS, AllParts have implemented a buyer-seller chat that the customers can use to resolve queries, get recommendations or ask general questions. It is not a full-fledged application but goes well with this tutorial. You can set up your project from [GitHub](https://github.com/aswinrajeevofficial/TalkJS-Angular) before getting started and if you’ve already done that, let’s get going.

![Angular application with TalkJS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2lqf8nd1ajhiz4qv2gq.png)

## Adding TalkJS to an Angular application
To add TalkJS to your Angular application, use the following command:
`npm install talkjs –save`
This will add the TalkJS dependency to your current project. Next, we will add a component and a service to the project. A service in Angular is used to separate out the component code from functions that are used commonly and also to keep the code modular and scalable. To create a new service, we use the following command:
`ng generate service talk`
There is also a shorthand equivalent of this command which is `ng g s talk`. This will create a new service called `TalkService`. Once that is created we will also create a component for our buyer-seller chat. To create a new component, we will use the following command:
`ng generate component talkjs`
Just like before, the shorthand equivalent of this command is `ng g c talkjs`. Once these prerequisite steps are out of the way, we can get started with the actual integration.

## Application walkthrough
Before we integrate TalkJS into our application, let’s take a look at the existing application itself. It is intended to be an e-commerce website specializing in automobile spare parts and accessories. Customers can sign in with Google and view products from different manufacturers which they can purchase. The application has a home page with a simple banner and also the products page which only logged-in users can access.

## Using TalkJS to add a buyer-seller chat
Our service code looks like this right now.
```typescript
@Injectable({providedIn: 'root'})
export class TalkService {
  private currentUser: Talk.User;
  constructor() {}
}
```
We have added a variable for the current user which is of the TalkJS User type. We will create 4 methods inside it. They are given below.
### Method 1: async createUser(applicatonUser: any)
The code for this method is given below.
```typescript
async createUser(applicationUser: any) {
    await Talk.ready;
    console.log(this.user$);
    return new Talk.User({
      id: applicationUser.id,
      name: applicationUser.username,
      photoUrl: applicationUser.photoUrl,
      role: applicationUser.role
    });
  }
```
This method is used to map the users in the application to a TalkJS User object. This allows TalkJS to identify the users in the system. It also allows keeping track of their conversations. In our case, the user logged in through Google will be mapped to this object so that his name and photo appear inside the chatbox.

### Method 2: async createCurrentSession()
This method is used to initialize the user’s current active session and also authenticate TalkJS. TalkJS has an `appId` that is assigned to each account which is used to authenticate it. To find your appId, simply login to your TalkJS dashboard and you should see it under the Settings tab. You have different appIds for your test environment as well as your live environment.
```typescript
  async createCurrentSession() {
    await Talk.ready;
    const user = {
      id: this.user$.uid,
      username: this.user$.displayName,
      email: this.user$.email,
      photoUrl: this.user$.photoURL,
      role: 'default'
    };
    this.currentUser = await this.createUser(user);
    const session = new Talk.Session({
         appId: 'YOUR_APP_ID_HERE',
         me: this.currentUser
    });
    return session;
  }
```
This is also where we initialize our currently logged-in user. If you look at the code above, you can see that we have retrieved the current user using `this.user$` and the attributes from it match the one returned from Google after successfully signing in.

### Method 3: async getOrCreateConversation(session: Talk.Session, otherApplicationUser: any)
This function creates the conversation between the current user and the other user and also links it up with the session that was created before. This is where you set the participants for the conversation. System messages in TalkJS can also be set up here by adding the `conversation.setAttributes()` method and setting an array of strings to a property called `welcomeMessages`.
```typescript
  private async getOrCreateConversation(session: Talk.Session, otherApplicationUser: any) {
    const otherUser = await this.createUser(otherApplicationUser);
    const conversation = session.getOrCreateConversation(Talk.oneOnOneId(this.currentUser, otherUser));
    conversation.setParticipant(this.currentUser);
    conversation.setParticipant(otherUser);
    conversation.setAttributes({
      welcomeMessages: ["Welcome to AllParts Support Chat!", "Leave your message here and one of our support agents will assist you soon."]
  })
    return conversation;
  }
```
### Method 4: async createPopup(session: Talk.Session)
The last method is to create a popup chat towards the right bottom corner of our screen. The popup UI provided by TalkJS out-of-the-box is really handy in scenarios like this. If you require a full-fledged chatbox or an inbox, they are also provided within TalkJS.
```typescript
  async createPopup(session: Talk.Session) {
    const supportUser = {
      id: 5,
      username: 'Sebastien',
      email: 'sebastian@allparts.com',
      photoUrl: 'https://randomuser.me/api/portraits/men/71.jpg',
      role: 'default'
    };
 
    const conversation = await this.getOrCreateConversation(session, supportUser);
    return session.createPopup(conversation, { keepOpen: false });
 }
```
In the code above, the support user is hardcoded, but when you have your live application, you can use the credentials of actual people that the users can talk to.

## TalkJS Component Walkthrough
We have completed writing up all our helper methods, now we just need to set up our TalkJS component that will contain the popup chatbox. The TalkjsComponent consists of just a single line that has a `div` with an id of `talkjsContainer`. It also has the `*ngIf` directive that checks if the user is logged in or not. For unauthenticated users, the chatbox will not appear.
```html
<div *ngIf = "auth.user$ | async" #talkjsContainer style="height: 500px"></div>
```
Inside the TypeScript file for the component, we have the following code.
```typescript
export class TalkjsComponent implements OnInit {
  private popup: Talk.Popup;
  private session: Talk.Session;
  @ViewChild('talkjsContainer') talkjsContainer!: ElementRef;
  constructor(private talkService: TalkService, public auth: AuthService) {
  }
  ngOnInit(): void {
    this.createPopup();
  }
  private async createPopup() {
    const session = await this.talkService.createCurrentSession();
    this.popup = await this.talkService.createPopup(session);
    this.popup.mount(this.talkjsContainer.nativeElement);
  }
}
```
We use the `@ViewChild` decorator to access the HTML element from the component code to mount our chatbox. We have the AuthService which is used for authenticating the user. The component implements the `OnInit` interface which provides the lifecycle hook of `ngOnInit()`. This gets triggered after component initialization and this is where we call the `createPopup()` method to create the chatbox and mount it to our component.

## Full Demo
Below is a full demo of the application. We can see that the user is logged in and his username is displayed at the top. For authenticated users, the chatbox option is available at the bottom right corner and they can also view the products.

![Angular app with TalkJS Full Demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/plsz6zq8iqqhcoojdu9k.gif)

## Wrapping Up
There you have it. We have successfully integrated TalkJS to our existing Angular application called AllParts. We didn’t go over the Angular code much in-depth and the tutorial assumes that the user has some basic knowledge of Angular. The entire code is available on [GitHub](https://github.com/aswinrajeevofficial/TalkJS-Angular). Make sure you create a Firebase project on Firebase Console and use the credentials provided there to authenticate your application with Firebase.