ng-file-upload
AngularJS directive and service for HTML5 file uploads with drag-and-drop, resize, and legacy-browser shim support.
Repository Health
Technical Analysis
ng-file-upload is an AngularJS directive/service pair (ngfSelect, ngfDrop, Upload) that wires file selection, drag-and-drop, and HTTP upload straight into markup with attributes like ngf-pattern, ngf-max-size, and ngf-resize, so a developer never hand-writes FormData/XMLHttpRequest plumbing. Uploads go through Angular’s $q/$http stack, giving promise-based progress notifications, pause/resume for resumable uploads, and CORS/binary uploads via Upload.$http().
Beyond the core select/drop surface it bundles client-side image resize and center-crop, EXIF orientation correction for JPEGs, thumbnail/audio/video preview bindings, and pluggable sync/async validation for file type, size, and image dimensions. For browsers without native File/FormData/XHR2 support (IE8-9), it lazy-loads a vendored FileAPI shim so modern browsers never pay that cost.
What You Get
ngfSelectandngfDropdirectives for click-to-select and drag-and-drop file input, bindable directly tong-model- An
Uploadservice (Upload.upload(),Upload.http()) that returns a decorated Angular promise with progress notifications, pause/resume, and abort - Declarative validation attributes (
ngf-pattern,ngf-max-size,ngf-min-height,ngf-max-height, duration checks for audio/video) with pluggable custom validators - Client-side image resize and center-crop before upload, plus automatic EXIF orientation correction for JPEGs
- Thumbnail/audio/video preview bindings (
ngf-thumbnail,ngf-src) that render selected files without a manual FileReader round trip - An on-demand FileAPI shim for IE8-9 and other browsers lacking native FormData/XHR2 support, loaded only when needed
Common Use Cases
- Adding a validated single- or multi-file upload button to an AngularJS form with size/type/dimension constraints
- Building a drag-and-drop upload zone with live progress bars for a media or document management screen
- Resizing and cropping user-selected images client-side before sending them to a server or S3-compatible endpoint
- Uploading files via CORS or as raw binary data using
Upload.$http()against a separately hosted API - Rendering an instant thumbnail/audio/video preview of a selected file before the upload completes
Under The Hood
Architecture
The module registers directives (ngfSelect, ngfDrop) and services (Upload, UploadBase) on one ngFileUpload Angular module, all funneling through a shared sendHttp implementation in src/upload.js that wraps Angular’s $http/$q/$timeout to add upload-progress events and resumable-upload support; select.js and drop.js implement the two input surfaces (native file input vs. HTML5 drag-drop) and route into that shared service, while validate.js, resize.js, exif.js, and model.js layer optional validation, client-side resize, EXIF-orientation correction, and ngModel integration on top of the same file objects. A bundled third-party shim (src/FileAPI.js, several thousand lines, plus a Flash fallback) is loaded lazily only for browsers lacking native File/FormData/XHR2 support, keeping the modern-browser path free of that weight. It’s a flat, module-scoped design with no internal DI boundaries or plugin system, so changing the core sendHttp/progress-event plumbing would ripple through every directive since they all depend on it directly.
Tech Stack
A vanilla AngularJS 1.x directive/service library with no build-time framework dependency beyond Angular itself, built via Grunt (concat/uglify/jshint/copy tasks in Gruntfile.js) into concatenated dist/ bundles, linted with JSHint rather than ESLint, and published in parallel to npm, Bower, NuGet, and Meteor. No TypeScript and no ES modules; the legacy-browser shim (src/FileAPI.js and FileAPI.flash.swf) is vendored directly into the repository rather than pulled in as a dependency.
Code Quality
The only test file present (test/spec/spec/test.js) is an unfilled placeholder spec with an empty it block, so there is no real automated test suite despite Grunt’s watch/serve tasks suggesting a dev loop was intended. JSHint linting (.jshintrc) enforces basic style consistency, but the code is plain ES5 with no type annotations and relies on the global angular object rather than imports. Error/async handling goes through Angular’s $q promise rejection rather than thrown exceptions, which is idiomatic for the framework version. No CI configuration (no GitHub Actions, Travis, or similar) was found in the repo, so quality gates depend entirely on the maintainer’s local tooling before each release.
API Design
The surface is attribute-driven (ngf-select, ngf-drop, ngf-pattern, ngf-max-size, ngf-resize, ngf-thumbnail) so validation, resizing, and preview can be wired from markup with no imperative boilerplate, and Upload.upload()/Upload.http() return a standard Angular promise decorated with progress notifications that meshes naturally with existing controller code. Getting started needs only three script tags and one module dependency (['ngFileUpload']) with no configuration step, and the same Upload service handles both direct-binary CORS uploads and multipart form submits. Naming is consistent throughout (ngf-* prefix), though the attribute surface is large and documented only in one long single-page README rather than structured API docs.