npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@dabapps/django-s3-file-upload

v0.1.3

Published

Upload files from the browser to S3 - client side implementation

Downloads

38

Readme

Django S3 File Upload Client

Build Status

Upload files from the browser to S3 - client side implementation (with redux integration)

For the server side implementation see github.com/dabapps/django-s3-file-upload-server

Installation

To install the package run:

npm i @dabapps/django-s3-file-upload -S

Compatibility

You will also need polyfills for both Promises and Symbols if you wish to target older browsers.

Usage

How it works

The flow to be able to upload files from the browser straight to AWS is as follows. Flow S3 file uploads

This library abstracts away the process of chaining the three requests that the frontend needs to make to upload a file from the browser to S3:

  1. Request upload from server
  2. Upload file to AWS S3
  3. Mark upload as complete on server

The implementation is specific to the endpoints setup in this repo github.com/dabapps/django-s3-file-upload-server so be sure to have the backend configured accordingly.

Redux integration

This library provides 3 functions that can be combined to handle uploading multiple files, and storing the results, errors, and loading states in redux.

createActionSet

This function simply creates an object with some keys that will be used internally to allow the action and reducer to communicate.

const UPLOAD_PROFILE_PHOTO = createActionSet('UPLOAD_PROFILE_PHOTO');

createFileUploadAction

This creates a redux-thunk action that handles dispatching requests, and actions that track the loading states of the files, as well as the responses / errors.

const uploadProfilePhoto = createFileUploadAction(UPLOAD_PROFILE_PHOTO);

createFileUploadAction takes an action set, and an optional options object, and returns a Promise<UploadData> (see Types).

Actions created with this function will not throw errors by default. This means that calling .catch on the returned promise will not be effective unless you utilize the following option...

Currently the options object only exists to allow you to provide a shouldRethrow function, which is called with any errors, and will cause the action to rethrow any errors if true is returned from shouldRethrow.

Once you've created your action you can then dispatch this from your store, or connected component e.g.

class MyComponent extends PureComponent<Props> {
  // ...
  private onSubmit = (data: FormData) => {
    this.props.uploadProfilePhoto([data.picture]);
  }
  // ...
}

export default connect(undefined, { uploadProfilePhoto })(MyComponent);

This takes an array of files. If you only have a single file to upload just provide an array containing that file.

You should prevent the user from attempting to upload the same set of, or additional files while the requests are in progress (as this will cause issues with the loading states). You can check the current loading state from the reducer, and disable your submit button.

createFileUploadReducer

This function is used to create a reducer for a specific set of file uploads.

DO NOT use the same reducer for uploading multiple sets of files unless you really know what you are doing.

const profilePhotoUpload = createFileUploadReducer(UPLOAD_PROFILE_PHOTO);

This can then be added to your store, and connected to React components to provide you with the UploadState (see Types).

Basic usage

The function uploadFileToS3 is used internally by the other functions that integrate with redux. If you're not using redux, you can use this to upload individual files, and manually store the loading state, responses, and errors.

uploadFileToS3 returns a Promise of type Promise<UploadData> (see Types).

Let's say we have a form which contains a file, which we want to upload to S3 on submit, we can do the following:

import { UploadData, uploadFileToS3 } from '@dabapps/django-s3-file-upload';

interface FormData {
  file: File
}

const handleSubmit = (formData: FormData): Promise<UploadData> => {
  uploadFileToS3(formData.file)
};

The file should now be stored in S3, but isn't linked to any useful models (apart from UploadedFile) on the backend yet.

Say we have a Llama model on the backend and an action implemented on the frontend to updateLlamaProfile. We'll probably want to update the Llama profile with the new file after it's been stored in S3.

We can do this by chaining our functions:

import { UploadData, uploadFileToS3 } from '@dabapps/django-s3-file-upload';

import { updateLlamaProfile, displayError } from './path';

interface FormData {
  file: File
}

const handleSubmit = (formData: FormData) => {
  uploadFileToS3(formData.file)
    .then(({id}) => {
      updateLlamaProfile({
        llama_file: id
      })
    })
    .catch((error) => {
      displayError(error);
    });
};

Types

The response type for each file upload:

interface UploadData {
  id: string;
  created: string;
  modified: string;
  complete_url: string;
  file: string;
  file_key: string;
  file_path: string;
  filename: string;
  upload_form: UploadForm;
}

Reducer state:

interface UploadState {
  loading: boolean;
  fileCount: number; // Total number of files to be uploaded
  inFlightCount: number; // Number of files being uploaded (but have not finished)
  completeCount: number;
  successCount: number;
  failureCount: number;
  data: undefined | ReadonlyArray<UploadData>;
  error: undefined | ReadonlyArray<unknown>;
}

Code of conduct

For guidelines regarding the code of conduct when contributing to this repository please review https://www.dabapps.com/open-source/code-of-conduct/