Skip to content

Instantly share code, notes, and snippets.

@oops-wrong
Created April 10, 2017 16:01
Show Gist options
  • Save oops-wrong/11b7a6a871dde102f80b506db09f1104 to your computer and use it in GitHub Desktop.
Save oops-wrong/11b7a6a871dde102f80b506db09f1104 to your computer and use it in GitHub Desktop.
import {Cast} from '../helpers/cast';
import {
QnAnswer,
QnHelper,
QnOption,
QnQuestion,
QnTask,
QnTest
} from '../models/qn.model';
import {
QuestionnaireView,
QuestionnaireAvailableName,
QuestionnaireName,
RawQuestionnaire,
UserQuestionnaire
} from '../models/questionnaire.model';
export class QuestionnaireService {
public static $inject = [
'$http',
'$q',
'ApiFactory'
];
public questionnaires: QuestionnaireView[] = [];
public qnTests: QnTest[] = [];
constructor(
private $http: ng.IHttpService,
private $q: ng.IQService,
private api: Restangular.IService
) {
this.buildQuestionnaires();
}
public createOrUpdateQnAnswer(qnAnswer: QnAnswer): QnAnswerLoader {
QnHelper.normalizeQnAnswer(qnAnswer);
if (QnHelper.isNewQnAnswer(qnAnswer)) {
return this.createQnAnswer(qnAnswer);
}
return this.updateQnAnswer(qnAnswer);
}
public finishQuestionnaire(userQuestionnaire: UserQuestionnaire): UserQuestionnaireLoader {
let qnLoader = this.finishQuestionnaireRequest(userQuestionnaire);
return this.setUserQuestionnaire(qnLoader);
}
public getQuestionnaire(name: QuestionnaireAvailableName): QuestionnaireView {
return _.find(this.questionnaires, ['name', name]);
}
public getQustionText(questionnaireName: string): ng.IPromise<any> {
let textUrl = `/json/qestion-text/${questionnaireName}.json`;
return this.$http.get(textUrl);
}
public static getRawQuestionnaires(): RawQuestionnaire[] {
return [
{
name: QuestionnaireName.psychological,
introTemplate: require('../templates/questionnaire/psychological/intro.jade'),
questionnaireTemplate: require('../templates/questionnaire/psychological/questionnaire.jade'),
},
{
name: QuestionnaireName.verbal,
introTemplate: require('../templates/questionnaire/verbal/intro.jade'),
questionnaireTemplate: require('../templates/questionnaire/verbal/questionnaire.jade'),
},
{
name: QuestionnaireName.numerical,
introTemplate: require('../templates/questionnaire/numerical/intro.jade'),
questionnaireTemplate: require('../templates/questionnaire/numerical/questionnaire.jade'),
},
{
name: QuestionnaireName.en,
introTemplate: require('../templates/questionnaire/foreign/intro.jade'),
questionnaireTemplate: require('../templates/questionnaire/foreign/questionnaire.jade'),
},
{
name: QuestionnaireName.es,
introTemplate: require('../templates/questionnaire/foreign/intro.jade'),
questionnaireTemplate: require('../templates/questionnaire/foreign/questionnaire.jade'),
},
{
name: QuestionnaireName.it,
introTemplate: require('../templates/questionnaire/foreign/intro.jade'),
questionnaireTemplate: require('../templates/questionnaire/foreign/questionnaire.jade'),
},
{
name: QuestionnaireName.de,
introTemplate: require('../templates/questionnaire/foreign/intro.jade'),
questionnaireTemplate: require('../templates/questionnaire/foreign/questionnaire.jade'),
},
{
name: QuestionnaireName.fr,
introTemplate: require('../templates/questionnaire/foreign/intro.jade'),
questionnaireTemplate: require('../templates/questionnaire/foreign/questionnaire.jade'),
},
];
}
public loadQnEntities(questionnaireName: QuestionnaireAvailableName): ng.IPromise<QnEntities> {
let qnEntitiesLoader = new QnEntitiesLoader();
qnEntitiesLoader.qnAnswers = this.loadQnAnswers(questionnaireName);
qnEntitiesLoader.qnOptions = this.loadQnOptions(questionnaireName);
qnEntitiesLoader.qnQuestions = this.loadQnQuestions(questionnaireName);
qnEntitiesLoader.qnTasks = this.loadQnTasks(questionnaireName);
return this.$q.all(qnEntitiesLoader);
}
public loadQnTests(): QnTestsLoader {
if (!_.isEmpty(this.qnTests)) {
return this.$q(resolve => {
resolve(this.qnTests);
});
}
let loader = this.fetchQnTests();
return this.setQnTests(loader);
}
public loadUserQuestionnaires(): UserQuestionnairesLoader {
let qnLoader = this.fetchUserQuestionnaires();
return this.setUserQuestionnaires(qnLoader);
}
public startQuestionnaire(test: QnTest): UserQuestionnaireLoader {
let qnLoader = this.createQuestionnaire(test);
return this.setUserQuestionnaire(qnLoader);
}
private buildQuestionnaires() {
let rawQuestionnaires = QuestionnaireService.getRawQuestionnaires();
this.setQuestionnaires(rawQuestionnaires);
}
private clearAndCast<T>(entities: T[], Model: new() => T): T[] {
let resultEntities = _.map(entities, entity => this.api.stripRestangular(entity));
Cast.castObjectsToModels(resultEntities, Model);
return resultEntities;
}
private clearAndCastOne<T>(entity: T, Model: new() => T): T {
let resultEntity = this.api.stripRestangular(entity);
return _.assignIn(new Model(), resultEntity);
}
private createQnAnswer(qnAnswer: QnAnswer): QnAnswerLoader {
return this.api
.one('tests')
.all('user-answers')
.post(qnAnswer)
.then((qnEntity: QnAnswer) => this.clearAndCastOne(qnEntity, QnAnswer as new() => QnAnswer));
}
private createQuestionnaire(test: QnTest): UserQuestionnaireLoader {
let createObj = {
test: {
id: test.id,
name: test.name
},
finished_at: null
};
return this.api
.one('tests')
.all('user-tests')
.post(createObj);
}
private fetchQnTests(): QnTestsLoader {
return this.api
.all('tests')
.getList();
}
private fetchUserQuestionnaires(): UserQuestionnairesLoader {
return this.api
.one('tests')
.all('user-tests')
.getList();
}
private finishQuestionnaireRequest(userQuestionnaire: UserQuestionnaire): UserQuestionnaireLoader {
userQuestionnaire.finished_at = new Date();
return this.api
.one('tests')
.one('user-tests', userQuestionnaire.id)
.patch(userQuestionnaire);
}
private loadQnAnswers(questionnaireName: QuestionnaireAvailableName): QnAnswersLoader {
return this.api
.all('tests')
.all('user-answers')
.getList({question__task__test__name: questionnaireName})
.then((qnEntities: QnAnswer[]) => this.clearAndCast(qnEntities, QnAnswer));
}
private loadQnOptions(questionnaireName: QuestionnaireAvailableName): QnOptionsLoader {
return this.api
.all('tests')
.all('tasks')
.all('questions')
.all('options')
.getList({question__task__test__name: questionnaireName})
.then((qnEntities: QnOption[]) => this.clearAndCast(qnEntities, QnOption));
}
private loadQnQuestions(questionnaireName: QuestionnaireAvailableName): QnQuestionsLoader {
return this.api
.all('tests')
.all('tasks')
.all('questions')
.getList({task__test__name: questionnaireName})
.then((qnEntities: QnQuestion[]) => this.clearAndCast(qnEntities, QnQuestion));
}
private loadQnTasks(questionnaireName: QuestionnaireAvailableName): QnTasksLoader {
return this.api
.all('tests')
.all('tasks')
.getList({test__name: questionnaireName})
.then((qnEntities: QnTask[]) => this.clearAndCast(qnEntities, QnTask));
}
private setQnTests(loader: QnTestsLoader): QnTestsLoader {
return loader.then((qnEntities: QnTest[]) => {
this.qnTests = this.clearAndCast(qnEntities, QnTest);
return this.qnTests;
});
}
private setQuestionnaires(rawQuestionnaires: RawQuestionnaire[]): void {
_.each(rawQuestionnaires, (rawQuestionnaire: RawQuestionnaire) => {
let questionnaire = new QuestionnaireView(rawQuestionnaire);
this.questionnaires.push(questionnaire);
});
}
private setUserQuestionnaire(qnLoader: UserQuestionnaireLoader): UserQuestionnaireLoader {
return qnLoader.then(
(userQuestionnaire: UserQuestionnaire) => this.setUserQuestionnaireModel(userQuestionnaire)
);
}
private setUserQuestionnaireModel(userQuestionnaire: UserQuestionnaire): UserQuestionnaire {
let cleanUserQuestionnaire = this.api.stripRestangular(userQuestionnaire);
let userQuestionnaireModel = new UserQuestionnaire();
return _.assignIn(userQuestionnaireModel, cleanUserQuestionnaire);
}
private setUserQuestionnaires(qnLoader: UserQuestionnairesLoader): UserQuestionnairesLoader {
return qnLoader.then((userQuestionnaires: UserQuestionnaire[]) => {
return _.map(userQuestionnaires, userQuestionnaire => this.setUserQuestionnaireModel(userQuestionnaire));
});
}
private updateQnAnswer(qnAnswer: QnAnswer): QnAnswerLoader {
return this.api
.one('tests')
.one('user-answers', qnAnswer.id)
.patch(qnAnswer)
.then((qnEntity: QnAnswer) => this.clearAndCastOne(qnEntity, QnAnswer as new() => QnAnswer));
}
}
export class QnEntities {
qnAnswers: QnAnswer[];
qnOptions: QnOption[];
qnQuestions: QnQuestion[];
qnTasks: QnTask[];
}
export class QnEntitiesLoader {
qnAnswers: QnAnswersLoader;
qnOptions: QnOptionsLoader;
qnQuestions: QnQuestionsLoader;
qnTasks: QnTasksLoader;
[index: string]: ng.IPromise<any>;
}
export abstract class QnLocaleStorage {
public static resetQnParams(params: QnStorageModel) {
this.setStartTime(params.timer);
this.setListeningFlag(params.listening);
this.setReadingFlag(params.reading);
localStorage.setItem(QnStorageName.listeningCount, '0');
}
public static setListeningFlag(listening: boolean): void {
localStorage.setItem(QnStorageName.listeningFlag, _.toString(listening));
}
public static setReadingFlag(reading: boolean): void {
localStorage.setItem(QnStorageName.readingFlag, _.toString(reading));
}
public static setStartTime(timer: number): void {
localStorage.setItem(QnStorageName.startTime, timer.toString());
};
public static getListeningFlag(): boolean {
return this.castToBoolean(localStorage.getItem(QnStorageName.listeningFlag));
}
public static getReadingFlag(): boolean {
return this.castToBoolean(localStorage.getItem(QnStorageName.readingFlag));
}
public static getStartTime(): number {
return _.toNumber(localStorage.getItem(QnStorageName.startTime));
};
private static castToBoolean(item: string): boolean {
return item === 'true';
}
}
export class QnStorageName {
static readonly startTime = 'startTime';
static readonly listeningCount = 'listeningCount';
static readonly listeningFlag = 'listeningFlag';
static readonly readingFlag = 'readingFlag';
}
export class QnStorageModel {
timer: number = 0;
listening: boolean = false;
reading: boolean = false;
}
export type QnAnswersLoader = ng.IPromise<QnAnswer[]>;
export type QnOptionsLoader = ng.IPromise<QnOption[]>;
export type QnQuestionsLoader = ng.IPromise<QnQuestion[]>;
export type QnTasksLoader = ng.IPromise<QnTask[]>;
export type QnTestsLoader = ng.IPromise<QnTest[]>;
export type QnAnswerLoader = ng.IPromise<QnAnswer>;
export type UserQuestionnaireLoader = ng.IPromise<UserQuestionnaire>;
export type UserQuestionnairesLoader = ng.IPromise<UserQuestionnaire[]>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment