Message component


Create a new interface _models/Message.ts

export interface Message {
  id: number;
  senderId: number;
  senderKnownAs: string;
  senderPhotoUrl: string;
  recipientId: number;
  recipientKnownAs: string;
  recipientPhotoUrl: string;
  content: string;
  sentDate: Date;
  isRead: boolean;
  readDate: Date;


We will use the UserService, it can be argued that a new service for the messages is a better choice.

Add new method getMessages

  userId: number, pageNumber?: number, itemsPerPage?: number, messageContainer?: string
): Observable<PaginatedResult<Message[]>> {
  let params = new HttpParams();
  if (pageNumber !== null && itemsPerPage !== null) {
    params = params.set('pageNumber', pageNumber.toString()).set('pageSize', itemsPerPage.toString());
  if (messageContainer !== null) {
    params = params.set('messageContainer', messageContainer);

  return this.http
    .get<Message[]>(this.baseUrl + userId + '/messages', {
      params: params,
      observe: 'response'
      map(response => {
        const paginatedResults = new PaginatedResult<Message[]>();
        paginatedResults.result = response.body;
        if (response.headers.get('Pagination') !== null) {
          paginatedResults.pagination = JSON.parse(response.headers.get('Pagination'));
        return paginatedResults;


Create a new resolver messages.resolver.ts

export class MessagesResolver implements Resolve<PaginatedResult<Message[]>> {
  pageNumber = 1;
  pageSize = 5;
  messageContainer = 'Unread';

    private userService: UserService,
    private authService: AuthService,
    private router: Router,
    private alertify: AlertifyService
  ) {}

  resolve(route: ActivatedRouteSnapshot): Observable<PaginatedResult<Message[]>> {
    return this.userService.getMessages(this.authService.getUserId(), this.pageNumber, this.pageSize, this.messageContainer).pipe(
      catchError(error => {
        this.alertify.error('Problem retrieving messages');
        return empty();

Register the resolver in app.module.ts in the providers.

Add the resolver in routes.ts

  path: 'messages',
  component: MessagesComponent,
  resolve: { messages: MessagesResolver }


Open messages.component.ts

  selector: 'app-messages',
  templateUrl: './messages.component.html',
  styleUrls: ['./messages.component.css']
export class MessagesComponent implements OnInit {
  messages: Message[];
  pagination: Pagination;
  messageContainer: 'Unread';

    private userService: UserService,
    private authService: AuthService,
    private route: ActivatedRoute,
    private alertify: AlertifyService
  ) {}

  ngOnInit() { => {
      const paginatedResult = <PaginatedResult<Message[]>>data['messages'];
      this.messages = paginatedResult.result;
      this.pagination = paginatedResult.pagination;

  loadMessages() {
        paginatedResult => {
          this.messages = paginatedResult.result;
          this.pagination = paginatedResult.pagination;
        error => this.alertify.error(error)

  pageChanged(event: any): void {
    this.pagination.currentPage =;


Open message.component.html

<div class="container mt-5">
  <div class="row">
    <div class="btn-group" btnRadioGroup [(ngModel)]="this.messageContainer">
      <label class="btn btn-primary" btnRadio="Unread" (click)="loadMessages()">
        <i class="fa fa-envelope"></i> Unread
      <label class="btn btn-primary" btnRadio="Inbox" (click)="loadMessages()">
        <i class="fa fa-envelope-open"></i> Inbox
      <label class="btn btn-primary" btnRadio="Outbox" (click)="loadMessages()">
        <i class="fa fa-paper-plane"></i> Outbox

  <div class="row" *ngIf="messages.length == 0">
    <h3>No messages</h3>

  <div class="row" *ngIf="messages.length > 0">
    <table class="table table-hover" style="cursor: pointer">
        <th style="width: 40%">Message</th>
        <th style="width: 20%">From / To</th>
        <th style="width: 20%">Sent / Received</th>
        <th style="width: 20%"></th>
      <tr *ngFor="let message of messages" [routerLink]="['/members',
        messageContainer == 'Outbox' ? message.recipientId : message.senderId]">
          <div *ngIf="messageContainer != 'Outbox'">
            <img src={{message?.senderPhotoUrl}} class="img-circle rounded-circle mr-1">
          <div *ngIf="messageContainer == 'Outbox'">
            <img src={{message?.recipientPhotoUrl}} class="img-circle rounded-circle mr-1">
        <td>{{message.sentDate | timeAgo}}</td>
          <button class="btn btn-danger">Delete</button>

<div class="d-flex justify-content-center" *ngIf="messages.length > 0">
  <pagination [boundaryLinks]="true" [totalItems]="pagination.totalItems" [itemsPerPage]="pagination.itemsPerPage" [(ngModel)]="pagination.currentPage"
    (pageChanged)="pageChanged($event)" previousText="&lsaquo;" nextText="&rsaquo;" firstText="&laquo;" lastText="&raquo;">

Add some style in message.component.css

table {
    margin-top: 15px;

.img-circle {
    max-height: 50px;

td {
    vertical-align: middle;