Search code examples
javascriptnode.jsmongodbmeteormeteor-blaze

Mongo/Meteor: Insert data from from other MongoDB Collection


I would like to embed a document from one collection into another, here a UoM into Products.

Template.NewProduct.helpers({
  ...
  uoms: function() {
    return UoM.find();
  },
  ...
});

Template.NewProduct.events({
  //Submit and Add to Database
  'submit form': function(event, template) {
    event.preventDefault();
    selectedUoM = UoM.findOne({
      _id: event.target.uomid.value
    });
    var doc = {
      name: event.target.name.value,
      category: event.target.category.value,
      suppliers: selectedSup,
      uomid: event.target.uomid.value,
    };
    Products.insert(doc, function(error, result) {
      ...
    });
  },
});

========= Collections ===========
import SimpleSchema  from 'simpl-schema';

Products = new Mongo.Collection("products");
Products.attachSchema(new SimpleSchema({
  name: {
    type: String,
    label: "Product Name",
    max: 200
  },
  suppliers: {
    type: Array,
    label: "Suppliers",
  },
  'suppliers.$' : {type: String},

  category: {
    type: String,
    label: "Category"
  },
  // Unit: unit , 50kg bag, 25kg bag, 22.5kg barrel etc...
  uomid: { //This one is working with UoM._id
    type: String,
    label: "Unit of Measurement",
  },
  uom_data: { //Need to populate this one with _id, name, unit, unitname from UoM collection
    type: Array,
    optional: true
  },
<template name="NewProduct">
  ...
    <label for="uomid">Unit of Measurement</label>
    <select class="sel2js" name="uomid">
      {{#each uoms}}
        {{> uomprod}}
      {{/each}}
    </select>
    <button type="submit" class="btn" id="submitNewProduct" value="Submit">Submit</button>
    
  
<template name="uomprod">
  <option value="{{_id}}">{{name}} - {{unit}} {{unitname}}</option>
</template>


<script type="text/javascript">
  $(document).ready(function() {
        $(".sel2js").select2();
      };
</script>


Solution

  • It's quite simple since you've already found the UoM document, your selectedUoM variable will contain a simple js object which can be directly assigned to a key in your other collection.

    selectedUoM = UoM.findOne(event.target.uomid.value);
    var doc = {
      name: event.target.name.value,
      category: event.target.category.value,
      suppliers: selectedSup,
      uomid: event.target.uomid.value,
      uomdata: selectedUoM
    };
    Products.insert(doc,...
    

    Note that since uomid === selectedUoM._id you have a small redundancy in your model. You can easily eliminate the uomid key altogether.

    You also need to alter your Products schema to support an object for uomdata instead of an array! - you're only inserting a single document, not an array. To avoid having to specify the substructure you also have to use blackbox: true.

      uom_data: { //Need to populate this one with _id, name, unit, unitname from UoM collection
        type: Object,
        optional: true,
        blackbox: true
      },