[Updated] Finished Frontend, Added statushandling to backend and frontend [Todo: session token handling at lvl 2]
This commit is contained in:
@@ -31,8 +31,13 @@ public class QuizController {
|
|||||||
@RequestParam(required = false) String type
|
@RequestParam(required = false) String type
|
||||||
) {
|
) {
|
||||||
QuizSettings quizSettings = new QuizSettings(amount, category, difficulty, type);
|
QuizSettings quizSettings = new QuizSettings(amount, category, difficulty, type);
|
||||||
String jsonString = String.format("{\"sessionId\":\"%s\"}", quizService.createSession(quizSettings));
|
Optional<String> result = quizService.createSession(quizSettings);
|
||||||
return jsonString;
|
if(result.isPresent()) {
|
||||||
|
String jsonString = String.format("{\"statusCode\":0,\"sessionId\":\"%s\"}", result.get());
|
||||||
|
return jsonString;
|
||||||
|
}
|
||||||
|
String jsonString = String.format("{\"statusCode\":5}");
|
||||||
|
return jsonString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/status/{sessionId}")
|
@GetMapping("/status/{sessionId}")
|
||||||
|
|||||||
@@ -59,11 +59,6 @@ public class QuizSettings {
|
|||||||
|
|
||||||
/** Inverse of toApiQuery */
|
/** Inverse of toApiQuery */
|
||||||
public QuizSettings(int amount, Integer category, String difficulty, String type) {
|
public QuizSettings(int amount, Integer category, String difficulty, String type) {
|
||||||
System.out.println(amount);
|
|
||||||
System.out.print(category);
|
|
||||||
System.out.print(difficulty);
|
|
||||||
System.out.print(type);
|
|
||||||
|
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.category = category == null ? Category.ANY : Category.values()[category];
|
this.category = category == null ? Category.ANY : Category.values()[category];
|
||||||
this.difficulty = difficulty == null ? Difficulty.ANY : Difficulty.valueOf(difficulty.toUpperCase());
|
this.difficulty = difficulty == null ? Difficulty.ANY : Difficulty.valueOf(difficulty.toUpperCase());
|
||||||
|
|||||||
@@ -1,20 +1,31 @@
|
|||||||
package com.ninjaws.quiz.services;
|
package com.ninjaws.quiz.services;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestClientException;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import com.ninjaws.quiz.models.ApiResponse;
|
||||||
import com.ninjaws.quiz.models.QuizSettings;
|
import com.ninjaws.quiz.models.QuizSettings;
|
||||||
|
import com.ninjaws.quiz.models.Request;
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ApiService {
|
public class ApiService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CleanerService cleanerService;
|
||||||
|
@Autowired
|
||||||
|
private ResponseHandlingService responseHandler;
|
||||||
@Autowired
|
@Autowired
|
||||||
private RestTemplate restTemplate;
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
private static final System.Logger logger = System.getLogger(ApiService.class.getName());
|
||||||
|
|
||||||
private final String apiUrl = "https://opentdb.com/api.php";
|
private final String apiUrl = "https://opentdb.com/api.php";
|
||||||
|
|
||||||
public ApiService() {
|
public ApiService() {
|
||||||
@@ -24,25 +35,17 @@ public class ApiService {
|
|||||||
return apiUrl + quizSettings.toApiQuery();
|
return apiUrl + quizSettings.toApiQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String requestQuestions(@Valid QuizSettings quizSettings) {
|
public void handleRequest(@Valid Request request) {
|
||||||
String url = buildRequestString(quizSettings);
|
String url = buildRequestString(request.getQuizSettings());
|
||||||
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
|
|
||||||
String jsonData = response.getBody();
|
|
||||||
|
|
||||||
// try {
|
try {
|
||||||
// int responseCode = getResponseCode(jsonData);
|
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
|
||||||
// /** When the code has expired or you've ran out of questions, update the token and try again */
|
String json = response.getBody();
|
||||||
// if(responseCode == 3 || responseCode == 4) {
|
ApiResponse apiResponse = cleanerService.extractApiResponse(json);
|
||||||
// requestSessionToken();
|
responseHandler.handleResponse(request.getSessionId(), apiResponse);
|
||||||
// requestQuestions(quizSettings);
|
|
||||||
// }
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// // Failed to get a responseCode, meaning the request failed completely (they always send a response_code)
|
|
||||||
// }
|
|
||||||
return jsonData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleStatusCode(int statusCode) {
|
|
||||||
|
|
||||||
|
} catch (RestClientException | IOException | IllegalStateException e) {
|
||||||
|
logger.log(System.Logger.Level.ERROR, "Critical failure", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
package com.ninjaws.quiz.services;
|
package com.ninjaws.quiz.services;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.ninjaws.quiz.models.QuizSettings;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.ninjaws.quiz.models.ApiResponse;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class CleanerService {
|
public class CleanerService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
public CleanerService() {}
|
public CleanerService() {}
|
||||||
|
|
||||||
public QuizSettings jsonToQuizSettings(String json){
|
public ApiResponse extractApiResponse(String json) throws IOException {
|
||||||
QuizSettings quizSettings = new QuizSettings();
|
return objectMapper.readValue(json, ApiResponse.class);
|
||||||
return quizSettings;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,14 @@ public class QueueService {
|
|||||||
* Executes them in order, one every 5 seconds (the limit of the external API)
|
* Executes them in order, one every 5 seconds (the limit of the external API)
|
||||||
* Removes them from the Queue when the request was succesful
|
* Removes them from the Queue when the request was succesful
|
||||||
*/
|
*/
|
||||||
private final BlockingQueue<Request> requests = new LinkedBlockingQueue<>();
|
private final BlockingQueue<Request> requests = new LinkedBlockingQueue<>(5);
|
||||||
|
|
||||||
public void addToQueue(Request request) {
|
/**
|
||||||
requests.add(request);
|
* Offer automatically doesn't add it to the queue if it is full, so no Exceptions thrown
|
||||||
|
* @return Whether it's possible to add the request to the queue
|
||||||
|
*/
|
||||||
|
public boolean addToQueue(Request request) {
|
||||||
|
return requests.offer(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Request popFromQueue() {
|
public Request popFromQueue() {
|
||||||
|
|||||||
@@ -27,12 +27,17 @@ public class QuizService {
|
|||||||
* @param quizSettings The values set by the user, determining the kind of quiz they want
|
* @param quizSettings The values set by the user, determining the kind of quiz they want
|
||||||
* @return The sessionId
|
* @return The sessionId
|
||||||
*/
|
*/
|
||||||
public String createSession(QuizSettings quizSettings) {
|
public Optional<String> createSession(QuizSettings quizSettings) {
|
||||||
Session session = new Session();
|
Session session = new Session();
|
||||||
cacheService.addToCache(session.getId(), session);
|
cacheService.addToCache(session.getId(), session);
|
||||||
queueService.addToQueue(new Request(session.getId(), quizSettings));
|
boolean addedToQueue = queueService.addToQueue(new Request(session.getId(), quizSettings));
|
||||||
|
/** In this order, because doing the queue before the cache could lead to race conditions (request completion immediately calls cache, but then the item doesn't exist) */
|
||||||
|
if(!addedToQueue) {
|
||||||
|
cacheService.removeFromCache(session.getId());
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
return session.getId();
|
return Optional.of(session.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,9 +54,16 @@ public class QuizService {
|
|||||||
throw new IllegalArgumentException("Invalid session ID: " + sessionId);
|
throw new IllegalArgumentException("Invalid session ID: " + sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Still waiting for a response */
|
||||||
if (session.getQuestions() == null) {
|
if (session.getQuestions() == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Anything other than statuscode 0 doesn't result in active sessions, so remove them from the cache after reporting to the frontend */
|
||||||
|
if(session.getStatusCode() != 0) {
|
||||||
|
cacheService.removeFromCache(session.getId());
|
||||||
|
}
|
||||||
|
|
||||||
return Optional.of(session);
|
return Optional.of(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,10 +88,6 @@ public class QuizService {
|
|||||||
for(int i = 0; i < session.getQuestions().size(); i++) {
|
for(int i = 0; i < session.getQuestions().size(); i++) {
|
||||||
String correctAnswer = session.getQuestions().get(i).getCorrectAnswer();
|
String correctAnswer = session.getQuestions().get(i).getCorrectAnswer();
|
||||||
String userAnswer = answers.getAnswers().get(i);
|
String userAnswer = answers.getAnswers().get(i);
|
||||||
// for(String answer : session.getQuestions().get(i).getAnswers()) {
|
|
||||||
// System.out.print(answer);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (correctAnswer.equalsIgnoreCase(userAnswer)) {
|
if (correctAnswer.equalsIgnoreCase(userAnswer)) {
|
||||||
amountCorrect++;
|
amountCorrect++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.ninjaws.quiz.services;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.ninjaws.quiz.models.ApiResponse;
|
||||||
|
import com.ninjaws.quiz.models.Session;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ResponseHandlingService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CacheService cacheService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is no sessionId, then this is a request from the scheduler
|
||||||
|
* purely to stock in the database No Cache call is required
|
||||||
|
*/
|
||||||
|
public void handleResponse(String sessionId, ApiResponse response) throws IllegalStateException {
|
||||||
|
|
||||||
|
Session session = cacheService.getFromCache(sessionId);
|
||||||
|
if (session == null) {
|
||||||
|
// Critical system failure: Should never occur
|
||||||
|
throw new IllegalStateException("Session should be defined!");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (response.getResponseCode()) {
|
||||||
|
case 0:
|
||||||
|
// Nothing
|
||||||
|
updateSessionInCache(session, response);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// Not enough questions to satisfy the request.
|
||||||
|
updateSessionInCache(session, response);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// Invalid parameters
|
||||||
|
updateSessionInCache(session, response);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// If it expired. Shouldn't happen since the backup database is full within 40 minutes, and the code lasts for 6 hours
|
||||||
|
// Return a statuscode 1 to signal an issue, just in case a user hits this situation (should not happen)
|
||||||
|
session.setStatusCode(1);
|
||||||
|
updateSessionInCache(session, response);
|
||||||
|
case 4:
|
||||||
|
// It returns nothing, the previous batch was the last one
|
||||||
|
// Return a statuscode 1 to the user
|
||||||
|
session.setStatusCode(1);
|
||||||
|
updateSessionInCache(session, response);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
// Should be prevented by the scheduler
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the request was made by the scheduler during queue-downtime, there is no session
|
||||||
|
*/
|
||||||
|
public void switchInternal(ApiResponse response) {
|
||||||
|
switch (response.getResponseCode()) {
|
||||||
|
case 0:
|
||||||
|
// TODO: Store in DB
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
// Signal DataService that we have extracted all the data. Stop gathering, switch to caching-mode
|
||||||
|
// TODO: Signal DB that it's full, start db-swapping process
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
// Should be prevented by the scheduler
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSessionInCache(Session session, ApiResponse response) {
|
||||||
|
session.setStatusCode(response.getResponseCode());
|
||||||
|
session.setQuestions(response.getResults());
|
||||||
|
cacheService.addToCache(session.getId(), session);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,17 +1,10 @@
|
|||||||
package com.ninjaws.quiz.services;
|
package com.ninjaws.quiz.services;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.ninjaws.quiz.models.ApiResponse;
|
|
||||||
import com.ninjaws.quiz.models.Question;
|
|
||||||
import com.ninjaws.quiz.models.Request;
|
import com.ninjaws.quiz.models.Request;
|
||||||
import com.ninjaws.quiz.models.Session;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class SchedulerService {
|
public class SchedulerService {
|
||||||
@@ -20,40 +13,21 @@ public class SchedulerService {
|
|||||||
private QueueService queueService;
|
private QueueService queueService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApiService apiService;
|
private ApiService apiService;
|
||||||
@Autowired
|
|
||||||
private CacheService cacheService;
|
|
||||||
@Autowired
|
|
||||||
private ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
private static final System.Logger logger = System.getLogger(SchedulerService.class.getName());
|
|
||||||
|
|
||||||
public SchedulerService() {}
|
public SchedulerService() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every 5 seconds:
|
* Every 5 seconds:
|
||||||
* - Take the top request from the queue (removes it)
|
* - Check if there is a request in queue
|
||||||
* - Perform the request
|
* - Yes: Send it to the apiService
|
||||||
* - Wait for the data
|
* - No: Have the apiService do bulk gathering for the DB
|
||||||
* - Find the matching session from the cache
|
|
||||||
* - Add the data to the session in the cache
|
|
||||||
*/
|
*/
|
||||||
@Scheduled(fixedDelay = 5000)
|
@Scheduled(fixedDelay = 5000)
|
||||||
protected void processQueue() {
|
protected void processQueue() {
|
||||||
Request request = queueService.popFromQueue();
|
Request request = queueService.popFromQueue();
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
String json = apiService.requestQuestions(request.getQuizSettings());
|
apiService.handleRequest(request);
|
||||||
try {
|
|
||||||
List<Question> questions = extractQuestions(json);
|
|
||||||
Session session = cacheService.getFromCache(request.getSessionId());
|
|
||||||
session.setQuestions(questions);
|
|
||||||
cacheService.addToCache(request.getSessionId(), session);
|
|
||||||
} catch (IOException | NullPointerException e) {
|
|
||||||
logger.log(System.Logger.Level.ERROR, "Critical failure", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Question> extractQuestions(String json) throws IOException {
|
|
||||||
return objectMapper.readValue(json, ApiResponse.class).getResults();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
import { Question } from "./question";
|
||||||
|
|
||||||
|
export interface Session {
|
||||||
|
id: string;
|
||||||
|
statusCode: number;
|
||||||
|
questions: Question[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Question } from '../models/question';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class CleanerService {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets decoded strings for the questions and the answers, so the special characters will be shown instead of their codes
|
||||||
|
*/
|
||||||
|
public cleanQuestionStrings(questions: Question[]): Question[] {
|
||||||
|
for(let i = 0; i < questions.length; i++) {
|
||||||
|
questions[i].question_decoded = this.decodeString(questions[i].question);
|
||||||
|
questions[i].answers_decoded = [];
|
||||||
|
for(let j = 0; j < questions[i].answers.length; j++){
|
||||||
|
questions[i].answers_decoded!.push(this.decodeString(questions[i].answers[j]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return questions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Puts special characters back into the string, like ' and " */
|
||||||
|
private decodeString(text: string) {
|
||||||
|
const txt = document.createElement("textarea");
|
||||||
|
txt.innerHTML = text;
|
||||||
|
const decodedValue = txt.value;
|
||||||
|
txt.remove(); // Clean up the temporary element
|
||||||
|
return decodedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,8 @@ import {
|
|||||||
import { Question } from '../models/question';
|
import { Question } from '../models/question';
|
||||||
import { Answers } from '../models/answers';
|
import { Answers } from '../models/answers';
|
||||||
import { StorageService } from './storage.service';
|
import { StorageService } from './storage.service';
|
||||||
|
import { CleanerService } from './cleaner.service';
|
||||||
|
import { ResponseHandlerService } from './response-handler.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -23,13 +25,22 @@ import { StorageService } from './storage.service';
|
|||||||
export class QuizService {
|
export class QuizService {
|
||||||
private apiUrl = 'http://localhost:9090/quiz';
|
private apiUrl = 'http://localhost:9090/quiz';
|
||||||
|
|
||||||
constructor(private http: HttpClient, private storageService: StorageService) {}
|
constructor(
|
||||||
|
private http: HttpClient,
|
||||||
|
private storageService: StorageService,
|
||||||
|
private cleanerService: CleanerService,
|
||||||
|
private reponseHandler: ResponseHandlerService) {}
|
||||||
|
|
||||||
public async startSession(quizParams: QuizParams) {
|
public async startSession(quizParams: QuizParams): Promise<Question[] | null> {
|
||||||
const sessionIdObj = await firstValueFrom(this.http.get<any>(this.apiUrl + '/questions' + this.convertParamsToUrl(quizParams)));
|
const sessionIdObj = await firstValueFrom(this.http.get<any>(this.apiUrl + '/questions' + this.convertParamsToUrl(quizParams)));
|
||||||
|
/** No need to poll if the session is not created. Likely means the queue is full */
|
||||||
|
if(sessionIdObj.statusCode !== 0) {
|
||||||
|
return this.reponseHandler.handleResponse(sessionIdObj.statusCode);
|
||||||
|
}
|
||||||
this.storageService.setSession(sessionIdObj.sessionId);
|
this.storageService.setSession(sessionIdObj.sessionId);
|
||||||
const questionsObj = await lastValueFrom(this.pollQuestions(sessionIdObj.sessionId));
|
const sessionObj = await lastValueFrom(this.pollQuestions(sessionIdObj.sessionId));
|
||||||
return this.cleanQuestionStrings(questionsObj.questions) as Question[];
|
|
||||||
|
return this.reponseHandler.handleResponse(sessionIdObj.statusCode, sessionObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public pollQuestions(sessionId: string) {
|
public pollQuestions(sessionId: string) {
|
||||||
@@ -42,26 +53,6 @@ export class QuizService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private cleanQuestionStrings(questions: Question[]): Question[] {
|
|
||||||
for(let i = 0; i < questions.length; i++) {
|
|
||||||
questions[i].question_decoded = this.decodeString(questions[i].question);
|
|
||||||
questions[i].answers_decoded = [];
|
|
||||||
for(let j = 0; j < questions[i].answers.length; j++){
|
|
||||||
questions[i].answers_decoded!.push(this.decodeString(questions[i].answers[j]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return questions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Puts special characters back into the string, like ' and " */
|
|
||||||
private decodeString(text: string) {
|
|
||||||
const txt = document.createElement("textarea");
|
|
||||||
txt.innerHTML = text;
|
|
||||||
const decodedValue = txt.value;
|
|
||||||
txt.remove(); // Clean up the temporary element
|
|
||||||
return decodedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getScore(answers: string[]) {
|
public async getScore(answers: string[]) {
|
||||||
const answersJson: Answers = {
|
const answersJson: Answers = {
|
||||||
sessionId: this.storageService.getSession()!,
|
sessionId: this.storageService.getSession()!,
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Session } from '../models/session';
|
||||||
|
import { CleanerService } from './cleaner.service';
|
||||||
|
import { Question } from '../models/question';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class ResponseHandlerService {
|
||||||
|
constructor(private cleanerService: CleanerService) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session is optional, except for the success state (0)
|
||||||
|
*/
|
||||||
|
public handleResponse(statusCode: number, session?: Session): Question[] | null {
|
||||||
|
switch (statusCode) {
|
||||||
|
case 0:
|
||||||
|
// Success
|
||||||
|
session!.questions = this.cleanerService.cleanQuestionStrings(session!.questions);
|
||||||
|
return session!.questions;
|
||||||
|
case 1:
|
||||||
|
// No Results (requests too much data for this combination of parameters)
|
||||||
|
alert('Not enough data for this request, please try a different combination');
|
||||||
|
return null;
|
||||||
|
case 2:
|
||||||
|
// Invalid parameter (should be handled by the backend)
|
||||||
|
alert('Invalid input');
|
||||||
|
return null;
|
||||||
|
case 5:
|
||||||
|
// Queue is full, try again later
|
||||||
|
alert('The server is experiencing a lot of traffic, please try again later');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,8 +43,10 @@ export class SetupComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.spinnerService.setActive(true);
|
this.spinnerService.setActive(true);
|
||||||
this.quizService.startSession(params).then((questions: Question[]) => {
|
this.quizService.startSession(params).then((questions: Question[] | null) => {
|
||||||
this.gotoQuiz(questions);
|
if(questions !== null) {
|
||||||
|
this.gotoQuiz(questions);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => {alert("Something went wrong, please try again");})
|
.catch((e) => {alert("Something went wrong, please try again");})
|
||||||
.finally(() => {this.spinnerService.setActive(false);});
|
.finally(() => {this.spinnerService.setActive(false);});
|
||||||
|
|||||||
@@ -1,4 +1,2 @@
|
|||||||
<!-- <div class="h-screen"> -->
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
<!-- </div> -->
|
|
||||||
<app-spinner></app-spinner>
|
<app-spinner></app-spinner>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<title>Quiz</title>
|
<title>Quiz</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="question.ico">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
|
|||||||
Reference in New Issue
Block a user