Skip to content

Commit 9d0ae3c

Browse files
committed
MOBILE-2272 quiz: Convert sync function to async/await
1 parent 46efcc4 commit 9d0ae3c

File tree

1 file changed

+89
-97
lines changed

1 file changed

+89
-97
lines changed

src/addon/mod/quiz/providers/quiz-sync.ts

Lines changed: 89 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { CoreSitesProvider, CoreSitesReadingStrategy } from '@providers/sites';
2121
import { CoreSyncProvider } from '@providers/sync';
2222
import { CoreTextUtilsProvider } from '@providers/utils/text';
2323
import { CoreTimeUtilsProvider } from '@providers/utils/time';
24+
import { CoreUtils } from '@providers/utils/utils';
2425
import { CoreCourseProvider } from '@core/course/providers/course';
2526
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
2627
import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate';
@@ -288,16 +289,6 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
288289
syncQuiz(quiz: any, askPreflight?: boolean, siteId?: string): Promise<AddonModQuizSyncResult> {
289290
siteId = siteId || this.sitesProvider.getCurrentSiteId();
290291

291-
const warnings = [];
292-
const courseId = quiz.course;
293-
const modOptions = {
294-
cmId: quiz.coursemodule,
295-
readingStrategy: CoreSitesReadingStrategy.OnlyNetwork,
296-
siteId,
297-
};
298-
let syncPromise;
299-
let preflightData;
300-
301292
if (this.isSyncing(quiz.id, siteId)) {
302293
// There's already a sync ongoing for this quiz, return the promise.
303294
return this.getOngoingSync(quiz.id, siteId);
@@ -310,115 +301,116 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
310301
return Promise.reject(this.translate.instant('core.errorsyncblocked', {$a: this.componentTranslate}));
311302
}
312303

304+
return this.addOngoingSync(quiz.id, this.performSyncQuiz(quiz, askPreflight, siteId), siteId);
305+
}
306+
307+
/**
308+
* Perform the quiz sync.
309+
*
310+
* @param quiz Quiz.
311+
* @param askPreflight Whether we should ask for preflight data if needed.
312+
* @param siteId Site ID. If not defined, current site.
313+
* @return Promise resolved in success.
314+
*/
315+
async performSyncQuiz(quiz: any, askPreflight?: boolean, siteId?: string): Promise<AddonModQuizSyncResult> {
316+
siteId = siteId || this.sitesProvider.getCurrentSiteId();
317+
318+
const warnings = [];
319+
const courseId = quiz.course;
320+
const modOptions = {
321+
cmId: quiz.coursemodule,
322+
readingStrategy: CoreSitesReadingStrategy.OnlyNetwork,
323+
siteId,
324+
};
325+
313326
this.logger.debug('Try to sync quiz ' + quiz.id + ' in site ' + siteId);
314327

315328
// Sync offline logs.
316-
syncPromise = this.logHelper.syncIfNeeded(AddonModQuizProvider.COMPONENT, quiz.id, siteId).catch(() => {
317-
// Ignore errors.
318-
}).then(() => {
319-
// Get all the offline attempts for the quiz.
320-
return this.quizOfflineProvider.getQuizAttempts(quiz.id, siteId);
321-
}).then((attempts) => {
322-
// Should return 0 or 1 attempt.
323-
if (!attempts.length) {
324-
return this.finishSync(siteId, quiz, courseId, warnings);
325-
}
329+
await CoreUtils.instance.ignoreErrors(this.logHelper.syncIfNeeded(AddonModQuizProvider.COMPONENT, quiz.id, siteId));
326330

327-
const offlineAttempt = attempts.pop();
331+
// Get all the offline attempts for the quiz. It should always be 0 or 1 attempt
332+
const offlineAttempts = await this.quizOfflineProvider.getQuizAttempts(quiz.id, siteId);
328333

329-
// Now get the list of online attempts to make sure this attempt exists and isn't finished.
330-
return this.quizProvider.getUserAttempts(quiz.id, modOptions).then((attempts) => {
331-
const lastAttemptId = attempts.length ? attempts[attempts.length - 1].id : undefined;
332-
let onlineAttempt;
334+
if (!offlineAttempts.length) {
335+
// Nothing to sync, finish.
336+
return this.finishSync(siteId, quiz, courseId, warnings);
337+
}
333338

334-
// Search the attempt we retrieved from offline.
335-
for (const i in attempts) {
336-
const attempt = attempts[i];
339+
if (!this.appProvider.isOnline()) {
340+
// Cannot sync in offline.
341+
throw new Error(this.translate.instant('core.cannotconnect'));
342+
}
337343

338-
if (attempt.id == offlineAttempt.id) {
339-
onlineAttempt = attempt;
340-
break;
341-
}
342-
}
344+
const offlineAttempt = offlineAttempts.pop();
343345

344-
if (!onlineAttempt || this.quizProvider.isAttemptFinished(onlineAttempt.state)) {
345-
// Attempt not found or it's finished in online. Discard it.
346-
warnings.push(this.translate.instant('addon.mod_quiz.warningattemptfinished'));
346+
// Now get the list of online attempts to make sure this attempt exists and isn't finished.
347+
const onlineAttempts = await this.quizProvider.getUserAttempts(quiz.id, modOptions);
347348

348-
return this.finishSync(siteId, quiz, courseId, warnings, offlineAttempt.id, offlineAttempt, onlineAttempt,
349-
true);
350-
}
349+
const lastAttemptId = onlineAttempts.length ? onlineAttempts[onlineAttempts.length - 1].id : undefined;
350+
const onlineAttempt = onlineAttempts.find((attempt) => {
351+
return attempt.id == offlineAttempt.id;
352+
});
351353

352-
// Get the data stored in offline.
353-
return this.quizOfflineProvider.getAttemptAnswers(offlineAttempt.id, siteId).then((answersList) => {
354+
if (!onlineAttempt || this.quizProvider.isAttemptFinished(onlineAttempt.state)) {
355+
// Attempt not found or it's finished in online. Discard it.
356+
warnings.push(this.translate.instant('addon.mod_quiz.warningattemptfinished'));
354357

355-
if (!answersList.length) {
356-
// No answers stored, finish.
357-
return this.finishSync(siteId, quiz, courseId, warnings, lastAttemptId, offlineAttempt, onlineAttempt,
358-
true);
359-
}
358+
return this.finishSync(siteId, quiz, courseId, warnings, offlineAttempt.id, offlineAttempt, onlineAttempt, true);
359+
}
360360

361-
const answers = this.questionProvider.convertAnswersArrayToObject(answersList),
362-
offlineQuestions = this.quizOfflineProvider.classifyAnswersInQuestions(answers);
363-
let finish;
361+
// Get the data stored in offline.
362+
const answersList = await this.quizOfflineProvider.getAttemptAnswers(offlineAttempt.id, siteId);
364363

365-
// We're going to need preflightData, get it.
366-
return this.quizProvider.getQuizAccessInformation(quiz.id, modOptions).then((info) => {
364+
if (!answersList.length) {
365+
// No answers stored, finish.
366+
return this.finishSync(siteId, quiz, courseId, warnings, lastAttemptId, offlineAttempt, onlineAttempt, true);
367+
}
367368

368-
return this.prefetchHandler.getPreflightData(quiz, info, onlineAttempt, askPreflight,
369-
'core.settings.synchronization', siteId);
370-
}).then((data) => {
371-
preflightData = data;
369+
const offlineAnswers = this.questionProvider.convertAnswersArrayToObject(answersList);
370+
const offlineQuestions = this.quizOfflineProvider.classifyAnswersInQuestions(offlineAnswers);
372371

373-
// Now get the online questions data.
374-
const pages = this.quizProvider.getPagesFromLayoutAndQuestions(onlineAttempt.layout, offlineQuestions);
372+
// We're going to need preflightData, get it.
373+
const info = await this.quizProvider.getQuizAccessInformation(quiz.id, modOptions);
375374

376-
return this.quizProvider.getAllQuestionsData(quiz, onlineAttempt, preflightData, {
377-
pages,
378-
readingStrategy: CoreSitesReadingStrategy.OnlyNetwork,
379-
siteId,
380-
});
381-
}).then((onlineQuestions) => {
375+
const preflightData = await this.prefetchHandler.getPreflightData(quiz, info, onlineAttempt, askPreflight,
376+
'core.settings.synchronization', siteId);
377+
378+
// Now get the online questions data.
379+
const pages = this.quizProvider.getPagesFromLayoutAndQuestions(onlineAttempt.layout, offlineQuestions);
380+
381+
const onlineQuestions = await this.quizProvider.getAllQuestionsData(quiz, onlineAttempt, preflightData, {
382+
pages,
383+
readingStrategy: CoreSitesReadingStrategy.OnlyNetwork,
384+
siteId,
385+
});
382386

383-
// Validate questions, discarding the offline answers that can't be synchronized.
384-
return this.validateQuestions(onlineAttempt.id, onlineQuestions, offlineQuestions, siteId);
385-
}).then((discardedData) => {
387+
// Validate questions, discarding the offline answers that can't be synchronized.
388+
const discardedData = await this.validateQuestions(onlineAttempt.id, onlineQuestions, offlineQuestions, siteId);
386389

387-
// Get the answers to send.
388-
const answers = this.quizOfflineProvider.extractAnswersFromQuestions(offlineQuestions);
389-
finish = offlineAttempt.finished && !discardedData;
390+
// Get the answers to send.
391+
const answers = this.quizOfflineProvider.extractAnswersFromQuestions(offlineQuestions);
392+
const finish = offlineAttempt.finished && !discardedData;
390393

391-
if (discardedData) {
392-
if (offlineAttempt.finished) {
393-
warnings.push(this.translate.instant('addon.mod_quiz.warningdatadiscardedfromfinished'));
394-
} else {
395-
warnings.push(this.translate.instant('addon.mod_quiz.warningdatadiscarded'));
396-
}
397-
}
394+
if (discardedData) {
395+
if (offlineAttempt.finished) {
396+
warnings.push(this.translate.instant('addon.mod_quiz.warningdatadiscardedfromfinished'));
397+
} else {
398+
warnings.push(this.translate.instant('addon.mod_quiz.warningdatadiscarded'));
399+
}
400+
}
398401

399-
return this.quizProvider.processAttempt(quiz, onlineAttempt, answers, preflightData, finish, false, false,
400-
siteId);
401-
}).then(() => {
402-
403-
// Answers sent, now set the current page if the attempt isn't finished.
404-
if (!finish) {
405-
// Don't pass the quiz instance because we don't want to trigger a Firebase event in this case.
406-
return this.quizProvider.logViewAttempt(onlineAttempt.id, offlineAttempt.currentpage, preflightData,
407-
false, undefined, siteId).catch(() => {
408-
// Ignore errors.
409-
});
410-
}
411-
}).then(() => {
402+
// Send the answers.
403+
await this.quizProvider.processAttempt(quiz, onlineAttempt, answers, preflightData, finish, false, false, siteId);
412404

413-
// Data sent. Finish the sync.
414-
return this.finishSync(siteId, quiz, courseId, warnings, lastAttemptId, offlineAttempt, onlineAttempt,
415-
true, true);
416-
});
417-
});
418-
});
419-
});
405+
if (!finish) {
406+
// Answers sent, now set the current page.
407+
// Don't pass the quiz instance because we don't want to trigger a Firebase event in this case.
408+
await CoreUtils.instance.ignoreErrors(this.quizProvider.logViewAttempt(onlineAttempt.id, offlineAttempt.currentpage,
409+
preflightData, false, undefined, siteId));
410+
}
420411

421-
return this.addOngoingSync(quiz.id, syncPromise, siteId);
412+
// Data sent. Finish the sync.
413+
return this.finishSync(siteId, quiz, courseId, warnings, lastAttemptId, offlineAttempt, onlineAttempt, true, true);
422414
}
423415

424416
/**

0 commit comments

Comments
 (0)