2

I have successfully implemented ng-bootstrap table complete example.
Object deletion from DOM and database are working, but I can't find a way to delete row from view. In order to see the changes page reload is required. Please notice, that delete function is and should be triggered, from ng-bootstrap modal dialog confirm button.

I can't call data$ from the for loop like in the bellow approach or similar ones, because todo(or what ever) is observable todos$,

<!-- html -->
<tr *ngFor="let todo of tableService.todos$ | async;">
// typescript
deleteRow(id){
  for(let i = 0; i < this.data.length; ++i){
    if (this.data[i].id === id) {
        this.data.splice(i,1);
    }
  }
}

Could someone point me to the right direction, please.

I have this chunk of code:

deleteTodo(id: string) {
  this.todoService.deleteTodo(id)
    .subscribe(data => {
        console.log(data); // print message from server
    },
        error => console.log(error)
    );
  this.tableService.todoArray = this.tableService.todoArray.filter(elem => elem._id !== id);
  this.todoLength--;
  this.modalService.dismissAll();
  console.log('filtered array: ' + this.tableService.todoArray.length);
  console.log('id: ' + id);
}

This function deletes todo item from database and filter method deletes todo from an array. Please look at the screenshot bellow.

enter image description here

repo to my app source code:
https://github.com/SrdjanMilic/NG-Bootstrap-Todo-list

Srdjan Milic
  • 328
  • 2
  • 14

2 Answers2

2

Angular change detection doesn't work for splice because it does not change the reference to the array variable. You need either to update the variable reference (example below) or trigger change detection manually.

deleteRow(id) {
   this.data = this.data.filter(elem => elem.id !== id);
}
IAfanasov
  • 4,775
  • 3
  • 27
  • 42
  • Please take a look at edited question, I have added more info... I have tried `this.tableService.todoArray.filter(el => el._id !== id);` somewhere in deleteTodo() but nothing has happen. Maybe I wrote it wrong, or something else is missing. It seems to me really weird. Thank you very much for taking your time. – Srdjan Milic Mar 15 '20 at 07:09
  • I don't have access to your repo. stabblitz usually easy to use in such cases. have you tried this one? this.tableService.todoArray = this.tableService.todoArray.filter(el => el._id !== id); – IAfanasov Mar 15 '20 at 08:34
  • I'm really sorry. I forgot to change access from private to public. There is a bunch of components in the project, so I find time consuming to copy them all to stackblitz. Also, there is a node server as well. Anyway, please take a look at repo now. P.S. I have tried above with no luck. If this is meaningful, the ng-bootstrap api use some method to **refresh** the table. It can be triggered from the search input field. When it's triggered, the row vanish and there is no need to refresh the page. – Srdjan Milic Mar 17 '20 at 06:37
  • This solution doesn't work at all. Something else is not right here. – Srdjan Milic May 05 '20 at 04:45
  • it would be nice to be able to reproduce the issue. most likely smg else leads to such a bug – IAfanasov May 05 '20 at 08:19
0

This is the code that works:

todo-list.component.ts

export class TodoListComponent implements OnInit {
  todos$: Observable<Todo[]>;
  total$: Observable<number>;

  @ViewChildren(NgbdSortableHeader) headers: QueryList<NgbdSortableHeader>;

  constructor(private todoService: TodoService, private router: Router, private modalService: NgbModal,
              public tableService: TableService, public updateTodoComponent: UpdateTodoComponent,
              public myBootstrapModalCoomponent: MyBootstrapModalComponent, private ref: ChangeDetectorRef) {
    this.todos$ = this.tableService.todos$;
    this.total$ = this.tableService.total$;
  }

...

deleteTodo(id: string) {
  this.todoService.deleteTodo(id)
    .subscribe(todo => {
      console.log(todo); // print message from server
    },
      error => console.log(error)
    );
  this.todos$.subscribe(todos => {
    for (let i = 0; i < todos.length; i++) {
      if (todos[i]._id === id) {
        todos.splice(i, 1);
      }
    }
  });
  this.tableService.todoArray.length--;
  this.modalService.dismissAll();
}

table.service.ts

...
private _todos$ = new BehaviorSubject<Todo[]>([]);

get todos$() {
  return this._todos$.asObservable();
}
...
Srdjan Milic
  • 328
  • 2
  • 14