UNPKG

anonymous-student

Version:

Anonymous student is used to retrieve and save information from our website users.

134 lines (100 loc) 3.67 kB
import { ITokenBasedSessionService } from '@studyportals/student-interfaces'; import { IStudent, StudentField } from '@studyportals/studentdomain'; import config from 'config'; import { LastStateChangeHash, StudentClient } from '../interfaces/student-client'; export class StudentAPIClient implements StudentClient { constructor(private sessionService: ITokenBasedSessionService) { } private requestMap: Map<StudentField, Promise<any>> = new Map<StudentField, Promise<any>>(); private get fetch(): any { return fetch; } public async getData(studentFields: StudentField[]): Promise<IStudent> { const actions = this.getActiveDataRequestsAndFieldsToRequest(studentFields); const activeDataRequests = actions.activeDataRequests; const studentFieldsToRequest = actions.studentFieldsToRequest; if (studentFieldsToRequest.length > 0) { activeDataRequests.push(this.retrieveStudentFields(studentFieldsToRequest)); } return this.mergeStudentDataResponses(await Promise.all(activeDataRequests)); } private async patchData(body: object): Promise<LastStateChangeHash> { const request = await fetch(`${config.STUDENTAPI_BASE_URL}/data`, { method: 'PATCH', headers: { Authorization: await this.getAccessToken(), }, body: JSON.stringify(body), }); if (!request.ok) { throw new Error('Failed to patch student data'); } const responseBody = await request.json(); return responseBody[StudentField.LAST_STATE_CHANGE_HASH]; } public setData(studentData: IStudent): Promise<LastStateChangeHash> { return this.patchData(studentData); } public async addToCollection(type: StudentField, items: any[]): Promise<string> { return this.patchData({ [`${type}_add`]: items, }); } public async removeFromCollection(type: StudentField, items: any[]): Promise<string> { return this.patchData({ [`${type}_remove`]: items, }); } private getActiveDataRequestsAndFieldsToRequest(studentFields: StudentField[]): { activeDataRequests: Array<Promise<IStudent>>, studentFieldsToRequest: StudentField[] } { const activeDataRequests: Array<Promise<IStudent>> = []; const studentFieldsToRequest: StudentField[] = []; studentFields.forEach((field) => { const request = this.requestMap.get(field); if (request) { activeDataRequests.push(request); return; } studentFieldsToRequest.push(field); }); return {activeDataRequests, studentFieldsToRequest}; } private async retrieveStudentFields(studentFields: StudentField[]): Promise<IStudent> { const request = this.requestStudentData(studentFields); studentFields.forEach((field) => { this.requestMap.set(field, request); }); const response = await request; studentFields.forEach((field) => { this.requestMap.delete(field); }); return response; } private mergeStudentDataResponses(responses: IStudent[]): IStudent { let data: IStudent = {}; responses.forEach((response) => { data = {...data, ...response}; }); return data; } private async requestStudentData(studentFields: StudentField[]): Promise<IStudent> { const request = await fetch(`${config.STUDENTAPI_BASE_URL}/data?scope=${studentFields.join(',')}`, { headers: { Authorization: await this.getAccessToken(), }, }); if (!request.ok) { throw new Error('Failed to retrieve data from StudentAPI'); } const data = await request.json(); Object.keys(data).forEach((key) => { if (data[key] === null) { data[key] = undefined; } }); return data; } private async getAccessToken(): Promise<string> { const session = await this.sessionService.getSession(); return session!.getAccessToken(); } }