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

149 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 answers

0
saimeunt 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>