You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
10 KiB
310 lines
10 KiB
import { Injectable } from '@angular/core'; |
|
import axios, { AxiosInstance, AxiosResponse } from 'axios'; |
|
import { environment } from 'src/environments/environment'; |
|
|
|
import { Answer } from '../enums/answer.enum'; |
|
import { Poll } from '../models/poll.model'; |
|
import { HttpClient } from '@angular/common/http'; |
|
import { Observable, Subscription } from 'rxjs'; |
|
import { ToastService } from './toast.service'; |
|
import { LoaderService } from './loader.service'; |
|
import { Stack } from '../models/stack.model'; |
|
|
|
const apiVersion = environment.api.versionToUse; |
|
const currentApiRoutes = environment.api.version[apiVersion]; |
|
const apiBaseHref = environment.api.version[apiVersion].baseHref; |
|
|
|
const apiEndpoints = environment.api.endpoints; |
|
|
|
@Injectable({ |
|
providedIn: 'root', |
|
}) |
|
export class ApiService { |
|
private axiosInstance: AxiosInstance; |
|
private readonly pollsEndpoint = apiEndpoints.polls.name; |
|
private readonly answersEndpoint = apiEndpoints.polls.answers.name; |
|
private readonly commentsEndpoint = apiEndpoints.polls.comments.name; |
|
private readonly slugsEndpoint = apiEndpoints.polls.slugs.name; |
|
private readonly usersEndpoint = apiEndpoints.users.name; |
|
private readonly usersPollsEndpoint = apiEndpoints.users.polls.name; |
|
private readonly usersPollsSendEmailEndpoint = apiEndpoints.users.polls.sendEmail.name; |
|
private baseHref: string; |
|
private static loaderService: LoaderService; |
|
|
|
constructor(private http: HttpClient, private toastService: ToastService, private loaderService: LoaderService) { |
|
this.baseHref = apiBaseHref; |
|
|
|
this.axiosInstance = axios.create({ baseURL: apiBaseHref }); |
|
this.axiosInstance.defaults.timeout = 2500; |
|
this.axiosInstance.defaults.headers.post['Content-Type'] = 'application/json'; |
|
this.axiosInstance.defaults.headers.post['Accept'] = 'application/json'; |
|
this.axiosInstance.defaults.headers.post['Charset'] = 'UTF-8'; |
|
// this.axiosInstance.defaults.headers.post['Accept-Charset'] = 'UTF-8'; |
|
this.axiosInstance.defaults.headers.post['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'; |
|
this.axiosInstance.defaults.headers.post['Referrer-Policy'] = 'origin-when-cross-origin'; |
|
this.axiosInstance.defaults.headers.post['Access-Control-Allow-Origin'] = '*'; |
|
this.axiosInstance.defaults.headers.post['Allow-Origin'] = '*'; |
|
this.axiosInstance.defaults.headers.post['Access-Control-Allow-Headers'] = |
|
'Origin, X-Requested-With, Content-Type, Accept'; |
|
|
|
console.log('this.axiosInstance.defaults.headers', this.axiosInstance.defaults.headers); |
|
} |
|
|
|
////////////////////// |
|
// CREATE OR UPDATE // |
|
////////////////////// |
|
|
|
///////////////////// |
|
/** |
|
* prepare headers like the charset and json type for any call to the backend |
|
* @param bodyContent? |
|
*/ |
|
static makeHeaders(bodyContent?: any) { |
|
const headerDict = { |
|
Charset: 'UTF-8', |
|
// 'Content-Type': 'application/json', |
|
// Accept: 'application/json', |
|
'Access-Control-Allow-Origin': '*', |
|
'Content-Type': 'application/json', |
|
mode: 'no-cors', |
|
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', |
|
'Access-Control-Allow-Headers': 'Accept,Accept-Language,Content-Language,Content-Type', |
|
// 'Access-Control-Allow-Origin': '*', |
|
}; |
|
|
|
return { |
|
headers: headerDict, |
|
body: bodyContent, |
|
}; |
|
} |
|
|
|
public async createPoll(poll: Poll): Promise<Subscription> { |
|
// this.loaderService.setStatus(true); |
|
console.log('createPoll config', poll); |
|
return this.axiosInstance.post( |
|
`${this.baseHref}${currentApiRoutes['api_new_poll']}`, |
|
poll, |
|
ApiService.makeHeaders() |
|
); |
|
} |
|
|
|
/** |
|
* send a new vote stack |
|
* @param vote_stack |
|
*/ |
|
public sendNewVoteStackOfPoll(vote_stack: Stack): Promise<void> { |
|
// api_new_vote_stack POST ANY ANY /api/v1/poll/{id}/answer |
|
|
|
console.log('vote_stack', vote_stack); |
|
console.log('this.baseHref', this.baseHref); |
|
const headers = ApiService.makeHeaders(vote_stack); |
|
console.log('headers', headers); |
|
const url = `${this.baseHref}/vote-stack/`; |
|
|
|
const axiosconf = { |
|
url, |
|
method: 'POST', |
|
body: vote_stack, |
|
headers, |
|
}; |
|
|
|
return this.axiosInstance.post(url, vote_stack); |
|
} |
|
|
|
////////// |
|
// READ // |
|
|
|
public async createParticipation( |
|
pollId: string, |
|
choiceLabel: string, |
|
pseudo: string, |
|
response: Answer |
|
): Promise<string> { |
|
try { |
|
return await this.axiosInstance.post(`${this.pollsEndpoint}/${pollId}${this.answersEndpoint}`, { |
|
choiceLabel, |
|
pseudo, |
|
response, |
|
}); |
|
} catch (error) { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
|
|
public async createComment(slug: string, comment: string): Promise<string> { |
|
try { |
|
return await this.axiosInstance.post(`${this.pollsEndpoint}/${slug}${this.commentsEndpoint}`, comment); |
|
} catch (error) { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
|
|
////////// |
|
public async getAllAvailablePolls(): Promise<Poll[]> { |
|
// TODO: used for facilities in DEV, should be removed in production |
|
try { |
|
const response: AxiosResponse<Poll[]> = await this.axiosInstance.get<Poll[]>(`${this.pollsEndpoint}`); |
|
return response?.data; |
|
} catch (error) { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
|
|
public async getPollByCustomUrl(slug: string): Promise<Poll | undefined> { |
|
try { |
|
console.log('fetch API : asking for poll with custom_url=' + slug); |
|
const response: AxiosResponse<Poll> = await this.axiosInstance.get<Poll>(`${this.pollsEndpoint}/${slug}`); |
|
|
|
return response && response.data && !Array.isArray(response.data) ? response.data : undefined; |
|
} catch (error) { |
|
if (error.response?.status === 404) { |
|
return undefined; |
|
} else { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
} |
|
|
|
public async getPollByCustomUrlWithHash(slug: string, hash: string): Promise<Poll | undefined> { |
|
try { |
|
const response: AxiosResponse<Poll> = await this.axiosInstance.get<Poll>( |
|
`${this.pollsEndpoint}/${slug}/pass/${hash}` |
|
); |
|
console.log('fetch API : asking for poll with custom_url=' + slug, { response }); |
|
|
|
return response && response.data && !Array.isArray(response.data) ? response.data : undefined; |
|
} catch (error) { |
|
if (error.response?.status === 404) { |
|
return undefined; |
|
} else { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
} |
|
|
|
public async getSlug(slug: string): Promise<boolean> { |
|
try { |
|
// TODO: scenario should be : if we can get this custom_url, 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 { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
} |
|
|
|
//////////// |
|
// UPDATE // |
|
|
|
public async sendUpdateVoteStack(vote_stack: Stack) { |
|
try { |
|
return await this.axiosInstance.patch( |
|
`${this.baseHref}/vote-stack/${vote_stack.id}/token/${vote_stack.owner.modifier_token}`, |
|
vote_stack |
|
); |
|
} catch (error) { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
public findMyPollsByEmail(email: string): Promise<any> { |
|
return this.axiosInstance.get<any>(`${this.baseHref}/poll/owner/${email}`); |
|
} |
|
public async updateAnswer(slug: string, choiceLabel: string, pseudo: string, answer: Answer): Promise<string> { |
|
try { |
|
return await this.axiosInstance.patch(`${this.baseHref}/${slug}${this.answersEndpoint}`, { |
|
choiceLabel, |
|
pseudo, |
|
answer, |
|
}); |
|
} catch (error) { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
//////////// |
|
// DELETE // |
|
|
|
//////////// |
|
|
|
//////////// |
|
public async deletePoll(slug: string): Promise<boolean> { |
|
try { |
|
const response: AxiosResponse = await this.axiosInstance.delete(`${this.pollsEndpoint}/${slug}`); |
|
return response?.status === 204; |
|
} catch (error) { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
|
|
public async deletePollAnswers(slug: string): Promise<boolean> { |
|
try { |
|
const response: AxiosResponse = await this.axiosInstance.delete( |
|
`${this.pollsEndpoint}/${slug}${this.answersEndpoint}` |
|
); |
|
return response?.status === 204; |
|
} catch (error) { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
|
|
public async deletePollComments(slug: string): Promise<boolean> { |
|
try { |
|
const response: AxiosResponse = await this.axiosInstance.delete( |
|
`${this.pollsEndpoint}/${slug}${this.commentsEndpoint}` |
|
); |
|
return response?.status === 204; |
|
} catch (error) { |
|
ApiService.handleError(error); |
|
} |
|
} |
|
|
|
///////////////////// |
|
// PRIVATE METHODS // |
|
///////////////////// |
|
private static handleError(error): void { |
|
// this.loaderService.setStatus(true); |
|
if (error.response) { |
|
// The request was made and the server responded with a status code |
|
// that falls out of the range of 2xx |
|
console.error('Error response data', error.response.data); |
|
console.error('Error response status', error.response.status); |
|
console.error('Error response headers', 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('ErrorRequest', error.request); |
|
} else { |
|
// Something happened in setting up the request that triggered an Error |
|
console.log('Error', error.message); |
|
} |
|
console.log(error.config); |
|
// this.loaderService.setStatus(false); |
|
} |
|
public ousideHandleError(error) { |
|
// this.loaderService.setStatus(true); |
|
if (error.response) { |
|
// The request was made and the server responded with a status code |
|
// that falls out of the range of 2xx |
|
console.error('Error response data', error.response.data); |
|
console.error('Error response status', error.response.status); |
|
console.error('Error response headers', 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('ErrorRequest', error.request); |
|
} else { |
|
// Something happened in setting up the request that triggered an Error |
|
console.log('Error', error.message); |
|
} |
|
console.log(error.config); |
|
// this.loaderService.setStatus(false); |
|
} |
|
}
|
|
|