How to upload a photo in Meteor to S3 and have it sync to database item?

175 Views Asked by At

I am creating a cookbook web application and would like a picture to be uploaded with each new recipe.

I am using this package: Amazon S3 File Uploader(https://github.com/Lepozepo/S3).

I can successfully do two things upon clicking submit for a new appetizer:

  1. Add a new appetizer name and description to the database
  2. Add the uploaded photo to the s3 database

I am new to MongoDB/Meteor and I am unsure on how to connect these two so that the image is linked to the recipe name and description upon submission of the form.

Do I need to create a document in my appetizer collection that states a field where the s3 image is supposed to be placed? If this is the right direction, how do I go about this?

The deployed version so far can be seen at: reed-cookbook.meteor.com.

My form html:

<template name="appetizerForm">
    <!-- This is the appetizer modal -->
    <div class="modal fade" id="myAppModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h4 class="modal-title" id="myModalLabel">Add An Appetizer</h4>
          </div>
          <div class="modal-body">
              <!-- This is the appetizer form -->
              <form>
                  <div class="form-group">
                      <label for="inputNewLabel">Name</label>
                      <input type="text" class="form-control" id="addNewAppetizer" name="appName" placeholder="What is the name of this appetizer?">
                  </div>
                  <div class="form-group">
                      <label for="inputNewLabel">Description</label>
                      <input type="text" class="form-control" id="addNewAppDesc" name="appDesc" placeholder="Share details about your appetizer.">
                  </div>
                  <div class="form-group">
                      <label for="inputNewLabel">Add Photo</label>
                      {{>s3}}
                      <p class="help-block">Upload a photo of your appetizer.</p>
                  </div>
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            <button type="submit" class="btn btn-primary" value="submitApp">Submit Appetizer</button>
            </form>
        </div>
        </div>
      </div>
    </div>
</template>

My form js:

Template.appetizerForm.events({
    'submit form': function(event, template) {
        event.preventDefault();
        console.log("Form submitted");
        console.log(event.type);
        template.$("#myAppModal").modal("hide");

        var addNewAppetizerVar = event.target.appName.value;
        console.log(addNewAppetizerVar);
        var addNewAppDescVar = event.target.appDesc.value;
        console.log(addNewAppDescVar);

        Appetizers.insert({
            name: addNewAppetizerVar,
            description: addNewAppDescVar
        });

    var files = $("input.file_bag")[0].files

    S3.upload({
            files:files,
            path:"subfolder"
        },function(e,r){
            console.log(r);
    });

    }
});
1

There are 1 best solutions below

0
On BEST ANSWER

You definitely need to add the S3 url to your collection schema, this can be done upon receiving the url in the file upload callback using Mongo.Collection.update.

[...]
var appetizerId = Appetizers.insert({
  name: addNewAppetizerVar,
  description: addNewAppDescVar
});
var files = $("input.file_bag")[0].files;
S3.upload({
  files: files,
  path: "subfolder"
}, function(error, s3Url){
  Appetizers.update(appetizerId, {
    $set: {
      imageUrl: s3Url
    }
  });
});
[...]

Then you'll be able to actually display the recipe image inside your template using an <img> tag.

<template name="appetizer">
  <h3>{{name}}</h3>
  <p>{{description}}</p>
  <img src="{{imageUrl}}" alt="{{name}}">
</template>