0

I have a shopping website made with Angular where you can either delete items from the same products page, or modify them by being sent to a form in another page, and then navigate back to products.

In both cases you have to manually reload the page to show the updated results, is there any way to avoid this and have it update dynamically?

These are the key pieces of code that i have right now:

Products page:

  ngOnInit(): void {
    this.productsService.getProducts().subscribe((res: any) => {
      this.products = res;
    })
  }
  edit(id: string){
    this.productsService.getProductById(id).subscribe((res: any) => {
      this.productsService.product = res;
      this.router.navigate(['/edit']);
    });
  }

  delete(id: string) {
    this.productsService.deleteProduct(id).subscribe((res: any) => {
      this.ngOnInit();
    });
  }

Products service:

  getProducts(){
    return this.http.get(this.url);
  }
  addProduct(newproduct: product){
    return this.http.post(this.url, newproduct);
  }
  getProductById(id: string){
    return this.http.get(this.url + '/' + id);
  }
  editProduct(newproduct: product){
    return this.http.put(this.url + '/' + newproduct.id, newproduct);
  }
  deleteProduct(id: string){
    return this.http.delete(this.url + '/' + id);
  }

Edit page after you submit the new/edited product:

      this.productRegisterForm.reset();
      this.isSubmit = false;
      this.router.navigate(['/products'])

I tried to use window.location.reload in many places (it would loop on the products page onInit, it wouldn't do anything on the Form page with a .then after the navigate and it wouldn't fetch the products correctly if added on the Products service (i wasn't able to in many cases)

krst221
  • 1
  • 3

1 Answers1

0

The search term to research this is RxJs, reactive coding. Recommend looking up async pipe and learning more about observables.

Because you are updating state in your application you need to save the data somehow and replicate deletes and adds locally on this copy of the data. The simplest is a repository on the service you’ve created I.e. an array/object (internal management hidden and up to you) of products you maintain, when you add via api, you add to array etc. Using a RxJs subject and .next method you can expose a RxJs (behavioursubject) variable that emits for each of these changes.

In short, you change this,

  ngOnInit(): void {
    this.productsService.getProducts().subscribe((res: any) => {
      this.products = res;
    })
  }

to this

products$: Observable<IProduct[]> = of()

ngOnInit(): void {
  this.products$ = this.productsService.products$
  this.productsService.getAll()
}

and then use this in the template using the async pipe

{{ products$ | async | json }}

If you want to reach for a library then ngrx is one of the most popular state libraries.

Edit,

  1. You could have a separate repository service and inject into productService but easier to put on the service. You can always refactor later. e.g. https://stackoverflow.com/a/57355485/4711754

  2. E.g.

<ng-container *ngFor="let product of (products$ | async)">
  {{ product | json }}
</ng-container>

Brackets not needed, for clarity only, and you can replace ng-container with div or custom ui component.

Andrew Allen
  • 6,512
  • 5
  • 30
  • 73
  • Question edited – Andrew Allen Dec 05 '22 at 22:26
  • Edit question: The post you linked seems to have a different approach than what you answered me (im pretty new to Angular and never used observables really, my apologies). If i just want to make my website work for now what else do i need? i tried setting up the products$ in the service with the BehaviourSubject and the Obs functions but it was giving me a lot of errors – krst221 Dec 05 '22 at 22:40
  • The link was just to give example of how behavioursubject is used. The angular docs ( tour of heroes) goes through observables, highly recommend – Andrew Allen Dec 05 '22 at 22:43