Angular 9 Global Alert not being triggered (nested outlet)

Issue

I am following this tutorial that has implemented a global Alert class and service to handle all erros in the app. I’m trying to implement this alert on the login component only, but the error is not being triggered and Im kind of lost because all of this has to do with nested outlets so i’m not sure what is goin on

The alert Service (all with bootstrap)

 private subject = new Subject<Alert>()
  private defaultId = 'default-alert';


  onAlert(id = this.defaultId): Observable<Alert> {
    return this.subject.asObservable().pipe(filter(x => x && x.id === id));
  }

alert(alert: Alert) {
  alert.id = alert.id || this.defaultId;
  this.subject.next(alert);
}

clear(id = this.defaultId) {
  this.subject.next(new Alert({ id }));
}

  success(message: string, options?: any) {
    this.alert(new Alert({ ...options, type: AlertType.Success, message }));
  }

  error(message: string, options?: any) {
    this.alert(new Alert({ ...options, type: AlertType.Error, message }));
  }
    //other methods identical for info, etc

The alert component TS:

export class AlertComponent implements OnInit {
  @Input() id = 'default-alert';
  @Input() fade = true;

  alerts: Alert[] = [];
  alertSubscription: Subscription;
  routeSubscription: Subscription;
  constructor(private alertService: AlertService, private router: Router) { }

  ngOnInit(): void {
    this.alertSubscription = this.alertService.onAlert(this.id)
      .subscribe(alert => {
        if (!alert.message) {
          this.alerts = this.alerts.filter(x => x.keepAfterRouteChange);

          this.alerts.forEach(x => delete x.keepAfterRouteChange);
          return;
        }

        this.alerts.push(alert);
        console.log(this.alerts)

        if (alert.autoClose) {
          setTimeout(() => this.removeAlert(alert), 3000);
        }
      });

    this.routeSubscription = this.router.events.subscribe(event => {
      if (event instanceof NavigationStart) {
        this.alertService.clear(this.id);
      }
    });
  }

And some other methods about setting up bootstrap classes, and onDestroy lifeCycle

Now, this is the Alert Class HTML. The “p” tag displaying “alert works!” is visible all over the app(child routes), but not in the login component when I catch the error upon subscription

    <p>Alert Works!</p> 
    <div *ngFor="let alert of alerts" class="{{cssClass(alert)}}">
        <a class="close" (click)="removeAlert(alert)">&times;</a>
        <span [innerHTML]="alert.message"></span>
    </div>

And My Nav-bar, where I have the nested outlet and the reference to the alert component:

<div class="container">
    <app-alert></app-alert>
    <router-outlet></router-outlet>
  </div>

The implementation on the Login Component:

onSubmit() {

    this.alertService.clear();


    if (this.loginForm.invalid) return;




    this.auth.login(credentials)
      .pipe(first())
      .subscribe(data => {
        let returnUrl = this.route.snapshot.queryParamMap.get('returnUrl');
        this.alertService.success('Login successful', { keepAfterRouteChange: true });
        this.router.navigate(['/home' || returnUrl], { relativeTo: this.route });
      }, error => {
        this.alertService.error(error);
        console.log(error)
        //this.loginError=true;
      })

  }

Problably this has to do with the routing configuration? I hide the menu bar with routing. This is my main routing file:

export const routes: Routes = [
  {
    path: '', component: NavbarComponent,
    children: [
      { path: 'home', component: HomeComponent },
      { path: 'admin', loadChildren: adminModule, canLoad: [AuthGuardService], canActivate: [AdminAuthGuardService] },
      { path: 'detail/:id', component: DetailComponent, canActivate: [AuthGuardService] },
      { path: 'edit/:id', component: RegisterComponent, canDeactivate: [EditUserGuardService] },
      { path: '', redirectTo: 'home', pathMatch: 'full' },
    ]

  },
  { path: 'register', component: RegisterComponent },

  { path: 'login', component: LoginComponent },

  { path: '**', pathMatch: 'full', redirectTo: 'login' },

];

At this point I cant figure out why the alarm isn’t triggered. The code seems correct to me, I can’t see any logic error on this implementation…Can someone take a look? Thank you

Solution

Please move <app-alert></app-alert> in app.component.html

Answered By – Aakash Garg

Answer Checked By – Robin (AngularFixing Admin)

Leave a Reply

Your email address will not be published.