How to save an instance of 'this' in a callback function

In Angular2, I have a component that uses a service to upload a file to Amazon S3.

My component (simplified):

private _loading = true;

// use service to upload file
this._s3service.uploadFile(fileObject, this.uploadCallback)

// use this function as a callback
uploadCallback(err, data) {
  this._loading = false; // this crashes because of 'this' is referring to service instead of component
} 

My service (simplified):

    private getS3(): any {
       // Get or create AWS instance
       return s3;
    }

    public uploadFile(selectedFile, callback): boolean {
       this.getS3().upload({
            Key: key_name,
            ContentType: file.type,
            Body: file,
            StorageClass: 'STANDARD',
            ACL: 'private'
          }, function(err, data){ // <=== What to do here?!
            callback(err, data)
          });
    }

The problem is that when the callback function is started from the service, it thisrefers to the service and this._loadingcannot be found.

Question: How to save an instance thisin my callback function, ( thisin the callback should point to component, not service)

+4
source share
3 answers

@Gunter , , this , :

uploadCallback(err, data) {
  this._loading = false; // this is the "this" you want to keep
} 

:

this._s3service.uploadFile(fileObject, ()=>this._loading = false);
// or 
this._s3service.uploadFile(fileObject, ()=>this.uploadCallback());
// or
this._s3service.uploadFile(fileObject, this.uploadCallback.bind(this));

, Observable :

public uploadFile(selectedFile): Observable<any> { // "<any>" because I don't know what is the type of "data"
    return Observable.create((observer) => {
        this.getS3().upload({
            Key: key_name,
            ContentType: file.type,
            Body: file,
            StorageClass: 'STANDARD',
            ACL: 'private'
        }, (err, data)=> {
            if(err)
              observer.error(err);
            else
              observer.next(data);
            observer.complete();
        });
    });
}

this._s3service.uploadFile(fileObject).subscribe(data=>console.log(data))
+3

  }, (err, data) => { // <=== What to do here?!

, this - , ​​.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

, .bind(this) , , , =>

myCallback(err, data){ // <=== What to do here?!
        callback(err, data)
}

public uploadFile(selectedFile, callback): boolean {
   this.getS3().upload({
        Key: key_name,
        ContentType: file.type,
        Body: file,
        StorageClass: 'STANDARD',
        ACL: 'private'
      }, this.myCallback.bind(this));
}

,

public uploadFile(selectedFile, callback): boolean {
   this.getS3().upload({
        Key: key_name,
        ContentType: file.type,
        Body: file,
        StorageClass: 'STANDARD',
        ACL: 'private'
      }, (err, data) => this.myCallback(err, data));
}
+10

uploadFile, promise.

, . -

    public uploadFile(selectedFile): boolean {
        return new Promise((resolve, reject) => {
          this.getS3().upload({
            Key: key_name,
            ContentType: file.type,
            Body: file,
            StorageClass: 'STANDARD',
            ACL: 'private'
         }, function(err, data){ // <=== What to do here?!
            resolve(err, data)
        });
       }
  });

 this._s3service.uploadFile(fileObject).then((err, data)=> {
   this._loading = false;
 });
0
source

Source: https://habr.com/ru/post/1672543/


All Articles