meals-made-easy-app/src/app/service/recipe.service.ts

84 lines
3.0 KiB
TypeScript

import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { firstValueFrom, lastValueFrom, map } from 'rxjs';
import { Recipe, RecipeInfoViews, RecipeView } from '../model/Recipe.model';
import { AuthService } from './auth.service';
import { QueryClient } from '@tanstack/angular-query-experimental';
import { RecipeComment, RecipeComments } from '../model/RecipeComment.model';
import { QueryParams } from '../model/Query.model';
import { EndpointService } from './endpoint.service';
@Injectable({
providedIn: 'root',
})
export class RecipeService {
private readonly http = inject(HttpClient);
private readonly authService = inject(AuthService);
private readonly queryClient = inject(QueryClient);
private readonly endpointService = inject(EndpointService);
public getRecipes(): Promise<Recipe[]> {
return firstValueFrom(
this.http
.get<RecipeInfoViews>('http://localhost:8080/recipes')
.pipe(map((res) => res.content)),
);
}
public getRecipeView(username: string, slug: string): Promise<RecipeView> {
return firstValueFrom(
this.http.get<RecipeView>(`http://localhost:8080/recipes/${username}/${slug}`),
);
}
private getRecipeUrl(recipeView: RecipeView): string {
return `http://localhost:8080/recipes/${recipeView.recipe.owner.username}/${recipeView.recipe.slug}`;
}
public async toggleStar(recipeView: RecipeView): Promise<void> {
if (this.authService.accessToken()) {
if (recipeView.isStarred) {
await lastValueFrom(this.http.delete(this.getRecipeUrl(recipeView) + '/star'));
} else {
await lastValueFrom(this.http.post(this.getRecipeUrl(recipeView) + '/star', null));
}
await this.queryClient.invalidateQueries({
queryKey: ['recipe', recipeView.recipe.owner.username, recipeView.recipe.slug],
});
} else {
throw new Error('Cannot star a recipe when not logged in.');
}
}
public getComments(
username: string,
slug: string,
queryParams?: QueryParams,
): Promise<RecipeComments> {
return firstValueFrom(
this.http.get<RecipeComments>(
this.endpointService.getUrl('recipes', [username, slug, 'comments'], queryParams),
),
);
}
public async addComment(
username: string,
slug: string,
commentText: string,
): Promise<RecipeComment> {
const comment = await firstValueFrom(
this.http.post<RecipeComment>(
`http://localhost:8080/recipes/${username}/${slug}/comments`,
{
text: commentText,
},
),
);
await this.queryClient.invalidateQueries({
queryKey: ['recipeComments', username, slug],
});
return comment;
}
}