Check out the full series of Questions Management tutorial here.
After creating the interface for adding new question, now is the time to go to implement the function of adding a new question.
First, I will add to the QuestionsService class a method that will allow us to call the API adding new question of API Question Service to pass the question information we need to add.
Specifically, this method is as follows:
1 2 3 |
addQuestion(question: Question): Promise<CompositeQuestion> { return this.http.post<CompositeQuestion>("/question/add", JSON.stringify(question), { headers: this.headers }).toPromise(); } |
Since I wanted after adding a new question successfully, our application will redirect to the detail question page, so in the above method, I got the result returned from the API Question Service.
Next, we will edit the new question form in our new_question.component.html file, which will allow us to display all the categories in the system:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<form role="form"> <div class="form-group"> <label>Description</label> <textarea class="form-control" rows="3"></textarea> <p class="help-block">The description of the question.</p> </div> <div class="form-group"> <label>Category</label> <select class="form-control"> <option *ngFor="let c of categories" [ngValue]="c"> {{ c.name }} </option> </select> <p class="help-block">The category which this question belong to.</p> </div> <button type="submit" class="btn btn-primary">Add New Question</button> </form> |
with the categories variable is declared in the NewQuestionComponent class as follows:
1 |
categories: Category[]; |
The value of the category variable is derived from the API Category Service using the API retrieving all categories of this service:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import { AfterViewInit, Component } from "../../../../node_modules/@angular/core"; import { CategoriesService, Category } from "../../services/categories.service"; @Component({ selector: 'qm-body', templateUrl: './new_question.component.html' }) export class NewQuestionComponent implements AfterViewInit { categories: Category[]; selectedCategory: Category; constructor(private categoriesService: CategoriesService) { } ngAfterViewInit(): void { this.categoriesService.findAllCategories().then(r => { this.categories = r; }); } } |
Now we will go into the implementation for adding a new question.
In the new question form, we will declare variables that hold the value of the description and category entered by the user using the Angular ngModel directive as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<form role="form"> <div class="form-group"> <label>Description</label> <textarea class="form-control" rows="3" [(ngModel)]="description" name="description"></textarea> <p class="help-block">The description of the question.</p> </div> <div class="form-group"> <label>Category</label> <select [(ngModel)]="selectedCategory" class="form-control" name="category"> <option *ngFor="let c of categories" [ngValue]="c"> {{ c.name }} </option> </select> <p class="help-block">The category which this question belong to.</p> </div> <button type="submit" class="btn btn-primary" (click)="createNewQuestion()">Add New Question</button> </form> |
As you can see, I have also modified the content of the “Add New Question” button to allow when the user clicks on this button, our application will call the createNewQuestion() method in the NewQuestionComponent class to add new question.
The contents of the NewQuestionComponent class will be modified 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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
import { AfterViewInit, Component } from "../../../../node_modules/@angular/core"; import { QuestionsService, Question } from "../../services/questions.service"; import { CategoriesService, Category } from "../../services/categories.service"; import { Router } from "@angular/router"; @Component({ selector: 'qm-body', templateUrl: './new_question.component.html' }) export class NewQuestionComponent implements AfterViewInit { categories: Category[]; selectedCategory: Category; newQuestion: Question; description: string; constructor(private questionsService: QuestionsService, private categoriesService: CategoriesService, private router: Router) { } createNewQuestion() { if (this.isEmpty(this.description)) { alert("Description cannot be empty."); return; } if (this.isEmpty(this.selectedCategory)) { alert("Please select a category."); return; } this.newQuestion = new Question(); this.newQuestion.description = this.description; this.newQuestion.categoryId = this.selectedCategory.id; this.questionsService.addQuestion(this.newQuestion) .then(q => { alert("Success"); this.router.navigate(['/question/' + q.id]); }) .catch(this.handleError); } isEmpty(val) { return val === undefined || val == null || val.length <= 0; } private handleError(error: any): Promise<any> { alert('An error occurred' + error); return Promise.reject(error.message || error); } ngAfterViewInit(): void { this.categoriesService.findAllCategories().then(r => { this.categories = r; }); } } |
As I mentioned above, after successfully adding the question, our application will redirect to the detail question page, so in the NewQuestionComponent class, I declared the Router class and use the navigate() method of this class to redirect to the URL “/question/{id}” after receiving a successful response from the API Question Service.
OK, so we’ve finished the adding a new question in the Frontend of the Question Management application. Let’s try it out!
In the “New Question” page, after entering the question information need to add:
and click the “Add New Question” button, our application will redirect to the information page of this question as follows:
There is also a section on the “All Questions” page, we also have the “Add New” button:
In order to call to the New Question page, we will modify the code of this button as follows:
1 |
<a class="btn btn-success" routerLink="/new-question"><i class="fa fa-plus"></i> Add New</a> <p></p> |
Now you can from the “All Questions” page call to the New Question page.