Search code examples
angularangular-services

Displaying selected error messages that get generated over a period of time in Angular


I want to display messages as and when they get generated. I want to display only selected error messages from the array of errors that I have created. I am using array.filter method to filter the error messages, but that's not working. It is simply showing all the elements in the array.

Here's the service code:

error: any[] = [];

addError() {
    // error gets generated over a period of time
    this.error.push({ msg: 'A', statusText: 'a', status: 25 });
    this.error.push({ msg: 'B', statusText: 'b', status: 35 });
    this.error.push({ msg: 'C', statusText: 'c', status: 45 });
    this.error.push({ msg: 'D', statusText: 'd', status: 55 });
    this.error.push({ msg: 'E', statusText: 'e', status: 65 });
    this.error.push({ msg: 'F', statusText: 'f', status: 75 });

    this.error = this.error.filter(err => err.status > 45);
  }

  getErrors(): any[] {
    console.log(`in the get methog ${JSON.stringify(this.error)}`);
    return this.error;
  }

Here's the parent-component that's displaying the error messages:

  data: any[];

  constructor(private _error: ErrorService) {}

  ngOnInit() {
    this.data = this._error.getErrors();
  }

Here's the child-component that generates errors:

addError() {
    this._info.addInfo();
  }

Note: This addError method is called on the click event of a button.

The issue here is that: Even though I am filtering the error array, I can see all the error messages (A-F) whereas I should only see D, E and F.

Where am I going wrong?? Do I need to use observable to achieve the desired results or I can do it with some modification to the above code?

Here's the link to stackblitz


Solution

  • The issue was with the reference.

    • ngOnInit of parent-component the data holds the reference of the error array.
    • When we will do the array.filter() then error will hold a new reference but not updating in the parent-component.

    Solution We can fix With simple modification in code without using Observable. We can use Observable to fix the problem.

    Step 1: Add a filteredErrors property reader to the ErrorService.

    @Injectable({
      providedIn: 'root'
    })
    export class ErrorService {
    
      error: any[] = [];
    
      addError() {
          this.error.push({ msg: 'A', statusText: 'a', status: 25 });
          this.error.push({ msg: 'B', statusText: 'b', status: 35 });
          this.error.push({ msg: 'C', statusText: 'c', status: 45 });
          this.error.push({ msg: 'D', statusText: 'd', status: 55 });
          this.error.push({ msg: 'E', statusText: 'e', status: 65 });
          this.error.push({ msg: 'F', statusText: 'f', status: 75 });
      }
    
      get filteredErrors() {
        return this.error.filter(err => err.status > 45);
      }
    }
    

    Step 2: Read filteredErrors for iterating over filtered errors. Following are the details of the ParentComponent.

    @Component({
      selector: 'app-parent',
      template: `<p *ngFor="let error of errors">
          First Name: {{ error.msg }} Last Name: {{ error.statusText }}
        </p>
        <app-child></app-child>`
    })
    export class ParentComponent {
    
      constructor(public  _error: ErrorService) {}
    
      get errors() {
        return this._error.filteredErrors || [];
      }
    }
    

    For reference added stackblitz code link.