Implementing ngOnInit

Now that we know what we did wrong, we can fix our issue by properly implementing a ngOnInit hook within our QuizListComponent class.

Open the quiz-list.component.ts file and add the following code (new/updated lines are highlighted):

import { Component, Inject, Input, OnInit } from "@angular/core";
import { HttpClient } from "@angular/common/http";

@Component({
selector: "quiz-list",
templateUrl: './quiz-list.component.html',
styleUrls: ['./quiz-list.component.css']
})

export class QuizListComponent implements OnInit {
@Input() class: string;
title: string;
selectedQuiz: Quiz;
quizzes: Quiz[];
http: HttpClient;
baseUrl: string;

constructor(http: HttpClient,
@Inject('BASE_URL') baseUrl: string) {
this.http = http;
this.baseUrl = baseUrl;
}

ngOnInit() {
console.log("QuizListComponent " +
" instantiated with the following class: "
+ this.class);

var url = this.baseUrl + "api/quiz/";

switch (this.class) {
case "latest":
default:
this.title = "Latest Quizzes";
url += "Latest/";
break;
case "byTitle":
this.title = "Quizzes by Title";
url += "ByTitle/";
break;
case "random":
this.title = "Random Quizzes";
url += "Random/";
break;
}

this.http.get<Quiz[]>(url).subscribe(result => {
this.quizzes = result;
}, error => console.error(error));
}

onSelect(quiz: Quiz) {
this.selectedQuiz = quiz;
console.log("quiz with Id "
+ this.selectedQuiz.Id
+ " has been selected.");
}
}

Here's an explanation of what we just did:

  • In line 1, we added a reference to the OnInit interface, which is required to implement the ngOnInit() hook.
  • In lines 15-16, we added two new local properties that will store the constructor variables; we need to do that because we will use them within the ngOnInit() method, so we need to have them referenced somewhere. Since they are instantiated through DI, this won't have performance or memory impact.
  • In lines 19-20, we assigned the DI instances to our new properties. Note how all the class logic has been removed from the constructor, which is now very shallow.
  • Starting from line 23, we implemented the ngOnInit() method, which now handles the tasks that were previously done within the constructor.

The only downside of this new implementation is the amount of code bloat required to declare and assign these new properties; we can definitely use some syntactic sugar to shrink it out. Luckily enough, Angular support a neat constructor syntax that will allow us to skip these properties, declaration, and assignment. Consider writing the following:

http: HttpClient;
baseUrl: string;

constructor(http: HttpClient,
@Inject('BASE_URL') baseUrl: string) {
this.http = http;
this.baseUrl = baseUrl;
}

We can write this instead:

constructor(private http: HttpClient, 
@Inject('BASE_URL') private baseUrl: string) {
}

We will achieve the following result--as soon as we give them an explicit access modifier, these parameters will be exposed accordingly. In our specific scenario, the private modifier is more than enough, as it makes them available throughout the whole class; let's change our code to use this new syntax and go ahead.

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

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