How to update a component in Angular using a backend request, without refreshing the page?

Discussão em 'Angular' iniciado por lordlaurent, Dezembro 13, 2024.

  1. lordlaurent

    lordlaurent Guest

    I want to update my heart icon, which bound to every product, to add to favourites.

    <i class="fa-regular fa-heart" *ngIf="!isFavourite"></i>
    <i class="fa-solid fa-heart" *ngIf="isFavourite"></i>


    To do it I fetch data from the database using a backend request in the service, same with toggling, the backend logic works, the only problem is that I have to refresh the page every time to see the heart icon toggled.

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { environment } from '../../../../environments/environment';
    import { Observable, BehaviorSubject } from 'rxjs';
    import { PrimitiveProduct } from '../models/product.model';

    @Injectable({
    providedIn: 'root'
    })
    export class FavouriteService {
    apiUrl = `${environment.apiUrl}/user/favourites`;

    private favouritesSubject = new BehaviorSubject<PrimitiveProduct[]>([]);
    favourites$ = this.favouritesSubject.asObservable();

    constructor(private http: HttpClient) {}

    fetchFavourites(): void {
    this.http
    .get<PrimitiveProduct[]>(this.apiUrl, { withCredentials: true })
    .subscribe({
    next: (favourites) => {
    this.favouritesSubject.next(favourites);
    },
    error: (err) => console.error('Error fetching favourites:', err)
    });
    }

    toggleFavourite(productUid: string): Observable<string> {
    return this.http.post<string>(
    `${this.apiUrl}?productUid=${productUid}`,
    null,
    { withCredentials: true }
    );
    }

    updateFavouritesLocally(productUid: string) {
    const favourites = this.favouritesSubject.getValue();
    const isAlreadyFavorite = favourites.some((fav) => fav.uid === productUid);

    if (isAlreadyFavorite) {
    this.favouritesSubject.next(
    favourites.filter((fav) => fav.uid !== productUid)
    );
    } else {
    const newFavourite: PrimitiveProduct = {
    uid: productUid
    } as PrimitiveProduct;
    this.favouritesSubject.next([...favourites, newFavourite]);
    }
    }
    }


    This is how I use the toggleFavourite() in product component:

    ngOnInit() {
    this.favouriteService.favourites$.subscribe((favourites) => {
    this.isFavourite = favourites.some((fav) => fav.uid === this.product.uid);
    });
    }

    toggleFavourite(event: Event) {
    event.stopPropagation();

    this.favouriteService.toggleFavourite(this.product.uid).subscribe({
    next: () => {
    this.favouriteService.updateFavouritesLocally(this.product.uid);
    },
    error: (err) => {
    console.error('Error toggling favourite:', err);
    }
    });
    }


    And here in favourites component I display the data in user account section:

    export class FavouritesComponent implements OnInit {
    favouriteProducts: PrimitiveProduct[] = [];

    constructor(private favouriteService: FavouriteService) {}

    ngOnInit() {
    this.favouriteService.fetchFavourites();
    this.favouriteService.favourites$.subscribe((products) => {
    this.favouriteProducts = products;
    });
    }
    }


    I tried the approach with BehaviorSubject, but still I have to refresh page to see the result. Overall adding products to favourites (wishlist) works fine, I just have problem with this annoying refreshing. Should I use something like localStorage or something? Looks like a simple task, but still don't know how to do it.

    Continue reading...

Compartilhe esta Página