AnswerEditComponent

The same recommendation will also work for the AnswerEditComponent upgrade; the only real difference here is the answer's Value numeric property, which will require some specific code in the component's class file:

[...]

createForm() {
this.form = this.fb.group({
Text: ['', Validators.required],
Value: [0,
[Validators.required,
Validators.min(-5),
Validators.max(5)]
]
});
}

[...]

Also, it will require some specific code in the template file:

[...]

<div class="form-group"
[ngClass]="{ 'has-error has-feedback' : hasError('Value') }">
<label for="value">Score Value:</label>
<br />
<select id="value"
formControlName="Value" required
class="form-control">
<option *ngFor="let num of [-5,-4,-3,-2,-1,0,1,2,3,4,5]"
[value]="num">
{{num}}
</option>
</select>
<div *ngIf="hasError('Value')"
class="help-block">
Please select a valid number between -5 and 5.
</div>
</div>

[...]

As we can see, we added three different validators within the Form Model's Value property; we did that because we want to receive a required value that is also not smaller than -5 and not bigger than 5. Whenever any of these conditions fails, the Form Model will become invalid.

Wait a minute, we already provide the user with a <select> element filled with predetermined values from -5 to +5; should we really lose our valuable time in validating such input?

As a matter of fact, we should; validation isn't something that can be delegated to input elements, regardless of how they're supposed to work. That <select> can be replaced with another input type, and/or be rendered as something that can also accept empty or different values; we chose the Reactive pattern because we want to perform the validation logic to our Form Model, right? The HTML form elements have nothing to do with it, and they definitely can't give us the control that we crave for.

Anyway, since we added that validator, we can take the chance to improve the form UX by adding a Pick a value option to the <select> itself:

<select id="value"
formControlName="Value" required
class="form-control">
<option value="">Pick a value...</option>
<option *ngFor="let num of [-5,-4,-3,-2,-1,0,1,2,3,4,5]"
[value]="num">
{{num}}
</option>
</select>

We put the new option on top of the other ones to ensure that it will be shown when the user creates a new answer. However, for that to happen, we also need to change the new answer's default value from zero to empty string:

createForm() {
this.form = this.fb.group({
Text: ['', Validators.required],
Value: ['',
[Validators.required,
Validators.min(-4),
Validators.max(5)]
]
});
}

The last thing to do is perform a minor update to the Answer interface to make it able to handle a nullable number:

interface Answer {
Id: number;
QuestionId: number;
Text: string;
Value?: number;
}
Truth be told, updating the Answer interface is not strictly necessary; TypeScript 2.x doesn't enforce strict null-checking in variables, unless we explicitly enable it by adding the "strictNullChecks": true directive to the compilerOptions section of tsconfig.json. However, learning how to properly handle nullable and non-nullable types can be a great way to better understand the various implications of what we're doing.

As soon as we have done everything, we can run our project in debug mode, navigate through an existing question, and click on the Add a new Answer button; once there, give focus and leave focus to the form controls to see the results of our hard work:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.34.25