0

I'm using Angular Material Data Table in my project. The table is rendering with data

My problem is that I can't update automatically the view when I add new data to the database, every time I should refresh my page.

According to Cdk-table and after reading this tutorial I tried to add live data streaming that to table:

Here's my logique :

import { Component, OnInit } from "@angular/core";
import { MatTableDataSource } from "@angular/material";
import { AjoutprojService } from "../ajoutproj.service";
import { NouveauProjet } from "../models/nouveau-projet";
import { Observable } from "rxjs/Observable";
import 'rxjs/add/observable/merge';
import { DataSource } from "@angular/cdk/collections";



@Component({
  selector: "app-liste-projets",
  templateUrl: "./liste-projets.component.html",
  styleUrls: ["./liste-projets.component.css"]
})
export class ListeProjetsComponent implements OnInit {
  constructor( private ajoutProj: AjoutprojService  ) {}
  nouveauProjet: NouveauProjet[];
  nouveauProjet2: NouveauProjet[];

  stateExression: string = "inactive";

  ngOnInit() {}

  displayedColumns = ["Nom projet", "Lead Projet", "effectif"];
  dataSource = new UserDataSource(this.ajoutProj);
  applyFilter(filterValue: string) {
    filterValue = filterValue.trim(); // Remove whitespace
    filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
    //this.dataSource.filter = filterValue;
  }

}
export class UserDataSource extends DataSource<any> {
  constructor(private ajoutProj: AjoutprojService) {
    super();
  }


/*returns an observable that emits an array of data. 
Whenever the data source emits data to this stream, the table will render an update.*/

  connect(): Observable<NouveauProjet[]> {
    return this.ajoutProj.getAllProj();
  }
  disconnect() {}
}

Here's my service

getAllProj(): Observable<NouveauProjet[]> {
  return this.http.get<NouveauProjet[]>(
    "http://127.0.0.1:8081/api/proj/projets"
  );
}

ajoutProj.getAllProj() service is getting right data. but view is not live updating.

Hamza Haddad
  • 1,175
  • 3
  • 21
  • 36
  • The action should be on that service which you haven't posted. See if this helps: https://stackoverflow.com/questions/47443582/angular-material-table-is-it-possible-to-update-rows-without-entire-table-ref/47501790#47501790. – Preston Dec 31 '17 at 00:21
  • I added my service code , The post is so complicated for me understand but I'll try. – Hamza Haddad Dec 31 '17 at 00:47
  • You can look **Observable<>** [enter link description here](https://angular-2-training-book.rangle.io/handout/observables/using_observables.html) – Ali Can Dec 31 '17 at 22:18

2 Answers2

0

HttpClient doesn't stream. You're getting your data only once.

funkizer
  • 3,224
  • 1
  • 13
  • 16
  • But I'm using observable , how doesn't it stream ? – Hamza Haddad Dec 31 '17 at 22:11
  • All observables aren't "streams". They can also next one value and complete instantly. That's what HttpClient does. It unfortunately doesn't magically make your API real time... How would a service that makes a HTTP call know when your database changes? You need to either poll the api at a time period or look into realtime databases/frameworks like Firebase, FireLoop or GunJS (latter one is for future production use but very much worth a look at) :), or do a websocket implementation yourself. – funkizer Dec 31 '17 at 23:26
  • Thanks for the explication , but What should I add concretely If I have understood I should create a stream which is not an observable. but should I make modification on my service ? if yes what should I add? or it's rather a back end work ? – Hamza Haddad Jan 01 '18 at 21:54
  • Edit: I'll just post another answer as comments don't seem to allow line breaks x) – funkizer Jan 26 '18 at 13:25
  • You mean that if I use firebase I don't need to use express.js ? – Hamza Haddad Jan 26 '18 at 13:30
  • Indeed, you can spin up an app on Firebase with having only a client built, by running one console command. It basically gives you a db with access rules, hosting, authentication, cloud functions for more traditional server endpoints, and a JS api to do everything. Check out Angularfire2 if you wanna try it with Angular, it handles a lot of stuff for you. – funkizer Jan 26 '18 at 13:44
  • I just edited my answer too, there is a way to easily just poll for changes in the DB but it wastes a lot of bandwidth ofc to get all the data over and over again. But hey, that's how it was done in the near past all the time. :D – funkizer Jan 26 '18 at 13:45
0

First you'd need a realtime database / backend solution, then you need to connect to that via websocket and listen to changes in the database.

Some frameworks / libraries that I like and package both the client- and serverside of the equation, and make the whole thing a lot easier:

Fireloop - built on top of Loopback 3 on nodejs, provides Angular SDK creation, ie. same models and APIs on client as on server. Typescript, Observables all the way. It's just awesome.

Firebase - "backendless", totally different way of thinking about a "server" from any REST scheme you might be used to.

Meteor - a monolithic framework, probably also very far from what you're used to.

Of course there's always another (very inefficient) way: Poll your DB every X seconds for changes.

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/switchMap';
export class UserDataSource extends DataSource<any> {
  constructor(private ajoutProj: AjoutprojService) {
    super();
  }

  connect(): Observable<NouveauProjet[]> {
    const initialDelay = 0; // Time to wait before first poll, after the table has connected to this DataSource
    const period = 10000; // Polling period in milliseconds
    return Observable.timer(initialDelay, period)
        .switchMap(() => this.ajoutProj.getAllProj());
  }
  disconnect() {}
}
funkizer
  • 3,224
  • 1
  • 13
  • 16