import { Injectable } from '@angular/core'; import axios, { AxiosInstance, AxiosResponse } from 'axios'; import { environment } from 'src/environments/environment'; import { Poll } from '../models/poll.model'; import { User } from '../models/user.model'; @Injectable({ providedIn: 'root', }) export class ApiService { private axiosInstance: AxiosInstance; private readonly pollsEndpoint = environment.api.endpoints.polls.name; private readonly commentsEndpoint = environment.api.endpoints.polls.comments.name; private readonly votesEndpoint = environment.api.endpoints.polls.votes.name; private readonly slugsEndpoint = environment.api.endpoints.polls.slugs.name; private readonly votesStacksEndpoint = environment.api.endpoints.voteStack.name; private readonly usersEndpoint = environment.api.endpoints.users.name; private readonly usersPollsEndpoint = environment.api.endpoints.users.polls.name; private readonly usersPollsSendEmailEndpoint = environment.api.endpoints.users.polls.sendEmail.name; constructor() { this.axiosInstance = axios.create({ baseURL: environment.api.baseHref }); } //////////// // CREATE // //////////// public async savePoll(poll: Poll): Promise { try { await this.axiosInstance.post(`${this.pollsEndpoint}`, { params: { config: poll.config } }); } catch (error) { this.handleError(error); } } public async saveVote(poll: Poll): Promise { try { // TODO: add the votestack in the params await this.axiosInstance.post(`${this.pollsEndpoint}/${poll.id}${this.votesEndpoint}`, { params: { voteStack: {} }, }); } catch (error) { this.handleError(error); } } public async saveComment(poll: Poll, comment: string): Promise { try { // TODO: add the comment in the params await this.axiosInstance.post(`${this.pollsEndpoint}/${poll.id}${this.commentsEndpoint}`, { params: { comment }, }); } catch (error) { this.handleError(error); } } ////////// // READ // ////////// public async isSlugAvailable(slug: string): Promise { try { // TODO: scenario should be : if we can get this slug, it exists. if not, it doesn't. It's just a GET. const response: AxiosResponse = await this.axiosInstance.get( `${this.pollsEndpoint}${this.slugsEndpoint}/${slug}` ); if (response?.status !== 404) { return false; } } catch (error) { if (error.response?.status === 404) { return true; } else { this.handleError(error); } } } public async sendEmailToUserOfItsPollsList(user: User): Promise { // If user is not authenticated: the list of polls is send to user's email by the backend. try { await this.axiosInstance.get( `${this.usersEndpoint}/${user.email}${this.usersPollsEndpoint}${this.usersPollsSendEmailEndpoint}` ); } catch (error) { this.handleError(error); } } public async getPollsByUserEmail(user: User): Promise { // If user is authenticated : retrieve polls & display directly in frontend. // TODO: Backend should handle this case. Actually the endpoint doesn't exist in backend. try { const response: AxiosResponse = await this.axiosInstance.get( `${this.usersEndpoint}/${user.email}${this.usersPollsEndpoint}` ); return response?.data; } catch (error) { this.handleError(error); } } public async getPollByIdentifier(identifier: string): Promise { // TODO: identifier should be decided according to backend : Id || Slug ? try { const response: AxiosResponse = await this.axiosInstance.get( `${this.pollsEndpoint}/${identifier}` ); return response?.data; } catch (error) { if (error.response?.status === 404) { return undefined; } else { this.handleError(error); } } } //////////// // UPDATE // //////////// public async updatePoll(poll: Poll): Promise { try { // TODO: implement the params when entities are finalized. await this.axiosInstance.put(`${this.pollsEndpoint}/${poll.id}`, { params: { voteStack: {}, token: '' }, }); } catch (error) { this.handleError(error); } } public async updateVote(voteStack: any): Promise { try { // TODO: implement the params when entities are finalized. await this.axiosInstance.patch(`${this.votesStacksEndpoint}/${voteStack.id}`, { params: { voteStack: {}, token: '' }, }); } catch (error) { this.handleError(error); } } //////////// // DELETE // //////////// public async deletePoll(poll: Poll): Promise { try { await this.axiosInstance.delete(`${this.pollsEndpoint}${poll.id}`, {}); } catch (error) { this.handleError(error); } } public async deletePollVotes(poll: Poll): Promise { try { // TODO: update endpoint in Backend await this.axiosInstance.delete(`${this.pollsEndpoint}${poll.id}${this.votesEndpoint}`); } catch (error) { this.handleError(error); } } public async deletePollComments(poll: Poll): Promise { try { // TODO: modify endpoint in Backend await this.axiosInstance.delete(`${this.pollsEndpoint}${poll.id}${this.commentsEndpoint}`); } catch (error) { this.handleError(error); } } ///////////////////// // PRIVATE METHODS // ///////////////////// private handleError(error): void { if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else if (error.request) { // The request was made but no response was received // `error.request` is an instance of XMLHttpRequest in the browser and an instance of // http.ClientRequest in node.js console.log(error.request); } else { // Something happened in setting up the request that triggered an Error console.log('Error', error.message); } console.log(error.config); } }