# 7.11: Updating Profile Photo in NavBar

## BehaviorSubject

In this module, we'll learn how to pass data from any component to any other component in Angular.

We can communicate and pass data around between components with our services.

If we add a property called `MainPhotoUrl` to our AuthService - any component we want can subscribe to this property and receive updates when changes are made.

We subscribe to observables - and, MainPhotoUrl will be an observable - but, a different kind of observable: [BehaviorSubject](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md).

A BehaviorSubject is a type of [subject](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md).

A subject is _also_ an observer. It can be subscribed to and other subscribers can receive updated data - but, it can alo **receive** data.

A BehaviorSubject

1. nees an initial value (it must always return a value when subscribed to)
2. always returns the last value of the subject when subscribed to
3. you can use the getValue() method in non-observable code

These Reactive Programming ideas and techniques are really difficult to wrap your head around and they're one of the most tricky parts about Angular. They're also really difficult to explain in text! As is often the case, practice will make it more clear. If you're someone who learns best by reading or you'd like a more thorough introduction to Reactive Programming [check out this Readme from André Staltz](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754).

## Adding BehaviorSubject to the AuthService

In `auth.service.ts`, import `BehaviorSubject` from `rxjs` and add a new property:

```typescript
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

// ...

private photoUrl = new BehaviorSubject<string>('../../assets/user.png');
```

As stated before, we have to supply an initial photo for the BehaviorSubject. So, we'll use a default placeholder profile picture (think a Facebook profile when there is no photo).

Search on the web for a generic user placeholder image. I'd suggest one as generic and androgynous as possible. We won't be checking their gender. Although, having two default profile images and checking their gender might be an interesting feature to practice your skills.

Save it to your assets folder - and, if it is called something different, make sure to update your code to match.

Next, we'll add another property to `auth.service.ts`:

```typescript
currentPhotoUrl = this.photoUrl.asObservable();
```

Add a method called `changeMemberPhoto()`:

```typescript
changeMemberPhoto(photoUrl: string) {
    this.photoUrl.next(photoUrl);
}
```

And, we'll need to update the `login()` method so that when a user logs in, we set the `currentPhotoUrl` to the `photoUrl` contained in the `user` object.

```typescript
login(model: any) {
    return this._http.post<AuthUser>(this.baseUrl + 'auth/login', model, { headers: new HttpHeaders()
        .set('Content-Type', 'application/json') })
        .map(user => {
        if (user) {
            localStorage.setItem('token', user.tokenString);
            localStorage.setItem('user', JSON.stringify(user.user));
            this.decodedToken = this._jwtHelperService.decodeToken(user.tokenString);
            this.currentUser = user.user;
            this.userToken = user.tokenString;
            this.changeMemberPhoto(this.currentUser.photoUrl);                          //  <--- Added
        }
        });
}
```

## Subscribing in Components

Now, we need to subscribe to this in the NavComponent.

In `nav.component.ts`, add a property called `photoUrl` and update the `ngOnInit()` method to the following:

```typescript
photoUrl: string;

//  ...

ngOnInit() {
    this.authService.currentPhotoUrl.subscribe(photoUrl => this.photoUrl = photoUrl);
}
```

Now, instead of using the `photoUrl` from the `user` - we'll use the `photoUrl` data that we're subscribing to.

```markup
<div class="profile-photo">
    <img src="{{ photoUrl }}" alt="{{ authService.currentUser.knownAs }}">
</div>
```

Next, we need to update this in `app.component.ts` as well:

```typescript
if (user) {
    this._authService.currentUser = user;
    this._authService.changeMemberPhoto(user.photoUrl);
}
```

We also need to update the `member-edit.component.ts` so that the profile panel's image is also hooked up to the same data stream.

```typescript
photoUrl: string;                                                                              //  <--- Added

//  ...

ngOnInit() {
    this._route.data.subscribe(data => {
      this.user = data['user'];
    });
    this._authService.currentPhotoUrl.subscribe(photoUrl => this.photoUrl = photoUrl);          //  <--- Added
}
```

Also, update the `member-edit.component.html` template:

And, finally - we need to update the `photo-editor.component.ts`

We'll call the `changeMemberPhoto()` method and set the `currentUser.photoUrl` in our `AuthService`

We'll also reset the token in local storage.

```typescript
 setMainPhoto(photo: Photo) {
    this._userService.setMainPhoto(this._authService.decodedToken.nameid, photo.id).subscribe(() => {
      this.currentMain = _.findWhere(this.photos, { isMain: true });
      this.currentMain.isMain = false;
      photo.isMain = true;
      this._authService.changeMemberPhoto(photo.url);                               //  <--- Modified
      this._authService.currentUser.photoUrl = photo.url;                           //  <--- Added
      localStorage.setItem('user', JSON.stringify(this._authService.currentUser));  //  <--- Added
    }, error => {
      this._alertify.error(error);
    });
}
```

## Wrap-up

Test it our in your application. When you change the main photo in the profile editing section of the site, it should update in the profile panel and in the navbar.

[We finally added our profile photo in the navbar feature.](http://i.imgur.com/lOm0DdB.jpg) That was quite a bit of work. Especially for something that doesn't add all that much to our app.

[But, we learned a lot](https://media.giphy.com/media/83QtfwKWdmSEo/giphy.gif) and that's what we're here for!
