Large file uploads with Ember.js


#1

Hi everyone,

I have been working on a project where I am creating an admin for content creators to be able to create different types of media. I was able to get a successful way to be able to upload image, audio and video files and also have a preview with them. I was so pumped when I got that working and then I tried to upload a large movie and it hit me that I had not thought of where the data was actually being stored… my ember model in memory. So of course my browser crashed. This is my first time working with media let alone large media so I was wondering if you guys have any ideas or tips to help me out.

Thanks, Will


#2

I would suggest wrapping plupload in an ember view and, as much as possible, handling the file creation/uploads outside of Ember Data.

Create a proper asset model (server side) and an api endpoint that accepts file uploads. Use Plupload to send the files, and once the file has been uploaded/created you can handle the association on the client.

That’s how we’ve handled it and it’s been pretty nice so far.


#3

Thanks so much Emereson! I created a solution based on your comment. I have it send the file to AWS S3 and then associate the URL on the client when I get the response back.


#4

We are trying to implement plupload with ember now as well. Do you happen to have a code example of your approach that you would be willing to share?


#5

I haven’t seen that plug-in before- I think I like that better than using the FileReader API.

Server-side, the code I use for this kind of thing looks like this (using PHP and Slim):

<?php
	$RestServer->post("/upload", function () use ($RestServer) {
		$base_url = "/home1/username/public_html/site_name_here/";

		$file_name = "files/other/" . $RestServer->request->params("fileName");
		$file_data = $RestServer->request->getBody();

		$is_success = file_put_contents($base_url . $file_name, $file_data);

		if (!$is_success){
			$RestServer->response->setStatus(501);
			echo("Unable to save the file");
		} else {
			$RestServer->response->setStatus(201);
			$file_name = array("file_url" => $file_name);
			echo(json_encode($file_name));
		}
	});
?>

The idea is that you POST a file name and some data to the /upload endpoint, it creates the file, and on success returns the file path.

On the Ember component side, I have something like this:

file: function(key, value){
	if (arguments.length > 1){
		var self = this;
		var fileData = "";
		var fileName = "";
		var url = "";
		var Reader = new FileReader();

		Reader.onload = function(event){
			fileData = Reader.result;
			fileName = value.name;
			url = self.get("uploadEndpoint") + "?fileName=" + fileName;

			$.ajax({
				url: url,
				type: "POST",
				data: fileData,
				dataType: "JSON",
				processData: false,
				success: function(data) {
					self.set("errorMessage", "");
					self.set("fileUrl", data.file_url);
				},
				error: function() {
					self.set("errorMessage", "Problem uploading file");
				}
			});
		};
		Reader.readAsBinaryString(value);

		return value;
	}
}.property(),

#6

Gordon,

What type of backend are you posting to? I am using Node so if you need help with that let me know. As far as the ember side of things: I have setup separate components for audio, image and video uploads in DropzoneJS. I have pasted my ember code on this pastebin: http://pastebin.com/H93VnEt4. The image and width requirements are not built into DropzoneJS, I need to clean up the code a little and then ill push it to their git repo for review. Lmk if I can be more help.


#7

Thanks for the responses. We actually have file uploads working perfectly for Chrome/FF/IE10+, however we just found out that some of our major clients are using IE9 which does not support fileAPI. I want to try to use plupload so we can support drag and drop upload on IE9. Did you end up using plupload at all after your post?

The server side is not an issue however thanks for your code samples.


#8

Sorry dude, I did not use plupload and luckily for me I am now in a situation where supporting all browsers does not mean supporting all UI features in all browsers. I felt your pain for a long time and wish you good luck with your problem.


#9

We had been using JQuery File Upload in our Rails/JQuery app and recently switched to dropzone.js, which is amazing. Would love to see an ember implementation.