简体   繁体   中英

How to reload the image src after uploading the image file into AWS S3?

On the user profile page, my module gets an image from the gallery, uploads it to AWS S3, and then updates the existing image. However, even though the image has already been uploaded to AWS S3, the user profile image is not reloaded on the screen. One strange thing is that when I trigger some other event(eg, a segment or other button is clicked), the uploaded image is loaded. How should I trigger an event to reload an updated image?

I've already tried trigger events using Injectable and Subject, but it didn't solve this problem. Also, ChangeDetectorRef didn't solve this issue.

(Ionic 5 Cordova / Angular)

// typescript code:

import { UUID } from 'angular2-uuid';
import { Camera, CameraOptions } from '@ionic-native/camera/ngx';  

userImage: any;  

constructor(private platform: Platform,   
    private changeRef: ChangeDetectorRef, 
    private camera: Camera, 
    private util: UtilService, 
    private events: EventsService, 
    private rcvEvents: EventsService ) { 
} 

openGallery() {  
    const options: CameraOptions = {
      quality: 100, 
      targetWidth: 480, 
      targetHeight: 640, 
      sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
      destinationType: this.camera.DestinationType.FILE_URI,
      encodingType: this.camera.EncodingType.JPEG,
      mediaType: this.camera.MediaType.PICTURE,
    }; 
    const uuid = UUID.UUID().toString();  
    const uuid_file = uuid.replace(/-/g, "") + ".jpg"; 

     this.camera.getPicture(options).then((uri) => { 
      this.util.makeFileIntoBlob(uri, uuid_file).then((imageData:any) => {
        this.util.uploadAwsFile(imageData, 'user', uuid_file).then(res => { 
            const result = res['data'];  
            this.userImage = result['Location']; 
            }); 
        });  
    }).catch(err =>{ 
      this.util.presentToast(`${err}`, false, 'bottom', 1500); 
    });
  } 
// HTML 
<img [src]="userImage" class='round-image' (click)="openGallery()">

I think this issue is because of something very interesting and powerful called Zones . If the concept is new for you, please refer to here and here for a great explanation.

As mentioned in those articles:

Application state change is caused by three things:

  1. Events - User events like click, change, input, submit, …
  2. XMLHttpRequests - Eg when fetching data from a remote service
  3. Timers - setTimeout(),setInterval(), because JavaScript

… it turns out that these are the only cases when Angular is actually interested in updating the view.

So the problem is that your code is running some async tasks and then tries to update a property related to the view, but nothing is telling Angular that the view should be updated.

One way to fix it would be to run that code inside of a zone , like this:

  constructor(
      private platform: Platform,   
      private changeRef: ChangeDetectorRef, 
      private camera: Camera, 
      private util: UtilService, 
      private events: EventsService, 
      private rcvEvents: EventsService,
      private ngZone: NgZone, // <----- first inject it like this
  ) {} 

  ...

  // then in that method...
  this.camera.getPicture(options).then((uri) => { 
     this.util.makeFileIntoBlob(uri, uuid_file).then((imageData:any) => {
         this.util.uploadAwsFile(imageData, 'user', uuid_file).then(res => { 
             this.ngZone.run(() => { // <----- then use it like this
                 const result = res['data'];  
                 this.userImage = result['Location']; 
             });          
          }); 
       });  
   }).catch(err => { 
      this.util.presentToast(`${err}`, false, 'bottom', 1500); 
   });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM