- Angular 6 for Enterprise:Ready Web Applications
- Doguhan Uluca
- 812字
- 2021-06-25 21:20:34
Retrieving service data from a component
To be able to use the getCurrentWeather function in the CurrentWeather component, you need to inject the service into the component:
- Inject the WeatherService into the constructor of the CurrentWeatherComponent class
- Remove the existing code that created the dummy data in the constructor:
src/app/current-weather/current-weather.component.ts
constructor(private weatherService: WeatherService) { }
- Call the getCurrentWeather function inside the ngOnInit function:
src/app/current-weather/current-weather.component.ts
ngOnInit() {
this.weatherService.getCurrentWeather('Bethesda', 'US')
.subscribe((data) => this.current = data)
}
Fair warning, do not expect this code to be working just yet. You should see an error, so let's understand what's going in the next segment.
Angular components have a rich collection of life cycle hooks that allow you to inject your custom behavior, when a component is being rendered, refreshed, or destroyed. ngOnInit() is the most common life cycle hook you will be using. It is only called once, when a component is first instantiated or visited. This is where you will want to perform your service calls. For a deeper understanding of component life cycle hooks, check out the documentation at https://angular.io/guide/lifecycle-hooks.
Note that the anonymous function you have passed to subscribe is an ES2015 arrow function. If you're not familiar with arrow functions, it may be confusing at first. Arrow functions are actually quite elegant and simple.
Consider the following arrow function:
(data) => { this.current = data }
You can rewrite it simply as:
function(data) { this.current = data }
There's a special condition—when you write an arrow function that simply transforms a piece of data, such as this:
(data) => { data.main.temp }
This function effectively takes ICurrentWeatherData as an input and returns the temp property. The return statement is implicit. If you rewrite it as a regular function, it will look like this:
function(data) { return data.main.temp }
When the CurrentWeather component loads, ngOnInit will fire once, which will call the getCurrentWeather function that returns an object with a type of Observable<ICurrentWeatherData>. An Observable, as described in the official documentation, is the most basic building block of RxJS that represents an event emitter, which will emit any data received over time with the type of ICurrentWeatherData. The Observable object by itself is benign and will not cause a network event to be fired unless it is being listened to. You can read more about Observables at reactivex.io/rxjs/class/es6/Observable.js~Observable.html.
By calling .subscribe on the Observable, you're essentially attaching a listener to the emitter. You've implemented an anonymous function within the subscribe method, which will get executed whenever a new piece of data is received and an event is emitted. The anonymous function takes a data object as a parameter, and, the specific implementation in this case, assigns the piece of data to the local variable named current. Whenever current is updated, the template bindings you implemented earlier will pull in the new data and render it on the view. Even though ngOnInit executes only once, the subscription to the Observable persists. So whenever there's new data, the current variable will be updated and the view will rerender to display the latest data.
The root cause of the error at hand is that the data that is being emitted is of type ICurrentWeatherData; however, our component only understands data that is shaped as described by the ICurrentWeather interface. In the next section, you will need to dig deeper into RxJS to understand how best to accomplish that task.
Beware, VS Code and CLI sometimes stop working. As previously noted, as you code, the npm start command is running in the integrated terminal of VS Code. Angular CLI, in combination with the Angular Language Service plug-in, continuously watches for code changes and transpiles your TypeScript code to JavaScript, so you can observe your changes with live-reloading in the browser. The great thing is that when you make coding errors, in addition to the red underlining in VS Code, you will also see some red text in the terminal or even the browser, because the transpilation has failed. In most cases, when correcting the error, the red underlining will go away and Angular CLI will automatically retranspile your code and everything will work. However, under certain scenarios, you will note that VS Code will fail to pick typing changes in the IDE, so you won't get autocompletion help or the CLI tool will get stuck with message saying webpack: Failed to compile.
You have two main strategies to recover from such conditions:
- Click on the terminal and hit Ctrl + C to stop running the CLI task and restart by executing npm start
- If #1 doesn't work, quit VS Code with Alt + F4 for Windows or ⌘ + Q for macOS and restart it
Given Angular and VS Code's monthly releases cycles, I'm confident that in time the tooling can only improve.