简体   繁体   中英

Angular - Update data automatically without Refresh the Page

In my application there is a table that get rows from database.

This is the AJAX CALL (SERVICE)

getPosts(): Observable<Posts[]> {
    return this.http.post<Posts[]>(this.myAppUrl + this.myApiPostsUrl, this.authService.getLoggedUserFromSessionStorage())
      .pipe(
        retry(1),
        catchError(this.errorHandler)
      );
  }

All work perfectly, but my datas dont update automatically, and the user need to refresh the page to see the new rows, how can i do this? I would like do that the new rows are added in the table dynamically... without update the page. This is the table

COMPONENT HTML

    <table *ngIf="(posts$ | async)?.length>0" class="table align-items-center table-flush">
    .....
 <tr *ngFor="let post of (posts$ | async) | filter:authService.filter | paginate: config | orderBy: key : reverse">
              <!--              <td>{{posts.id}}</td>-->
              <td>{{post.title}}</td>
              <td>{{post.body}}</td>
.....
    </table>

COMPONENT TS

ngOnInit() {
    this.loadPosts();
  }

  loadPosts() {
    this.message = 'Loading....';
    this.posts$ = this.postService.getPosts();
    if (this.posts$ == null) {
      this.message = 'No Posts found';
    }
  }

Thanks so much.

in Angular, when you want to update your html, you need to use ngFor to update your data automatically.

<table *ngIf="(posts$ | async)?.length>0" class="table align-items-center table-flush">
   <div *ngFor="let data of datas; let i = index>
      {{ data }}
   </div>
</table>

ngFor will loop on datas and update it when it changes

There are several options. Here is a reactive way of handling this. Any time getPosts is successful, you'll need to refetch the initial data.

To fetch your initial data you will need to wrap your posts$ observable in an action stream:

// create a stream for your post request
private readonly postAction$ = new Subject();

posts$ = this.postAction$.pipe(
  startWith(''),
  concatMap(()=> {
    return this.postService.getPosts(); // this will be your http get request
  }),
)

The startWith operator will cause your get request to fire initially without an observable been passed to your postAction observable.

Your getPosts method now will call this.postAction$.next() on success, that will trigger the refetch of your posts$ observable.

getPosts(): Observable<Posts[]> {
    return this.http.post<Posts[]>(this.myAppUrl + this.myApiPostsUrl, this.authService.getLoggedUserFromSessionStorage())
      .pipe(
        retry(1),
        catchError(this.errorHandler),
        tap(() => this.postAction$.next())
      );
  }

You can see a demo of this. Check the console, you'll see that the get request is fired every time the button is clicked.


With Interval

posts$ = interval(30000)
    .pipe(
      startWith(''),
      switchMap(() => return this.postService.getPosts();)
    )

Interval demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM