0

I just working on a new Angular 6 WebApp which the whole communication between the components is based on Subjects and Subscriptions.

The whole subscription is implemented in the dashboard component (level 1 under the root). On the Dashboard, the component is a table generated from the C# ASP.NET Core Backend with SignalR web sockets.

Now we implemented edit and delete buttons for each row in this table. The edit button opens an ngx-bootstrap Modal. The Modal opening function takes a single row of information in the param.

Inside this "edit-modal" are some inputs with the date of the row. Now when I save the changes, the data is sent back to the dashboard component which invokes an update method for the row with the .NET Core API.

During this data stream between the edit modal and the dashboard, my subscription invokes 4x times.

I have tried to debug this but don't find any clue what is going on here...

My Service for Communication:

export class CommunicationService {

  private subject = new Subject<any>();

  constructor() { }

  sendData(data: any) {
    this.subject.next({ data });
  }

  removeData() {
    this.subject.next();
  }

  getData(): Observable<any> {
    return this.subject.asObservable();
  }

}

Edit Modal:

sendOrderToDashboard(): void {
    // this.order is a data of singel row. Its a table with different user orders as a row.
    this.communicationService.sendData(this.order);
    this.modalRef.hide();
  }

Dashboard Component

public ngOnInit(): void {
    this.communicationService.getData().subscribe(orderToUpdate => {
      if (orderToUpdate) {
        this.updateOrder(orderToUpdate.data);
        console.log(orderToUpdate.data);
        // this log invokes 4x times
      }
    });
  }

updateOrder(order): void {
    this.orderService.updateOrder(order).subscribe(next => {
      console.log('updated successfully');
      // This log is never executed even when the update is successful
    }, error => {
      console.log('error while updating order');
    });
  }

Update order in the OrderService (Bridge between Angular and SignalR (Backend))

  public updateOrder(order: Order): Observable<Order> {
    if (!this.orderSubjects[order.id]) {
      this.orderSubjects[order.id] = new Subject<Order>();
    }

    this.hubService.invoke(ServerMethod.UpdateOrder, order);

    return this.orderSubjects[order.id].asObservable();
  }

Have anybody a clue why my success log never executed and my its invokes 4x times?

Rohit Sharma
  • 3,304
  • 2
  • 19
  • 34
Pommesloch
  • 492
  • 5
  • 17

3 Answers3

0

You need to unsubscribe the subscription each time when ngOnDestroy method in DashBoardComponent.

DashBoardComponent

private subscription:

updateOrder(order): void {
    if(this.this.subscription){
      this.subscription.unsubscribe();
    }
    this.subscription = this.orderService.updateOrder(order).subscribe(next => {
      console.log('updated successfully');
      // This log is never executed even when the update is successful
    }, error => {
      console.log('error while updating order');
    });
  }

ngOnDestroy(){
   if(this.this.subscription){
      this.subscription.unsubscribe();
   }
}
Suresh Kumar Ariya
  • 9,516
  • 1
  • 18
  • 27
0

For debugging purposes, I have added some more logs to my Dashboard component. I have added a unsubscribe() to my subscription in ngOnDestroy() but this method is never been executed.

updateOrder(order): void {
    console.log('update method is called')
    this.subscription = this.orderService.updateOrder(order).subscribe(next => {
      console.log('updated successfully');
    }, error => {
      console.log('error while updating order');
    });
  }

  public ngOnInit(): void {
    console.log('data is available now');
    this.communicationService.getData().subscribe(orderToUpdate => {
      if (orderToUpdate) {
        this.updateOrder(orderToUpdate.data);
        console.log('update init');
        console.log(orderToUpdate.data);
      }
    });
  }

  public ngOnDestroy(): void {
    if (this.subscription) {
      this.subscription.unsubscribe();
      console.log('successfuly unsubscribe');
    }
  }

It seems like the whole component is initialized 2 times? And the unsubscribe is never executed. I have added a screenshot below with the console.log

Console Logs

Pommesloch
  • 492
  • 5
  • 17
  • Is it possible that your CommunicationService is instantiating multiple times ? Can you put a log in the constructor ? – CornelC Sep 07 '18 at 12:41
0

In your Dashboard Component, I can't see the export class expression, check that you implement OnDestroy.

Your class should look like this

import { Component, OnInit, OnDestroy } from '@angular/core';
export class DashboardComponent implements OnInit, OnDestroy {
    ngOnDestroy(){
       if(this.this.subscription){
          this.subscription.unsubscribe();
       }
    }
    // the rest of your code
}

If you don't implement it, you're just creating a function called ngOnDestroy that won't be executed unless you manually called it.

Ali
  • 2,702
  • 3
  • 32
  • 54