how to push an element to an observable and update UI

663 views Asked by At

Can someone help me out with this? I'm starting to learn about observables and async pipes in angular8.

I'm trying to add an element to my observable and also update my UI. At this moment i have this, it adds my element in the beginning and at the end of my array. What am i doing wrong?

in my component:

    var comment = new Comment();
    this.postService.addComment(commentdto).subscribe((c) => {
      comment = c;
      this.post.subscribe(x => {
        x.comments.push(comment);
        this.post = of(x);
      });
    });
<div *ngIf="post | async as p">
  <div class="post-container border-bottom border-dark mb-2">
    <h3 class="col-sm-12">{{p.text}}</h3>
    <div class="col-sm-12">
      <img class="img-fluid image-height" src="https://localhost:5003/posts/{{p.imageUrl}}" />
      <div class="row" style="margin-left: 0px; margin-top: 2%">
        <a style="margin-right:15px" class="pointer" (click)="vote(true, post)"><i class="fas fa-thumbs-up"></i> {{p.upVotes}}</a>
        <a style="margin-right:15px" class="pointer" (click)="vote(false, post)"><i class="fas fa-thumbs-down"></i> {{p.downVotes}}</a>
      </div>
    </div>
  </div>
  <h5>Comments:</h5>
  <div class="form-group mb-3">
    <textarea [(ngModel)]="addComment" class="form-control" aria-label="With textarea" placeholder="Add comment..."></textarea>
  </div>
  <div>
    <button type="button" class="btn btn-primary ml-auto" (click)="addCommentToPost()">Post</button>
  </div>
  <div *ngFor="let c of p.comments" class="container">
    <div class="row comment-bubble">
      {{c.text}}
    </div>
  </div>
</div>

service:

addComment(comment: EditComment): Observable<Comment> {
    return this.http.post<Comment>(`${this.baseUrl}/AddComment`, comment, this.httpOptionsAuthentication)
      .pipe(catchError(this.handleError));
  }

  handleError(error) {
    let errorMessage = '';
    if (error.error instanceof ErrorEvent) {
      // client-side error
      errorMessage = `Error: ${error.error.message}`;
    } else {
      // server-side error
      errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
    }
    console.log(errorMessage);
    return throwError(errorMessage);
  }
1

There are 1 answers

2
rveerd On BEST ANSWER

You are creating a new observable. You have to emit a new value.

Without seeing the rest of your code, something like:

post: Post; // I am assuming you have a type for a post.
post$ = new Subject<Post>(); // Our observable.
...
this.postService.addComment(commentdto).subscribe((comment) => {
  this.post.comments.push(comment);
  this.post$.next(this.post); // Emit a new value.
});

But this is a bit silly, having both a variable and an observable. It is probably better to not use AsyncPipe in this case.

post: Post;
...
this.postService.addComment(commentdto).subscribe((comment) => {
  this.post.comments.push(comment);
});
<div *ngIf="post">
  <div class="post-container border-bottom border-dark mb-2">
    <h3 class="col-sm-12">{{post.text}}</h3>