After receiving a list of subjects from the server, exercises are taken on each subject using the subject.id (from the server) and stored all together in the subEx variable. Classes are listed at the bottom.
subjects:Subject[]
temp:Exercise[] = []
subEx:SubjectExercise[] = []
constructor(private exService: ExerciseService, private subService: SubjectService) { }
ngOnInit(): void {
this.getSubjects()
}
getSubjects(){
let id = localStorage.getItem("id")
this.subService.GetSubjectsByUserId(localStorage.getItem("id")).subscribe(
res => {
this.subjects = res
for (const sub of this.subjects){
this.exService.GetExercisesBySubject(sub.name).subscribe(
res=>{
this.temp = res
this.subEx.push(new SubjectExercise(sub, this.temp))
console.log(this.subEx)
}
)
}
},
)
}
Retrieve subjects and exercises through a simple http.get call
GetExercisesBySubject(subName:string){
return this.http.get<any>(this._getExercisesBySubject+"/"+subName)
}
Then display all the subjects as buttons and add exercises as dropdown options to each button.
<div class="list-group list-group-flush">
<button *ngFor="let sub of subEx" type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{sub.subject.name}}
<div class="dropdown-menu">
<a *ngFor="let ex of sub.exercises" class="dropdown-item">{{ex.title}}</a>
</div>
</button>
</div>
The issue is that after every page reload, subjects have a different order and all subjects have the same random exercises. I suspect this is due to JavaScript's synchronous/asynchronous behavior.
So, how can I ensure that the page renders subjects in the same order and displays exercises individually for each subject?
Subject class
export class Subject
{
constructor(id: string, name: string){
this.Id = id
this.name = name
}
Id: string
name: string
}
Exercise class
import { Subject } from './Subject'
export class Exercise
{
Id: string
title: string
content: string
correctAnswer: string
subject: Subject
}
SubjectExercise class
import { Subject } from './Subject';
import { Exercise } from './Exercise';
export class SubjectExercise{
constructor(sub: Subject, ex: Exercise[]){
this.subject = sub
this.exercises = ex
}
subject: Subject
exercises:Exercise[]
}
This is how subEx looks after calling getSubjects()
0: SubjectExercise
exercises:
0: {id: "ea9bce1d-b6bf-471e-b1df-6edb253d68e7", title: "Task2", content: "string", correctAnswer:
"string", subject: {...}}
1: {id: "89121437-d01d-461b-b0a1-92b2798bd66e", title: "Task1", content: "string", correctAnswer:
"string", subject: {...}}
2: {id: "3643f5db-5271-4c70-abb8-cc4a2f00d1ae", title: "Task3", content: "string", correctAnswer:
"string", subject: {...}}
subject: {id: "d0d20a1e-8a75-4d56-0c67-08d892dcbbe6", name: "Math"}
1: SubjectExercise
exercises: []
subject:{id: "b827616b-8ee3-4dee-0c69-08d892dcbbe6", name: "Econometrics"}
2: SubjectExercise
exercises:
0: {id: "955a704a-00dc-4fe0-a953-5d8dd8ce4d35", title: "Task1", content: "string", correctAnswer:
"string", subject: {...}}
1: {id: "fe0dd1a7-2ee1-4948-9145-864a0b07b506", title: "Task2", content: "string", correctAnswer:
"string", subject: {...}}
subject: {id: "aad23a48-f04e-4114-0c68-08d892dcbbe6", name: "GIS"}