ILIA BROUDNO
ILIA BROUDNO

Reputation: 1893

PrimeNG sidebar clears primeng messages. Why?

In my app.component.html I have

<div class="main">
    <button type="button" (click)="onShowNotificationSideBar()" label="Show"></button>  
    <p-sidebar [(visible)]="notificationSideBarVisible" position="right" [style]="{width:'50em'}">
        <button type="button" pButton pRipple (click)="showSuccess()" label="S" class="p-button-success"></button>        
        <button type="button" pButton pRipple (click)="showWarn()" label="W" class="p-button-warning"></button>
        <button type="button" pButton pRipple (click)="showError()" label="E" class="p-button-danger"></button>
        <h3>Messages</h3>
        <h5>{{messages}}</h5>
        <p-messages [(value)]="messages" [enableService]="false" ></p-messages>
    </p-sidebar>
    <p-toast position="center"></p-toast>
    <router-outlet></router-outlet>
</div>

in app.component.ts I have

import { Component } from '@angular/core';
import { Message, MessageService } from 'primeng/api';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  providers: [MessageService]
})
export class AppComponent {
  title = 'WECO';
  notificationSideBarVisible = false;

  constructor(private messageService: MessageService) {
    messageService.messageObserver.subscribe((m:Message | Message[])=>{
      if (!Array.isArray(m)){
        this.messages.push(m)
      }
      this.messages = [...this.messages];
    });
  }

  onShowNotificationSideBar(){
    this.notificationSideBarVisible=true;
  }

  count=0;

  messages : Message[] = [
    // { severity: 'success', summary: 'Success', detail: 'Message Content' },
    // { severity: 'info', summary: 'Info', detail: 'Message Content' },
    // { severity: 'warn', summary: 'Warning', detail: 'Message Content' },
    // { severity: 'error', summary: 'Error', detail: 'Message Content' }
  ];

  longSentence = 'Let’s end all this nonsense about how long sentences = run-on sentences. You can have a six-word run-on sentence (“I went shopping I ate donuts.”), while most of the sentences below are much, much longer than that and are not run-ons';//'And let’s end all this nonsense about how long sentences = run-on sentences. You can have a six-word run-on sentence (“I went shopping I ate donuts.”), while most of the sentences below are much, much longer than that and are not run-ons (except for a few examples like Jose Saramago).  But whether the sentence is grammatically correct isn’t nearly as important as whether the sentence is fun or beautiful.'

  showWarn(){
    let detail='User Deleted a Weco Rule';
    if (this.count++%5===0)
      detail = this.longSentence;
    this.messageService.add({severity:'warn', summary:'User Action', detail: detail});
  }

  showSuccess(){
    let detail = 'Weco Rule 123 Saved';
    if (this.count++%5===0)
      detail = this.longSentence;
    this.messageService.add({severity:'success', summary:'Service Call', detail:detail});
  }

  showError(){
    let detail = 'api-call:get-factories returned 404';
    if (this.count++%5===0)
      detail = this.longSentence;
    this.messageService.add({severity:'error', summary:'Service Call', detail:detail});
  }
}

If I open side bar and add some messages in it they appear, but when I close and reopen they are gone. Even though I can see that messages variable still has them. Why?
P.S. If I then add some more messages I only see the new ones.

Upvotes: 1

Views: 258

Answers (1)

Naren Murali
Naren Murali

Reputation: 57986

The sidebar menu has a component called p-messages, if you check the element, you will note that the p-sidebar contents gets destroyed when you close.

When you reopen the sidebar, the data stays the same, but the messages are destroyed.

I think the p-messages component will only show the array references are getting changed, this might be due to the *ngFor inside the component with a trackBy, so we need to reset each array elements reference in memory, so that we trick p-messages into thinking that there are new messages in the list, for this we can use object destructuring! I will do this when the sidebar is opened (onShowNotificationSideBar)

onShowNotificationSideBar() {
    this.notificationSideBarVisible = true;
    this.messages = [...this.messages.map(x => ({...x}))]; // <- creates new references for the array and its contents!
}

full code

import { Component } from '@angular/core';
import { Message, MessageService } from 'primeng/api';

@Component({
  selector: 'sidebar-basic-demo',
  templateUrl: './sidebar-basic-demo.html',
  providers: [MessageService],
})
export class SidebarBasicDemo {
  title = 'WECO';
  notificationSideBarVisible = false;

  constructor(private messageService: MessageService) {
    messageService.messageObserver.subscribe((m: Message | Message[]) => {
      if (!Array.isArray(m)) {
        this.messages.push(m);
      }
      this.messages = [...this.messages];
    });
  }

  onShowNotificationSideBar() {
    this.notificationSideBarVisible = true;
    this.messages = [...this.messages.map(x => ({...x}))];
  }

  count = 0;

  messages: Message[] = [
    // { severity: 'success', summary: 'Success', detail: 'Message Content' },
    // { severity: 'info', summary: 'Info', detail: 'Message Content' },
    // { severity: 'warn', summary: 'Warning', detail: 'Message Content' },
    // { severity: 'error', summary: 'Error', detail: 'Message Content' }
  ];

  longSentence =
    'Let’s end all this nonsense about how long sentences = run-on sentences. You can have a six-word run-on sentence (“I went shopping I ate donuts.”), while most of the sentences below are much, much longer than that and are not run-ons'; //'And let’s end all this nonsense about how long sentences = run-on sentences. You can have a six-word run-on sentence (“I went shopping I ate donuts.”), while most of the sentences below are much, much longer than that and are not run-ons (except for a few examples like Jose Saramago).  But whether the sentence is grammatically correct isn’t nearly as important as whether the sentence is fun or beautiful.'

  showWarn() {
    let detail = 'User Deleted a Weco Rule';
    if (this.count++ % 5 === 0) detail = this.longSentence;
    this.messageService.add({
      severity: 'warn',
      summary: 'User Action',
      detail: detail,
    });
  }

  showSuccess() {
    let detail = 'Weco Rule 123 Saved';
    if (this.count++ % 5 === 0) detail = this.longSentence;
    this.messageService.add({
      severity: 'success',
      summary: 'Service Call',
      detail: detail,
    });
  }

  showError() {
    let detail = 'api-call:get-factories returned 404';
    if (this.count++ % 5 === 0) detail = this.longSentence;
    this.messageService.add({
      severity: 'error',
      summary: 'Service Call',
      detail: detail,
    });
  }
}

html

<div class="main">
  <button type="button" (click)="onShowNotificationSideBar()" label="Show">
    show sidebar
  </button>
  <p-sidebar
    [(visible)]="notificationSideBarVisible"
    position="right"
    [style]="{width:'50em'}"
  >
    <button
      type="button"
      pButton
      pRipple
      (click)="showSuccess()"
      label="S"
      class="p-button-success"
    >
      success
    </button>
    <button
      type="button"
      pButton
      pRipple
      (click)="showWarn()"
      label="W"
      class="p-button-warning"
    >
      warn
    </button>
    <button
      type="button"
      pButton
      pRipple
      (click)="showError()"
      label="E"
      class="p-button-danger"
    >
      error
    </button>
    <h3>Messages</h3>
    <h5>{{messages}}</h5>
    <p-messages [(value)]="messages" [enableService]="false"></p-messages>
  </p-sidebar>
  <p-toast position="center"></p-toast>
</div>

Stackblitz Demo

Upvotes: 3

Related Questions