Home > Software engineering >  Update UI after sending POST request on Angular 13
Update UI after sending POST request on Angular 13

Time:02-10

I have a method to post data and another one to fetch data, each one on it's current button and function. What I'm trying to achieve is to update the posts array when clicking on Send Post. My aproach was to call onFetchPosts in the same function in which I created them, each function works as a unit, but when I tried to call fetch on create, it just wont work

Html File Using Bootstrap 4 and angular template driven forms

    ``` <div >
    <div >
    <div >
      <form #postForm="ngForm" (ngSubmit)="onCreatePost(postForm.value)">
        <div >
          <label for="title">Title</label>
          <input
            type="text"
            
            id="title"
            required
            ngModel
            name="title"
          />
        </div>
        <div >
          <label for="content">Content</label>
          <textarea
            
            id="content"
            required
            ngModel
            name="content"
          ></textarea>
        </div>
        <button
          
          type="submit"
          [disabled]="!postForm.valid"
        >
          Send Post
        </button>
      </form>
      </div>
     </div>
     <hr />
     <div >
     <div >
      <button  (click)="onFetchPosts()">
        Fetch Posts
      </button>
      |
      <button
        
        [disabled]="loadedPosts.length < 1"
        (click)="onClearPosts()"
      >
        Clear Posts
      </button>
      </div>
      </div>
      <div >
      <div >
      <p *ngIf="loadedPosts.length < 1 && !isFetching">No posts available!</p>
      <ul  *ngIf="loadedPosts.length >= 1 && !isFetching">
        <li  *ngFor="let post of loadedPosts">
          <h3>{{ post.title }}</h3>
          <p>{{ post.content }}</p>
        </li>
      </ul>
      <div  *ngIf="isFetching">
        <div >
          <div ></div>
          <div ></div>
          <div ></div>
          <div ></div>
          <div ></div>
          <div ></div>
        </div>
      </div>
      </div>
      </div>
      </div> ```

Ts File, calling the functions made in the service.ts file

    ``` import { Component, OnInit } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Post } from './post.model';  
    import { PostsService } from './posts.service';

    @Component({
     selector: 'app-post',
     templateUrl: './post.component.html',
     styleUrls: ['./post.component.scss']
     })
    export class PostComponent implements OnInit {
   loadedPosts: Post[] = [];
   isFetching = false;

   constructor(private http: HttpClient, private postsService: PostsService) { }

   ngOnInit(): void {
    this.isFetching = true;
    this.postsService.fetchPosts().subscribe(posts => {
      this.isFetching = false;
      this.loadedPosts = posts;
    });
   }

   // Here I'm trying to call fetchPosts after I create one, but the UI won't get updated
   onCreatePost(postData: { title: string; content: string }) {
   this.isFetching = true;
    this.postsService.createAndStorePost(postData.title, postData.content) 
   this.postsService.fetchPosts().subscribe(posts => {
      this.isFetching = false;
      this.loadedPosts = posts;
     });
   }

  onFetchPosts() {
    // Send Http request
    this.isFetching = true;
    this.postsService.fetchPosts().subscribe(posts => {
      this.isFetching = false;
      this.loadedPosts = posts;
     });
     }

    onClearPosts() {
    // Send Http request
    this.postsService.deletePosts().subscribe(() => {
      this.loadedPosts = [];
    });
    }
    } ```

Service.ts, creating functions to create, fetch and delete posts

``` import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { map } from "rxjs/operators";

import { Post } from "./post.model";

@Injectable({providedIn: 'root'})
export class PostsService {

    constructor(private http: HttpClient) {}
    createAndStorePost(title: string, content: string) {
        const postData: Post = {title: title, content: content};
        this.http
        .post<{ name: string }>(
          'https://to my backend at.firebaseio.com/posts.json',
          postData
        )
        .subscribe(responseData => {
          console.log(responseData);
        });
    }
    
    fetchPosts() {
        return this.http
            .get<{ [key: string]: Post }>(
                'https://to my backend at.firebaseio.com/posts.json'
                )
            .pipe(
                map(responseData => { 
                    const postsArray: Post[] = [];
                    for (const key in responseData) {
                    if (responseData.hasOwnProperty(key)) {
                        postsArray.push({ ...responseData[key], id: key });
                    }     
                }
                return postsArray;
            })
        );
    }

    deletePosts() {
        return this.http.delete('https://to my backend at.firebaseio.com/posts.json')
    }
} ``` 

CodePudding user response:

You dont need to subscribe in service. Instead do this

createAndStorePost(title: string, content: string) {
    const postData: Post = { title: title, content: content };
    return this.http
        .post<{ name: string }>(
            'https://to my backend at.firebaseio.com/posts.json',
            postData
        );
}

And then in you component

onCreatePost(postData: { title: string; content: string }) {
    this.isFetching = true;
    this.postsService.createAndStorePost(postData.title, postData.content).subscribe(()=>{
        this.isFetching = false;
        this.onFetchPosts();
    });
}
  • Related