# Observables
Observable emmits an event driven by the data source.
Observer subscribe to the observable to be notified when an event is emitted.
This is an asynchronous operation.
It can also used promises or callbacks to achieve the same result. Observable is just an other approach.
## Install RxJS
```bash
npm install --save rxjs@6
npm install --save rxjs-compat
```
## Example and general usage
In this case `params` is an observable which we can subscribe to.
```ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
id: number;
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
this.route.params.subscribe((params: Params) => {
this.id = +params.id;
});
}
}
```
It exists various types of observable.
- executed once
- executed periodically
- ...
```ts
import { interval } from 'rxjs';
interval(1000).subscribe( count => {
consol.log(count);
})
```
`interval` is a built-in observable from rxjs.
If the app **don't** `unsubscribe` from the observable can cause **memory leaks**. Also, if we navigate to an other route, countless observable will be created and couses performance issues.
When we leave the component we can call the `OnDestroy` function to unsubscribe from the observable.
```ts
import { Component, OnDestroy, OnInit } from '@angular/core';
import { interval, Subscription, Observable } from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {
private firstObsSubscription: Subscription;
constructor() {}
ngOnInit() {
this.firstObsSubscription = interval(1000).subscribe(count => {
console.log(count);
});
ngOnDestroy(): void {
this.firstObsSubscription.unsubscribe();
}
}
```
In this example, the first subscription is stored in `firstObsSubscription` variable, which at leaving the component will be destroyed by calling `unsubscribe()`.
> Note: For all Angular built-in observables, is not necessary to unsubscribe from the observable. This is handleb by Angular itself.
## Building an observable (data, error, complete)
```ts
const customIntervalObservable = Observable.create(observer => {
let count = 0;
setInterval(() => {
observer.next(count);
if (count === 5) {
observer.complete();
}
if (count > 3) {
observer.error(new Error('Count is greater 3!'));
}
count++;
}, 1000);
});
this.firstObsSubscription = customIntervalObservable.subscribe(data => {
console.log(data);
}, error => {
console.log(error);
alert(error.message);
}, () => {
console.log('Completed!');
});
```
The `subscribe` function accepts up to three arguments: `data`, `error` and `complete`.
> Note: if the observable is completed, is not necessary to `unsubscribe`.
> Note: If an error is thrown, the observable is *cancelled* but not *completed*.
## Operators
Operators are grate to transform our data. The application can then subscribe to the result of the operator. On the operator can be called the `pipe()` function. Every operator has such a method. This function depends on the `rxjs/operators` pakage.
This is usefull when the application is fetching data from the server and it should trandformed before the component will use it.
## Subjec
Subject from RxJS is a more active then the event emitter because it can be called the function `next()` from the outside.
> Subject is the recommended way to emit events.
### Subject Example
user.service.ts
```ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({providedIn: 'root'})
export class UserService {
activatedEmitter = new Subject();
}
```
app.component.ts
```ts
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { UserService } from './user.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
userActivated = false;
private activatedSub: Subscription;
constructor(private userService: UserService) {
}
ngOnInit() {
this.activatedSub = this.userService.activatedEmitter.subscribe(didActivate => {
this.userActivated = didActivate;
});
}
ngOnDestroy(): void {
this.activatedSub.unsubscribe();
}
}
```
app.component.html
```html
...