Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for request progress #526

Open
szechyjs opened this issue Mar 27, 2018 · 14 comments
Open

Add support for request progress #526

szechyjs opened this issue Mar 27, 2018 · 14 comments

Comments

@szechyjs
Copy link

Angular now provides support for monitoring the progress of HTTP requests through an observable.

https://angular.io/guide/http#listening-to-progress-events

It would be great if this could be exposed through apollo-angular.

@kamilkisiela
Copy link
Owner

If you're interested in posting a PR, I could guide you and give some help. Just let me know.

@artem-galas
Copy link
Contributor

@kamilkisiela I would like to work on it.

Here is my thought how to implement it:

  1. Extend HttpRequestOptions type add new field reportProgress?: boolean
  2. Add that new field to request creation
const req: Request = {
          .....
          options: {
            ....
            reportProgress: this.options.reportProgress || false
          },
        };
  1. In util.ts in link-http-common remove reportProgress: false from create httpClient request.

Could you please look through and give your opinion?

Thanks.

@kamilkisiela
Copy link
Owner

If it's disabled by default then sure, let's do it. Make sure user can enable/disable not only in Link's config but also through operation's context.

@artem-galas
Copy link
Contributor

I've faced with two minor issues, that I don't know how to solve correct.

  1. Issue with types - compiler complains and want 'body' into observe variable
  2. Issue with testing.

Since in tests execute method are used (that come from appolo-link package) that method not using my local code, so I don't get HttpEvent response, I guess.

@kamilkisiela Could give me piece of advice?
And Could you please explain what do you mean:

but also through operation's context.

What is operation's context?

Thanks.

@kamilkisiela
Copy link
Owner

@artem-galas https://github.com/artem-galas/apollo-angular/pull/1

I'm interested how you will ship the progress value to the consumer. Apollo.query and Apollo.watchQuery both resolve with Observable<ApolloQueryResult>.

@artem-galas
Copy link
Contributor

@kamilkisiela Thanks for your help.

Yes, I'm also interested how to deliver that functionality to consumer....

I'm thinking to make reportProgress work we have to patch apollo-link / apollo-client packages, but I'm not sure it's a good Idea, because these packages are really significant and we can not change them for angular needs :)

What do you think?

@kamilkisiela
Copy link
Owner

@artem-galas Maybe a directive (let's say @http) inside of graphql operation? We can't break the interface of GraphQL Result.

Can I ask why you guys need to access this http progress thing? Can't that be done within http interception?

@artem-galas
Copy link
Contributor

@kamilkisiela

To be honest I hardly ever use reportProgress it might be useful when download/upload files and these operations dosen't not required GraphQL.
But might be for some heavy query it might be useful as well. But in that case it much more easy to implement it through the interceptor

Regarding directive @http inside graphQl operation, do you mean something like?

qpl
  @http
  heroes {
    name
 }

@leonetosoft
Copy link

leonetosoft commented Feb 20, 2020

I would really like to have this option without a "hack", but in this case I had to use rest.

@gsolecki
Copy link

gsolecki commented Mar 4, 2020

I would also like to have this option. In our application we upload files that have 1GB. We use https://github.com/jaydenseric/graphql-multipart-request-spec for this together with apollo-upload-client but I use the interceptor "the hacky way" to track progress.

@CDDelta
Copy link

CDDelta commented Mar 13, 2021

For those who want to be able to get the upload progress of files to their GraphQL endpoint yet don't want to hack around with apollo-upload-client, my solution was to simply reimplement the upload mutation using Angular's HttpClient with this helpful article.

Something like this:

import { HttpClient, HttpEventType, HttpResponse } from '@angular/common/http';
import { FetchResult } from '@apollo/client/core';
import { Apollo } from 'apollo-angular';
import { print } from 'graphql';
import { from, throwError } from 'rxjs';
import { filter, map, switchMap, tap } from 'rxjs/operators';
import { MutationError, UploadFileGQL, UploadFileMutation } from 'src/graphql';

const formData = new FormData();
formData.append(
'operations',
JSON.stringify({
  query: print(this.uploadFileGql.document),
  variables: {
    file: null,
  },
}),
);
formData.append(
'map',
JSON.stringify({
  file: ['variables.file'],
}),
);
formData.append('file', file, file.name);

this.http
.post('/graphql', formData, {
  reportProgress: true,
  observe: 'events',
})
.pipe(
  tap((event) => {
    if (event.type === HttpEventType.UploadProgress) {
      // You can get the upload progress here!
      console.log(Math.round((100 * event.loaded) / event.total!));
    }
  }),
  filter((event) => event.type === HttpEventType.Response),
  switchMap((event) => {
    const body: FetchResult<UploadFileMutation> = (<HttpResponse<any>>event).body!;

    if (!body.errors) {
      // This query refetching is optional and is only available in Apollo client 3.4+.
      return from(this.apollo.client.refetchQueries(['SomeQueriesToRefetch'])).pipe(map(() => body));
    } else {
      return throwError(body.errors);
    }
  }),
)
.subscribe(
  ({ data }: FetchResult<UploadFileMutation>) => {
  },
);

@directcuteo
Copy link

Any update on this? :/

@bardhyliis
Copy link

Is there any update on this?

@PowerKiKi
Copy link
Collaborator

No progress on this issue. It won't happen unless somebody make a PR for it.

One limitation to be aware of is that reportProgress for upload seems to be impossible for people using FetchBackend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants