0

When we want to report upload progress of a http request we add options to the request.

I.e.

const url = environment.content_creator_self_content_feed_posts_get + '/' + 
 this.createdpost.id;
          this.http.put(url, payload, {
            reportProgress: true,
            observe: 'events'
          }).subscribe(
              (event: any)=>{
                switch (event.type){
                  case HttpEventType.UploadProgress:
                    this.coverphotoprogress = Math.round(event.loaded / event.total * 100);
                    break;
                  case HttpEventType.Response:

                }

              });

but how do we do the same when we are chaining observables?

example take this request:

uploadmedia(event, type){

    this.s3.privateresourceuploadtos3(event, this.createdpost.contentcreator, this.createdpost.id, type)
      .subscribe(
        (req: any)=> {
          this.mediahasbeenuploaded = true;

        });
  }

and then the privateresourceuploadtos3 function it is subscribing to

privateresourceuploadtos3(event, userid, contentpostid, contenttype): Observable<any>{

    const mediatobeuploaded = event.target.files[0];
    const url = environment.private_generate_presigned_url_resource + userid + '/' + contentpostid + '/' + contenttype;
    return this.http.get(url).pipe(
      switchMap((req : any)=>{
        const resourceurl = req.uriroot + req.fields.key;

        let fd = new FormData();
        fd.append('acl', req.fields.acl);
        fd.append('key', req.fields.key);
        fd.append('content-type', req.fields['content-type']);
        fd.append('policy', req.fields.policy);
        fd.append('x-amz-meta-user', req.fields['x-amz-meta-user']);
        fd.append('x-amz-meta-contentpost', req.fields['x-amz-meta-contentpost']);
        fd.append('x-amz-meta-rawbucketkey', req.fields['x-amz-meta-rawbucketkey']);
        fd.append('x-amz-algorithm', req.fields['x-amz-algorithm']);
        fd.append('x-amz-credential', req.fields['x-amz-credential']);
        fd.append('x-amz-date', req.fields['x-amz-date']);
        fd.append('x-amz-signature', req.fields['x-amz-signature']);
        fd.append('file', mediatobeuploaded);
        return this.http.post(req.url, fd).pipe(
          // answer two https://stackoverflow.com/questions/51176537/angular-6-and-node-js-aws-s3-file-upload-progress-bar

          switchMap((req2: any)=>{
            const result = {
              resourceurl : resourceurl,
              resourcekey: req.fields.key
            };
            return of(result);
          }));
      }));
  }

this part in particular

return this.http.post(req.url, fd).pipe(
              switchMap((req2: any)=>{
                const result = {
                  resourceurl : resourceurl,
                  resourcekey: req.fields.key
                };
                return of(result);
              }));
          }));

the request is made then we use switchMap to change to another observable which returns an object of the request.

it would make sense that the options be added to this http request. Something like

return this.http.post(req.url, fd, {
                reportProgress: true,
                observe: 'events'
                 }).pipe(
                  switchMap((req2: any)=>{
                    const result = {
                      resourceurl : resourceurl,
                      resourcekey: req.fields.key
                    };
                    return of(result);
                  }));
              }));

but im not exactly sure to what I would do next so that one if the request is done it returns the result.

or if not. It returns a event and the code that is subscribe to the function listening to privateresourceuploadtos3 is receciving the progress events so that can be displayed on the screen

uploadmedia(event, type){
    
        this.s3.privateresourceuploadtos3(event, this.createdpost.contentcreator, this.createdpost.id, type)
          .subscribe(
            (req: any)=> {
              this.mediahasbeenuploaded = true;
    
            });
      }

1 Answers1

0

this was my hacky solution. But I guess it works. But I always remember. If it's stupid but it works it isn't stupid. And a CPU is a rock we tricked into thinking.

privateresourceuploadtos3(event, userid, contentpostid, contenttype): Observable<any>{

    const mediatobeuploaded = event.target.files[0];
    const url = environment.private_generate_presigned_url_resource + userid + '/' + contentpostid + '/' + contenttype;
    return this.http.get(url).pipe(
      switchMap((req : any)=>{
        const resourceurl = req.uriroot + req.fields.key;

        let fd = new FormData();
        fd.append('acl', req.fields.acl);
        fd.append('key', req.fields.key);
        fd.append('content-type', req.fields['content-type']);
        fd.append('policy', req.fields.policy);
        fd.append('x-amz-meta-user', req.fields['x-amz-meta-user']);
        fd.append('x-amz-meta-contentpost', req.fields['x-amz-meta-contentpost']);
        fd.append('x-amz-meta-rawbucketkey', req.fields['x-amz-meta-rawbucketkey']);
        fd.append('x-amz-algorithm', req.fields['x-amz-algorithm']);
        fd.append('x-amz-credential', req.fields['x-amz-credential']);
        fd.append('x-amz-date', req.fields['x-amz-date']);
        fd.append('x-amz-signature', req.fields['x-amz-signature']);
        fd.append('file', mediatobeuploaded);
        return this.http.post(req.url, fd, {
          reportProgress: true,
          observe: 'events'
        }).pipe(
          // answer two https://stackoverflow.com/questions/51176537/angular-6-and-node-js-aws-s3-file-upload-progress-bar

          switchMap((event: any)=>{
            switch(event.type){
              case HttpEventType.UploadProgress:
                const result = {
                  progressreport: true,
                  progress: Math.round(event.loaded / event.total * 100)
                  };
                return of(result);
              case HttpEventType.Response:
                const result = {
                  progressreport: false,
                  resourceurl : resourceurl,
                  resourcekey: req.fields.key
                };
                return of(result);
            }
          }));
      }));
  }