10.7: Adding Conversations to MemberDetailComponent

Now, we'll work on adding the message threads to the MemberDetailComponent

Adding getMessageThread() to UserService

We'll start by adding a new method getMessageThread() to the UserService:

getMessageThread(id: number, recipientId: number) {
    return this._http.get<Message[]>(this.baseUrl + 'users/' + id + '/messages/thread/' + recipientId);
}

Add MemberMessagesComponent

We'll add a new component to display the conversations.

ng g c members/member-messages --no-spec

Verify that it was added correctly to app.module.ts.

Update member-messages.component.ts to the following:

export class MemberMessagesComponent implements OnInit {
  @Input() userId: number;
  messages: Message[];

  constructor(private _userService: UserService,
              private _authService: AuthService,
              private _alertify: AlertifyService) { }

  ngOnInit() {
    this.loadMessages();
  }

  loadMessages() {
    this._userService.getMessageThread(this._authService.decodedToken.nameid, this.userId).subscribe(messages => {
      this.messages = messages;
    }, error => {
      this._alertify.error(error);
    });
  }

}

This is again very similar to what we've been doing. We do have an Input() property for the userId that we'll get from the MemberDetailComponent.

In member-detail.component.html, add the component and pass along the userId:

Adding MemberMessages Template

And, in member-messages.component.scss:

.chat {
    list-style: none;
    margin: 0;
    padding: 0;
}

.chat li {
    margin-bottom: 10px;
    padding-bottom: 10px;
    border-bottom: 1px dotted #b3a9a9;
}

.rounded-circle {
    height: 50px;
    width: 50px;
}

.card-body {
    overflow-y: scroll;
    height: 400px;
}

.read {
    color: #60AB15;
}

.unread {
    color: #D9514E;
}

We'd like to be able to navigate from the Messages component to the MemberDetail component and have the Messages tab be open instead of the About tab. We'd also like to open the Messages tab when a user clicks on the Message button in their profile panel.

We'll do this using ngx-bootstrap.

In member-detail.component.ts, add a ViewChild() property and a selectTab() method:

@ViewChild('memberTabs') memberTabs: TabsetComponent;

//  ...

selectTab(tabId: number) {
    this.memberTabs.tabs[tabId].active = true;
}

In the member-detail.component.html, add a click listener to the Message button:

<button type="button" class="btn btn-secondary" (click)="selectTab(3)">Message</button>

ngx-bootstrap passes the tab we want as a query string and handles it for us. We're passing 3 as the parameter because it's the 4th tab (0-indexed).

Now, we'll try to do the same thing from our Messages component. This time we'll have to pass the query parameters ourselves.

In messages.component.html - in the second <tr> element where we have our routerLink set up - we can also add query parameters.

<tr 
    *ngFor="let message of messages"
    [routerLink]="['/members', messageContainer == 'Outbox' ? message.recipientId : message.senderId]" 
    [queryParams]="{tab: '3'}">             <!--Added-->

We can then subscribe to the query parameters in the ngOnInit() method in the member-detail.component.ts similarly to how we're getting the user query params:

ngOnInit() {
    this._route.data.subscribe(data => {
      this.user = data['user'];
    });

    this._route.queryParams.subscribe(params => {
      this.memberTabs.tabs[params['tab']].active = true;
    });

    //  ...

We can also add this to the button with the envelope icon in our main list of users in the MemberCardComponent. Open up member-card.component.html and add the routerLink and queryParams:

Last updated