# 7.7: Adding Photo Upload in Angular

Now that we have our photo upload capability on the back-end, let's add the functionality in the Angular application.

## Add PhotoEditorComponent

Inside of the members folder in the SPA project, generate a new component called PhotoEditorComponent:

```
ng g c members/photo-editor --no-spec
```

Verify that it's added to `app.module.ts`

This will be a child component of our MemberEditComponent. So, let's add an Input property of an array of Photos to the `photo-editor.component.ts` file:

```typescript
export class PhotoEditorComponent implements OnInit {
  @Input() photos: Photo[];

  constructor() { }

  ngOnInit() {
  }

}
```

## PhotoEditorTemplate

Update `photo-editor.component.htmls` to:

```markup
<div class="row">
  <div class="col-md-2" *ngFor="let photo of photos">
    <img class="thumbnail" src="{{ photo.url }}" alt="{{ photo.description }}">
    <div class="row justify-content-center">
      <button type="button" class="btn btn-sm btn-secondary">Main</button>
      <button type="button" class="btn btn-sm btn-warning"><i class="fa fa-trash-o"></i></button>
    </div>
  </div>
</div>
```

Next, add it to the MemberEditComponent where we have placeholder text of `Edit photos will go here.`

We'll also grab the photos to send to our PhotoEditorComponent's Input property from our MemberEditComponent's User property:

```markup
<tab heading="Edit Photos">
    <app-photo-editor [photos]="user.photos"></app-photo-editor>
</tab>
```

## Add Styling to the Component

Let's add a custom color to our for warnings. In `styles.scss` add the following:

```css
$orange: #f79569;

//  ...

$theme-colors: (
    "primary": $red,
    "secondary": $cyan,
    "warning": $orange          //   <--- Added
);
```

And, in `photo-editor.component.scss`, add the following style:

```css
img.thumbnail {
    height: 100px;
    width: 100px;
    margin-bottom: 3px;
}
```

## Add File Uploader

We're going to use another library to handle file uploading called `ng2-file-upload`. It's by the same people that wrote our ngx-bootstrap library. See the docs [here](https://valor-software.com/ng2-file-upload/).

Run the following command to install the library:

```
npm install ng2-file-upload --save
```

Import it into the `app.module.ts` file and add it to the imports array:

```typescript
import { FileUploadModule } from 'ng2-file-upload';

//  ...
```

We'll be copying the examples from the documentation and modifying them to our needs.

In `photo-editor.component.ts`, modify it to this:

```typescript
export class PhotoEditorComponent implements OnInit {
  @Input() photos: Photo[];
  uploader: FileUploader;
  hasBaseDropZoneOver = false;

  constructor() { }

  ngOnInit() {
  }

  public fileOverBase(e: any): void {
    this.hasBaseDropZoneOver = e;
  }

}
```

Next, in our `photo-editor.template.html` template, below the `</div>` where we left off last time, add the following:

## Wiring Up File Uploader

Now, we need to implement an `initializeUploader()` method. We'll also inject the `AuthService` and add the base URL from our `environment`.

```typescript
export class PhotoEditorComponent implements OnInit {
  @Input() photos: Photo[];
  uploader: FileUploader;
  hasBaseDropZoneOver = false;
  baseUrl = environment.apiUrl;

  constructor(private _authService: AuthService) { }

  ngOnInit() {
    this.initializeUploader();
  }

  public fileOverBase(e: any): void {
    this.hasBaseDropZoneOver = e;
  }

  initializeUploader() {
    this.uploader = new FileUploader({
      url: this.baseUrl + 'users/' + this._authService.decodedToken.nameid + '/photos',
      authToken: 'Bearer ' + localStorage.getItem('token'),
      isHTML5: true,
      allowedFileType: ['image'],
      removeAfterUpload: true,
      autoUpload: false,
      maxFileSize: 10 * 1024 * 1024
    });

    this.uploader.onSuccessItem = (item, response, status, headers) => {
      if (response) {
        const res: Photo = JSON.parse(response);
        const photo = {
          id: res.id,
          url: res.url,
          dateAdded: res.dateAdded,
          description: res.description,
          isMain: res.isMain
        };

        this.photos.push(photo);
      }
    };

  }

}
```

## Test It Out

![PhotoUpload1](https://122480229-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAU8YfVcpLNVPaSQtyc%2F-LEoXBIjxiJ9_48lrXMp%2F-LEoXETWXEMDBTzycM5j%2Fphotoupload1.png?generation=1528816009340885\&alt=media)

![PhotoUpload2](https://122480229-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAU8YfVcpLNVPaSQtyc%2F-LEoXBIjxiJ9_48lrXMp%2F-LEoXETYMeLx3GRlHV3X%2Fphotoupload2.png?generation=1528816009255192\&alt=media)

Now that we have multiple photos, we can also try out our photo carousel:

![CarouselTest](https://122480229-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LAU8YfVcpLNVPaSQtyc%2F-LEoXBIjxiJ9_48lrXMp%2F-LEoXET_3yUmPbreNXnI%2Fcarouseltest.png?generation=1528816009471953\&alt=media)
