Nilakshi Naphade
Nilakshi Naphade

Reputation: 1085

Angular 2 uploaded picture does not persist on page after reload

I have created component for Uploading profile picture. Image preview, upload, delete, resize everything is working fine but once I reload the page, my picture does not persist on page. I'm using GET API for fetching uploaded image on reload, which is working fine (I've crosschecked it in postman).

Following is upload-picture service:

getPicture(userId = 'Current') {
    console.log(userId);

    let headers = new Headers();
    let data = new FormData();

    headers.append('authorization', 'Bearer ' + localStorage.getItem('id_token'));
    headers.append('Access-Control-Allow-Origin', '*');
    const url = 'http://docker-hip.cs.upb.de:5000/api/Users/'+ userId+ '/picture';

    return this.http.get(url, {headers})
      .toPromise()
      .then((response: any) => {return(response)})
      .catch(this.handleError);
  }

  public uploadPicture(fileToUpload: any, userId = 'Current') {
    let headers = new Headers();
    let data = new FormData();
    data.append('file', fileToUpload);

    headers.append('authorization', 'Bearer ' + localStorage.getItem('id_token'));
    headers.append('Access-Control-Allow-Origin', '*');

    const url = 'http://docker-hip.cs.upb.de:5000/api/Users/' + userId + '/picture';

    return this.http.post(url, data, {headers})
       .toPromise()
       .then((response: any) => {return(response)})
       .catch(this.handleError);
  }

Here is upload-picture component:

 ngOnInit(): void {
    const urls = this.route.snapshot.url;
    const urlSegment = urls.shift();
    // the user is in the admin view if the url starts with 'admin':
    if (urlSegment.path === 'admin') {
      // get the user id from the last part of the url:
      this.userId = urls.pop().path;
    } else {
      this.userId = 'Current';
    }

    this.userService.getPicture()
    .then(response => {
      console.log(typeof(response));
      return response;
    })
    .catch(this.displayError)

    console.log(this.file_srcs);

    if(this.fileCount > 0)
     {
      this.previewImage(this.fileToUpload)
     }

  }

  uploadPicture(): void {
    let fi = this.fileInput.nativeElement;

    if (fi.files && fi.files[0]) {
      console.log(fi.files[0]);
      this.fileToUpload = fi.files[0];
      this.userService.uploadPicture(this.fileToUpload, this.userId)
      .then(response => console.log('Image uploaded successfully!'))
      .catch(this.displayError);
    }
  }

  increaseCount()
  {
    this.fileCount = this.file_srcs.length+1;
    this.isUpload = false;
    this.isRemoved =  false;
    console.log(this.fileCount);
  }

  previewImage(fileInput: any) {
    this.fileToUpload = <Array<File>> fileInput.files;
    console.log(this.fileToUpload)
    for (var i = 0; i < fileInput.files.length; i++) {
      this.files.push(fileInput.files[i]);
      console.log(fileInput.files[i])

      var img = document.createElement("img");
      img.src = window.URL.createObjectURL(fileInput.files[i]);
      let reader = new FileReader();
      reader.addEventListener("load", (event) => {
        img.src = reader.result;

        this.file_srcs.push(img.src);
      }, false);
      reader.readAsDataURL(fileInput.files[i]);
      this.isUpload = true;
      this.uploadPicture();
    }
  }

Here is HTML for upload-picture component:

<div>
  <md-card class="Image">
    <div *ngFor = "let file_src of file_srcs">  
      <img  class = "uploadedImage" src="{{ file_src }}" alt="" />
    </div> 
  </md-card>              
  <input id = "uploadedFile" class = "uploadButton" type="file" #fileInput (change) = "increaseCount()"/>
  <button md-raised-button color="primary" [disabled] = "fileCount == 0 || isUpload" class="uploadButton" (click)="previewImage(fileInput)">Upload Picture</button>
  <button md-raised-button color="primary" [disabled] = "fileCount == 0 || isRemoved" class="uploadButton" (click)="removePicture()">Remove Picture</button>
</div>

I tried calling same previewImage function in ngOnInit to render image on UI, but I don't know what parameter I shall pass to it. Can someone please help.

Upvotes: 0

Views: 746

Answers (1)

Mostafa Abdelraouf
Mostafa Abdelraouf

Reputation: 628

In ngOnInit, this code seems to be responsible

this.userService.getPicture()
.then(response => {
  console.log(typeof(response));
  return response;
})
.catch(this.displayError)
// You seem to assume that at this point the images are loaded
// which is not the case because the promise will take some time
// to be resolved but the next line will be executed immediately 
// before the promise is resolved so you will always have this line
// output an empty array "[]"
console.log(this.file_srcs);

if(this.fileCount > 0)
 {
  this.previewImage(this.fileToUpload)
 }

Instead you should move your this.previewImage calls into the .then() of the this.userService.getPicture, maybe something along the lines of this

this.userService.getPicture()
.then(response => {
     //You will probably need to fill this.file_srcs with data from response
     console.log(this.file_srcs);
     if(this.fileCount > 0)
     {
        this.previewImage(this.fileToUpload)
     }
     console.log(typeof(response));
     return response;
})
.catch(this.displayError)

Upvotes: 1

Related Questions