# Data Flow

## Firebase and Angular

You can think of data interactions between Angular and Firebase as a messaging relay. Your Angular application sends a message (request) to Firebase, asking for data or permission to save new data. Firebase then responds with the requested data or a confirmation that the new data was saved. The message travels from your Angular application to Firebase and back again. This connection stays open and allows for real-time updates. In this way, you are not directly interacting with Firebase, but instead utilizing APIs to create requests that Firebase must respond to; these responses require appropriate handling.

When dealing with Firebase data in Angular, you typically use Observables to listen for changes in the Firebase database. Whenever data changes in Firebase, the Observable emits a new value. You may also use promise resolution for this; a promise represents a single eventual value, which can either be resolved or rejected depending on certain criteria. Something important to note is that the AngularFire API uses Observables rather than Promises.

***

## Data Across Components

Services are the primary way by which data variables across different components, especially without reducing performance with unnecessary API calls. Import your service into your component, declare it as a private variable in your component's constructor, and reference the **service's** variable for cross-component tracking.

#### Example

```typescript
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class UserService {
 private user$ = new BehaviorSubject<any>({});
 selectedUser$ = this.user$.asObservable();

 setUser(user: User) {
 this.user$.next(user);
 }
}

...

import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';

@Component({
 selector: 'app-example',
 templateUrl: './example.component.html',
 styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {
 user: User;

 constructor(private userService: UserService) { }

 ngOnInit(): void {
   this.userService.selectedUser$.subscribe((user: User) => {
     this.user = user;
   });
 }
}
```

Note that we **subscribe** here to the observable **selectedUser** of the behavior subject **user** to get updates on our target.

In Angular, lifecycle hooks are special methods that get called at specific points in the lifecycle of a component. When working with Observables, these hooks can be used to control when you subscribe and unsubscribe from them. These are **crucial** for handling data that is used to populate components; you need to make sure the data is there prior to rendering the component. Sometimes, this means that the initialization of your component is to be completed later in its lifecycle. Other times, it means that a new subscription must be made, pending changes to a variable bound to your component. Different lifecycle hooks are available to overcome this.

#### Example with OnInIt

```typescript
ngOnInit(): void {
 this.userService.selectedUser$.subscribe((user: User) => {
   this.user = user;
 });
}
```

#### Example with OnChanges

```typescript
ngOnChanges(changes: SimpleChanges): void {
 if (changes.user && !changes.user.firstChange) {
  this.userService.selectedUser$.subscribe((user: User) => {
    this.user = user;
  });
 }
}
```

#### Example with AfterViewInIt

```typescript
 ngAfterViewInit(): void {
  this.subscription = this.userService.selectedUser$.subscribe((user: User) => {
    this.user = user;
  });
 }
```

***
