jaydenseric / apollo-upload-client

A terminating Apollo Link for Apollo Client that fetches a GraphQL multipart request if the GraphQL variables contain files (by default FileList, File, or Blob instances), or else fetches a regular GraphQL POST or GET request (depending on the config and GraphQL operation).
https://npm.im/apollo-upload-client
1.53k stars 155 forks source link

Using in angular 5 #44

Closed manzonif closed 6 years ago

manzonif commented 6 years ago

It is possible to use it in angular? I was able to use the previuos version of upload-client (networkInterface), but I not sure if I can with apollo-link.

Thanks in advance

jaydenseric commented 6 years ago

I don't see why not, there is nothing React specific about it 🙂

manzonif commented 6 years ago

I'm going crazy with angular universal. I not still understand how debug properly on the server side :-(. So, for now I only know that this works for me:

import { Apollo } from 'apollo-angular';
import { HttpLink } from 'apollo-angular-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';

class AppModule {
  constructor(
    apollo: Apollo,
    httpLink: HttpLink
  ) {
    apollo.create({
      link: httpLink.create({ uri: 'https://api.example.com/graphql' }),
      cache: new InMemoryCache()
    });
  }
}

this doesn't works:

import { Apollo } from 'apollo-angular';
import { createUploadLink } from 'apollo-upload-client';
import { InMemoryCache } from 'apollo-cache-inmemory';

class AppModule {
  constructor(
    apollo: Apollo,
    httpLink: HttpLink
  ) {
    apollo.create({
      link: createUploadLink({ uri: 'https://api.example.com/graphql' }),
      cache: new InMemoryCache()
    });
  }
}

I saw that apollo-angular-link-http extends ApolloLink

giautm commented 6 years ago

@jaydenseric Hey, look like has some Angular specific for HttpLink

https://github.com/apollographql/apollo-angular/blob/master/packages/apollo-angular-link-http/src/HttpLink.ts

i think we can create a package like angular-fetch-api. and using like this:

import { Apollo } from 'apollo-angular';
import { createUploadLink } from 'apollo-upload-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { createFetch } from 'angular-fetch-api';

class AppModule {
  constructor(
    apollo: Apollo,
    httpLink: HttpLink
  ) {
    apollo.create({
      link: createUploadLink({
        uri: 'https://api.example.com/graphql',
        // Wrap Angular's HttpClient as Fetch API.
        fetch: createFetch(),
      }),
      cache: new InMemoryCache()
    });
  }
}
Eraldo commented 6 years ago

Do I understand it correctly that angular-fetch-api does not exist yet? :)

Eraldo commented 6 years ago

And.. why does it say "angular 5" is there a different solution for "angular 4"?

PowerKiKi commented 6 years ago

Just wanted to let you know that I got this lib working without issue with Angular 5 and Apollo 2 with something like:

diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 152f8af..be4b34d 100644
--- a/client/app/app.module.ts
+++ b/client/app/app.module.ts
@@ -2,8 +2,8 @@ import { BrowserModule } from '@angular/platform-browser';
 import { NgModule } from '@angular/core';
 import { HttpClientModule } from '@angular/common/http';
 import { Apollo, ApolloModule } from 'apollo-angular';
-import { HttpLink, HttpLinkModule } from 'apollo-angular-link-http';
 import { ApolloLink, concat } from 'apollo-link';
+import { createUploadLink } from 'apollo-upload-client';
 import { InMemoryCache } from 'apollo-cache-inmemory';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import {
@@ -66,7 +66,6 @@ import { ImageService } from './image/services/image.service';
         FormsModule,
         ReactiveFormsModule,
         ApolloModule,
-        HttpLinkModule,
         BrowserAnimationsModule,
         MatButtonModule,
         MatCheckboxModule,
@@ -102,8 +101,8 @@ import { ImageService } from './image/services/image.service';
     bootstrap: [AppComponent],
 })
 export class AppModule {
-    constructor(apollo: Apollo, httpLink: HttpLink, networkActivitySvc: NetworkActivityService) {
-        const link = httpLink.create({uri: '/graphql'});
+    constructor(apollo: Apollo, networkActivitySvc: NetworkActivityService) {
+        const link = createUploadLink({uri: '/graphql'});

         const middleware = new ApolloLink((operation, forward) => {
             networkActivitySvc.increase();
jaydenseric commented 6 years ago

@manzonif does @PowerKiKi's example resolve this issue?

manzonif commented 6 years ago

@jaydenseric, seems to be ok. Now I have to update on the server side...

manzonif commented 6 years ago

@jaydenseric, in Angular Universal, there is a problem with linkFetch as @giautm pointed out. So I think it need something specific for angular.

manzonif commented 6 years ago

@jaydenseric, for what I understood, basically, there are a couple of issue on using Angular 5 Universal. The first is that Universal performs all needed Graphql requests on server side, where is not available Global.fetch. Furthermore, when an http request is performed on server side, it can be cached to avoid that the same request will be sent on client side. this mechanism is achieved through, TransferHttpCacheModule and HttpClient.

I also noticed that angular-link-http provides a different behavior if the request method is different from 'POST', 'PUT', 'PATCH', (shouldUseBody). I do not know the reasons.

I just quickly realized a merging of the two modules and quickly tested. Do you think that somehow this logic can be implemented in your module?

Relevant code is here.

jaydenseric commented 6 years ago

@manzonif it sounds like this is a use case for the fetch option; it's explained in more detail here for the vanilla http link.

jaydenseric commented 6 years ago

If anyone works out a solution, feel free to report back or open a PR if necessary.

mrdulin commented 6 years ago

same issue. Need apollo-upload-client + Angular 5 example

PowerKiKi commented 6 years ago

@mrdulin see my earlier comment

mrdulin commented 6 years ago

@PowerKiKi I made a sample using apollo-upload-client + Angular 6.

This is apollo graphql server: https://github.com/mrdulin/apollo-server-express-starter/blob/master/src/fileupload/server.js

This is apollo graphql Angular6 client: https://github.com/mrdulin/angular-apollo-starter/blob/master/src/app/upload/upload.component.ts

hkjalwaniya commented 5 years ago

@mrdulin I am using almost the same code as yours but my upload request is not being converted into multipart as backend is throwing GraphQL error: createReadStream is not a function image

hkjalwaniya commented 5 years ago

backend code is : export const uploadFile = async (fileToUpload, userName) => { console.log('fileToUpload',fileToUpload); const {createReadStream, filename, mimetype} = await fileToUpload; const stream = createReadStream(); const saveResponse = await saveFile(stream, filename, userName); return (saveResponse); };

intellix commented 5 years ago

This has been added to apollo-angular-link-http 1.6: https://github.com/apollographql/apollo-angular/commit/bd9f68310fbc9164065aaf122474fa141f908ece#diff-e7ae3030ff923dfadbbb984508439a19

just add context: { useMultipart: true } to your mutation

hkjalwaniya commented 5 years ago

This has been added to apollo-angular-link-http 1.6: apollographql/apollo-angular@bd9f683#diff-e7ae3030ff923dfadbbb984508439a19

just add context: { useMultipart: true } to your mutation

@intellix really thanks I was stuck in my demo project for 2 weeks and looking for the solution.

RyannGalea commented 4 years ago

This has been added to apollo-angular-link-http 1.6: apollographql/apollo-angular@bd9f683#diff-e7ae3030ff923dfadbbb984508439a19

just add context: { useMultipart: true } to your mutation

Angular example of sending a file to the server? I continue to have an empty file object on my sevrer.

nbaua commented 4 years ago

I am getting 0 byte files after following the instructions, and adding the { useMultipart: true }, It seems not working with Angular 8/9, does anyone got this resolved?

fourjuaneight commented 3 years ago

Same here. Stuck on 0 bytes and a pending request that times out. On Angular 11.