Check out the full series of Questions Management tutorial here.
In the previous tutorial, I built the interface for displaying all the questions. Now is the time to call the API of the API Question Service to perform some manipulations on the question. The first would be to display all the questions.
First, I will create a new QuestionService class to make call to the API to get all the questions from the API Question Service.
To do this, I will first create a new QuestionsService class located in the src/app/services directory as follows:
This class will be injected into the AllQuestionsComponent class so we will declare it with the @Injectable decorator as follows:
1 2 3 4 5 6 |
import { Injectable } from "@angular/core"; @Injectable() export class QuestionsService { } |
Next, I will create new objects to contain information about the question that the API Question Service will return. Since the object contains the category information we created in the previous tutorial, so I will create more the Question, Option, and CompositeQuestions as follow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import { Injectable } from "@angular/core"; @Injectable() export class QuestionsService { } export class Option { id: string; note: string; questionId: string; description: string; isCorrect: boolean; } export class Question { id: string; categoryId: string; description: string; } export class CompositeQuestion { id: string; category: Category; description: string; options: Option[]; } |
To be able to call the API to retrieve all questions from API Question Service, I will declare using Angular’s HttpClient object as follows:
1 2 3 4 5 6 7 8 9 10 |
import { Injectable } from "@angular/core"; import { HttpClient } from "@angular/common/http"; @Injectable() export class QuestionsService { constructor(private http: HttpClient) { } } |
Now I can write a method to retrieve all the questions from the API Question Service:
1 2 3 |
findAllQuestions(): Promise<CompositeQuestion[]> { return this.http.get<CompositeQuestion[]>("/question/all").toPromise(); } |
Similar to calling the API Category Service, to avoid the CORS error mentioned in this tutorial, I will modify the proxy.conf.json file located in the frontend project directory to add more for the API Question Service, as follow:
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "/category/*": { "target": "http://localhost:8282", "secure": false, "logLevel": "debug" }, "/question/*": { "target": "http://localhost:8281", "secure": false, "logLevel": "debug" } } |
With this declaration, outbound requests with URLs beginning with “/question” will be requested to http://localhost:8281, which is the address of the API Question Service.
Similar to the class CategoriesService, we need to declare this QuestionsService class in the AppModule class, in the provider attribute of the @NgModule decorator, as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { NavigationModule } from './navigation/navigation.module'; import { DashboardModule } from './dashboard/dashboard.module'; import { AppRoutingModule } from './app-routing.module'; import { QuestionsModule } from './questions/questions.module'; import { CategoriesService } from './services/categories.service'; import { HttpClientModule } from '@angular/common/http'; import { QuestionsService } from './services/questions.service'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule, AppRoutingModule, NavigationModule, DashboardModule, QuestionsModule ], providers: [ CategoriesService, QuestionsService ], bootstrap: [ AppComponent ] }) export class AppModule { } |
OK, now we will use the QuestionsService class to get all the questions we need, to display on the interface of the questionnaire display.
To do this, we will first declare using the QuestionsService class in the constructor of the AllQuestionsComponent class as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import { Component, AfterViewInit } from "../../../../node_modules/@angular/core"; import { QuestionsService, CompositeQuestion } from "../../services/questions.service"; declare var $: any; @Component({ selector: 'qm-body', templateUrl: './all_questions.component.html' }) export class AllQuestionsComponent implements AfterViewInit { constructor(private questionsService: QuestionsService) { } ngAfterViewInit(): void { $('#dataTables-questions').DataTable({ responsive: true }); } } |
Now we can write the code using the QuestionsService findAllQuestions() method to get all the questions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import { Component, AfterViewInit } from "../../../../node_modules/@angular/core"; import { QuestionsService, CompositeQuestion } from "../../services/questions.service"; declare var $: any; @Component({ selector: 'qm-body', templateUrl: './all_questions.component.html' }) export class AllQuestionsComponent implements AfterViewInit { compositeQuestions: CompositeQuestion[]; constructor(private questionsService: QuestionsService) { } showAllQuestions() { this.questionsService.findAllQuestions().then(r => { this.compositeQuestions = r; setTimeout(function() { $('#dataTables-questions').DataTable({ responsive: true }); }, 100); }); } ngAfterViewInit(): void { this.showAllQuestions(); } } |
To display these questions, in the all_questions.component.html file, the table displays the list of questions, I will edit as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-questions"> <thead> <tr> <th>Description</th> <th>Category</th> <th>Actions</th> <th>Options</th> </tr> </thead> <tbody> <tr *ngFor="let c of compositeQuestions; let odd = odd; let even = even" [ngClass]="{ odd: odd, even: even }"> <td>{{ c.description }}</td> <td>{{ c.category.name }}</td> <td> <button type="button" class="btn btn-primary btn-circle"><i class="fa fa-eye"></i></button> <button type="button" class="btn btn-warning btn-circle"><i class="fa fa-edit"></i></button> <button type="button" class="btn btn-danger btn-circle"><i class="fa fa-trash"></i></button> </td> <td> <button type="button" class="btn btn-success btn-circle"><i class="fa fa-plus"></i></button> </td> </tr> </tbody> </table> <!-- /.table-responsive --> |
OK, everything is over, now try it.
Here, we need to run the Questions Management application with the proxy.conf.json file as follows:
1 |
ng serve --proxy-config proxy.conf.json |
Suppose now in the database I have the following information:
At this point, if you run the application you will see the list of questions displayed as follows: