0.1.2 • Published 5 years ago

apollo-uploader v0.1.2

Weekly downloads
10
License
MIT
Repository
github
Last release
5 years ago

See example application.

Table of contents:

Install

npm i apollo-uploader

Initialize

import { createUploadLink, Uploader } from 'apollo-uploader';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';

const uploadLink = createUploadLink('http://site.com/grqphql')
const apolloClient =  new ApolloClient({
    link: uploadLink,
    cache: new InMemoryCache({})
});
Uploader.init({apolloClient});

Initial configuration

PropertyTypeDescriptionDefault
apolloClientApolloClientApolloClient instanceno
onSuccess() => PromiseCallback called when upload is successyes (stub)
mutationDocumentNodeMutation which uploader sends to servermutation uploadFile($file: Upload!) {uploadFile(file: $file)}

Note:

  • Assumes that you already have installed apollo-client and some of Apollo cache implementation like apollo-cache-inmemory.
  • Instead of direct passing uploadLink to link property at ApolloClient config, you should concat it with other links in your app, i.e http link. For example you can use from() from 'apollo-link':
...
import { from } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';

const uri = 'http://site.com/grqphql';
const httpLink = new HttpLink({uri});
const apolloClient =  new ApolloClient({
    ...
    link: from([httpLink, uploadLink])
});

Basic usage

import * as React from 'react';
import { upload } from 'apollo-uploader';

class UploadExample extends React.Component {
    handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        upload(e.target.files[0], {})
            .subscribe((value: any) => console.log(value));
        
    };

    render() {
        return (
            <div>
                <input type="file" onChange={this.handleFileChange}/>
            </div>
        );
    }
}

Advanced usage

import * as React from 'react';
import { upload } from 'apollo-uploader';
import {FileUploadProcess, FileUploadStatuses} from "apollo-uploader/lib/types";

class UploadExample extends React.Component {
    handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        upload(e.target.files[0], {
                    crop: {
                        offsetX: 25,
                        offsetY: 37,
                        width: 600,
                        height: 600,
                    },
                    bucket: 'image'
                }).subscribe((uploadProcess: FileUploadProcess) => {
                      switch (uploadProcess.status) {
                          case FileUploadStatuses.UPLOAD_IN_PROGRESS:
                              console.log(`Upload in progress. Uploaded: ${uploadProcess.loaded} from ${uploadProcess.total}`);
                              break;
                          case FileUploadStatuses.UPLOAD_ERROR:
                              console.log(`Upload error: ${uploadProcess.error}`);
                              break;
                          case FileUploadStatuses.UPLOAD_DONE:
                              console.log(`File successfully loaded!`);
                              break;
          
                      }
                });
    };

    render() {
        return (
            <div>
                <input type="file" onChange={this.handleFileChange}/>
            </div>
        );
    }
}

List of upload processes

You can get all changes of upload processes just by using Apollo Query component and uploading query:

import * as React from 'react';
import {Queries} from 'apollo-uploader';
import {Query} from "react-apollo";
import {FileUploadProcess} from "apollo-uploader/lib/types";

class UploadList extends React.Component {

    render(): React.ReactElement | string {
        return (
            <div>
                <h2>Upload processes</h2>
                <table>
                    <tbody>
                    <tr>
                        <th>id</th>
                        <th>fileName</th>
                        <th>status</th>
                        <th>fileSize</th>
                        <th>loaded</th>
                        <th>total</th>
                        <th>result</th>
                        <th>error</th>
                    </tr>

                    <Query query={Queries.uploading}>
                        {({data}: { data: { uploading: FileUploadProcess[] } }) =>
                            data.uploading.map((process: FileUploadProcess) => {
                                const result = JSON.parse(process.result);

                                return (
                                    <tr key={process.id}>
                                        <td> {process.id} </td>
                                        <td> {process.fileName} </td>
                                        <td> {process.status} </td>
                                        <td> {process.loaded} </td>
                                        <td> {process.fileSize} </td>
                                        <td> {process.total} </td>
                                        <td> {result.id} </td>
                                        <td> {process.error} </td>
                                    </tr>
                                )
                            })
                        }
                    </Query>
                    </tbody>
                </table>
            </div>
        );
    }
}

Note: Do not forget to wrap a root component with an ApolloProvider.

Upload callback

You can pass a second argument as a callback function when initializing Uploader.

...

const onSuccess = (result: {id: string}): Promise<any> => {
     return new Promise((resolve: (result: any) => void, reject: () => void) => {
         // do some stuff here
         if(/* success */) {
             resolve(result);
         } else {
             reject();
         }
         // or call reject on error
         
     });
 };

Uploader.init({
    apolloClient, 
    onSuccess
});

Customize upload mutation

Apollo-uploader sends a mutation with attached file. You need to implement resolver on your server for uploadFile mutation. You can customize upload mutation by passing it in Uploader.init(). You MUST NOT change mutation name and parameter file.

...
import gql from "graphql-tag";

Uploader.init({
    ...
    mutation: gql`
      mutation uploadFile($file: Upload!, $customParam: String!) {
          uploadFile(file: $file, customParam: $customParam)
      }`
});

And then pass customParam to upload():

import { upload } from 'apollo-uploader';

upload(file, {
            customParam: 'custom param value'
        })

FileUploadProcess

PropertyTypeDescription
idstringInternal ID (autogenerated).
fileNamestringLocal file name.
fileSizenumberFile size in bytes.
statusFileUploadStatusesStatus of uploading.
loadednumberNumber of bytes uploaded to server.
totalnumberFile size in bytes. You should use this value with loaded to get loading progress.
resultstringuploadFile property in server response. Use JSON.parse() to access is as an object.

FileUploadStatuses

StatusDescription
UPLOAD_PENDINGFile is waiting to be sent to the server.
UPLOAD_IN_PROGRESSUpload in progress.
UPLOAD_DONEUpload successfully finished.
UPLOAD_ERRORError happened during upload.
UPLOAD_ABORTED_BY_CLIENTProcess aborted by sending abort mutation or calling abort() method.
POST_UPLOAD_PROCESS_ERRORCalled reject() in upload callback.
POST_UPLOAD_PROCESS_DONECalled resolve() in upload callback.

License

0.1.2

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago

0.0.16

5 years ago

0.0.15

5 years ago

0.0.14

5 years ago

0.0.13

5 years ago

0.0.12

5 years ago

0.0.11

5 years ago

0.0.10

5 years ago

0.0.9

5 years ago

0.0.8

5 years ago

0.0.7

5 years ago

0.0.6

5 years ago

0.0.5

5 years ago

0.0.4

5 years ago

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago