Is there a recommended method for managing file uploads in Meteor?
Is there a recommended method for managing file uploads in Meteor?
My go-to solution is using . They handle the file upload, storage in S3, and provide a convenient URL for access. I simply take that URL and store it in my database.
First step is to download the filepicker script to your client folder.
wget https://api.filepicker.io/v0/filepicker.js
Next, insert a filepicker input tag:
<input type="filepicker" id="attachment">
Then, initialize it during startup:
Meteor.startup( function() {
filepicker.setKey("YOUR FILEPICKER API KEY");
filepicker.constructWidget(document.getElementById('attachment'));
});
Add an event handler:
Templates.template.events({
'change #attachment': function(evt){
console.log(evt.files);
}
});
When it comes to handling images, I have a technique that is similar to the one used by Dario, but with a slight twist - I skip saving the file on disk altogether. Instead, I store the image data directly in the database as a field within the respective model. This approach suits my needs perfectly as I primarily target browsers that are compatible with the HTML5 File API, and my requirements for image support are quite basic.
Template.myForm.events({
'submit form': function(e, template) {
e.preventDefault();
var file = template.find('input type=["file"]').files[0];
var reader = new FileReader();
reader.onload = function(e) {
// Incorporate the image data into your model
model.update(id, { $set: { src: e.target.result }});
// Display the updated image on the page
$(template.find('img')).attr('src', e.target.result);
}
reader.readAsDataURL(file);
}
});
Check out my latest approach to handling file uploads by leveraging Meteor.methods and the HTML5 File API. I'm interested in hearing your thoughts on it.
A new solution has emerged: edgee:slingshot. This package changes the game by avoiding file uploads directly to your meteor server, allowing it to focus on its core function of serving the meteor app without the burden of handling resource-intensive transfers.
Instead, files are sent to cloud storage services, with current support for AWS S3 and Google Cloud Files, and future plans to include Rackspace Cloud Files and even Cloudinary.
Your meteor server simply acts as a middleman in this process.
This package is not only versatile but also lightweight, making it a standout choice for efficient file management.
Discover a unique atmosphere plugin known as router that specializes in this feature.
For the ultimate file upload solution, check out collectionFS
Looking for a top-notch solution? Look no further! This method utilizes collectionFS.
meteor add cfs:standard-packages
meteor add cfs:filesystem
Client Side Implementation:
Template.yourTemplate.events({
'change .your-upload-class': function(event, template) {
FS.Utility.eachFile(event, function(file) {
var yourFile = new FS.File(file);
yourFile.creatorId = Meteor.userId(); // adding custom data
YourFileCollection.insert(yourFile, function (err, fileObj) {
if (!err) {
// handle callback events here
}
});
});
}
});
Server Configuration:
YourFileCollection = new FS.Collection("yourFileCollection", {
stores: [new FS.Store.FileSystem("yourFileCollection", {path: "~/meteor_uploads"})]
});
YourFileCollection.allow({
insert: function (userId, doc) {
return !!userId;
},
update: function (userId, doc) {
return doc.creatorId == userId
},
download: function (userId, doc) {
return doc.creatorId == userId
}
});
Template Setup:
<template name="yourTemplate">
<input class="your-upload-class" type="file">
</template>
If you don't need to deal with huge files or only plan on storing them temporarily, this straightforward approach is quite effective.
In your HTML file...
<input id="files" type="file" />
In your template event mapping...
Template.template.events({
'submit': function(event, template){
event.preventDefault();
if (window.File && window.FileReader && window.FileList && window.Blob) {
_.each(template.find('#files').files, function(file) {
if(file.size > 1){
var reader = new FileReader();
reader.onload = function(e) {
Collection.insert({
name: file.name,
type: file.type,
dataUrl: reader.result
});
}
reader.readAsDataURL(file);
}
});
}
}
});
Subscribe to the Collection and display a link in a template...
<a href="{{dataUrl}}" target="_blank">{{name}}</a>
While this may not be the most robust solution for handling large files or extensive file operations, it serves well for various file formats when you simply need a basic upload/download feature.
One option is to upload content directly to Amazon S3 by using JavaScript uploaders and other techniques. Check out this article on how to do it!
Looking at the meteor roadmap, it appears that the feature "File upload pattern" is set for release "After 1.0". So, we will have to be patient and wait for an official solution to become available.
In the meantime, a good option is to utilize "collectionFS" (currently in version 0.3.x dev preview).
Another suggestion is to use inkfilepicker (formerly filepicker.io). While this requires an Internet connection on the user's end, it is a simple and effective solution.
If you just want to experiment, you can also explore utilizing HTML5 features for file uploads, like in this example.
Here's a different approach you may find helpful:
This method utilizes Blueimp's upload solution, which offers chunked uploads, progress bars, and more features.
If you want to achieve the same result as the top-rated answer but without using filepicker.io, you can follow the steps outlined in this package: https://github.com/Lepozepo/S3
After that, you can retrieve the link by using code similar to the one below. Then simply add the returned URL from secureLink into the database.
Template.YourTemplate.events({
"click button.upload": function() {
var files = $("input.file_bag")[0].files;
S3.upload(files, "/subfolder", function(e,r) {
console.log(r);
Session.set('secureLink', r.secure_url);
})
}
});
Template.YourTemplate.helpers({
"files": function() {
return S3.collection.find();
},
"secureLink": function() {
return Session.get('secureLink');
}
});
I am facing a challenge in building an array of custom objects by resolving promises from an array created based on another array. Consider having an array of letters = ['a', 'b', 'c']. I then map this array to make Ajax call ...
When working with a save function that requires you to call another function to retrieve the revision number and make an API call, both of which are asynchronous in nature, how can you ensure one function waits for the other to execute? $scope.getRevision ...
Looking to include a contact page on my website, but struggling with limitations imposed due to hosting on a secure school server that restricts script execution. Wondering if there's a workaround that would allow for email sending on the client side ...
I am dealing with a web app issue where an AJAX call is functioning as expected on local and test servers, but not on the client's end. The client reported that after some changes were made to the architecture of the app and it was reuploaded to thei ...
I am currently facing a challenge with an angular app that sends JSON data to a Django backend. The Django application saves the JSON data into a database and later retrieves it to send it back to the angular app. However, I am struggling to get this entir ...
I am facing an issue with rendering a form inside a modal. The form is being rendered but the form_for does not show up, only the inputs are visible. This prevents me from targeting the submit button, which I need for ajax functionality. My file path: Adg ...
To begin, I want to clarify that I am intentionally avoiding the use of jQuery. While it may simplify things, it goes against the purpose of my project. Please note that 'ajaxFunction' serves as a generic example for AJAX requests using GET/POST ...
I've been diving into the world of React Relay and GraphQL with react-relay-router, but I'm having trouble getting the params in my routes to function correctly. Specifically, I'm struggling with the "/Maps/:userID" route. Let me share my r ...
I have a map where initially the markers load coming from the database, Then there is a time-based Ajax request that fetches new records every minute. In my code snippet, I am using setMapOnAll(null) following the guidance from the Google Maps Documentati ...
function filteredArray(arr, elem) { let newArr = []; Iterating through each element of the multidimensional array. for (let i=0;i<arr.length;i++){ for (let j=0;j<arr[i].length;j++){ If the value matches the argument passed, assi ...
I have a project in the works that involves tracking chefs and their new recipes. I am developing a simple frontend application where users can input a chef's username, which will then be sent to the backend for scraping several cooking websites to re ...
I am currently exploring the use of mailchimp-api-v3 in a Meteor project (1.4.1.3) and I particularly like the batch support it offers. To make the call, I have enclosed it within Meteor's .wrapAsync function (which had a bit of a learning curve, but ...
Similar Question: How can I access a specific value in a nested data structure or JSON? I am trying to display data from a JSON array using the following code, but it is not working: var Content = [{ "01":[{"text":"blablablablabla","foo":"abeille ...
Currently working on enhancing the appearance of the scrollbar within my ReactJS project. Specifically, I am aiming for a design similar to this example: https://i.stack.imgur.com/2Q0P4.png Experimented with CSS properties like -webkit-scrollbar, -webki ...
For a school project, I am working on developing a mobile-first website prototype that includes Google Maps integration. I have successfully added a ground overlay using this image, but I am facing issues with enabling the "my location layer". When I tried ...
I am encountering an issue with a textarea count code. It functions perfectly on its own but when I integrate it as shown below, it stops working without throwing any errors. I have been trying to resolve this for more than 3 days now. Any assistance would ...
Currently, I am working on a project where I am using 3 nested ng-repeat to read a JSON file and display various questions along with their answers. Everything seems to be working fine up to this point, but I am facing an issue with storing the selected an ...
How can I eliminate text and spaces? For instance: http://www.exampleweb.com/myprogram.rar http://www.examplebackup.com/mybackups.rar http://www.exampleweb.com/myprogram1.rar I have used something similar to remove the second line: http://www.exampleba ...
Within my "ROI calculator," there is a feature that allows users to adjust different labels. One of these labels is called "onlineRevenue." The concept is to recommend the most suitable plan based on the user's online revenue. However, I have some re ...
Let's say we have a react application called A, which renders a component called B. The two of them are using an npm dependency with version 1.0. Now, the need arises to upgrade the version of this dependency in B to 1.1. Since the updated version has ...