Meteor / Mongo - How do you link to the collection? (de-normalization versus normalization)

I am Meteor and mongo noob (now a huge fan of Meteor), and I am struggling with how to implement search collections in Meteor.

Scenario:

  • I have a product with custom colors (user defined / unknown amount)
  • The user can add their own colors, and then go to the product page and select from the color selection field what color they want to use for this product
  • If the user returns and changes the hexadecimal color value (and saves) on the color page, the product (on the product page) reflects this new colorHex value

What am I trying to do:

  • Allow user to return and change a previously existing color on the color page
  • Whether this color change of the hexadecimal value on the product page is ignored.
  • Trying not to duplicate data in different collections (and worry about updating data in multiple collections / data discrepancies if the update doesn’t go partially)

Initially, I set up my product schema to store color data (unnormalized data), although when updating color it is not updated in the typography document. I saw that you can use the watch function to essentially listen for changes and then make additional changes, although this seems more complicated than necessary. Is there a way I can link to a collection of colors for all colors added to a particular product so that any changes are reflected on the product page?

Below is the code I'm working on. I use collection2 and iron: Router if this helps. I tried to combine both collections, although this is not what I need, since each cycle also goes through colors (not desirable).

Any help is appreciated. Thank you in advance! -Chris

ProductPage Helper:

Template.productPageTpl.helpers({ ownProduct: function() { return this.userId === Meteor.userId(); }, productItems: function() { return ProductCollection.find({productId: this._id}); }, colorsItems: function() { return ColorsCollection.find({productId: this._id}); }, // This is my attempt and although give me back both collections, // I only need to reference the colors. productAndColorsItems: function() { var product = ProductCollection.find({productId: this._id}).fetch(); var colors = ColorsCollection.find({productId: this._id}).fetch(); var productColorsJoin = product.concat(colors); console.log(productColorsJoin); return _.sortBy(productColorsJoin, function(doc) {return doc.createdAt;}); } }); 

Html product page:

 <template name="productPageTpl"> <div class="product"> {{#each productAndColorsItems}} {{> productItemTpl}} {{/each}} </div> </template> // All the {{properties}} below reference the ProductCollection except for the {{colorHex}} // {{colorHex}} is a property on the ColorsCollection <template name="productItemTpl"> <div id="product-sentence-js" style="color: #{{colorHex}}; font-family: {{fontFamily}}; font-weight: {{fontWeight}}; font-size: {{fontSize}}{{fontUnit}}; font-style: {{fontStyle}}; text-transform: {{fontTextTransform}}; line-height: {{fontLineHeight}}{{fontLineHeightUnit}}; padding: {{fontPaddingTop}}{{fontPaddingTopUnit}} {{fontPaddingRight}} {{fontPaddingTopUnit}} {{fontPaddingBottom}}{{fontPaddingTopUnit}} {{fontPaddingLeft}}{{fontPaddingTopUnit}}; margin: {{fontMarginTop}}{{fontMarginTopUnit}} {{fontMarginRight}}{{fontMarginTopUnit}} {{fontMarginBottom}}{{fontMarginTopUnit}} {{fontMarginLeft}}{{fontMarginTopUnit}};"> {{productSentence}} </div> </template> 

Flower picking scheme

 ColorsCollection = new Mongo.Collection('colors'); var Schema = {}; Schema.ColorsCollectionSchema = new SimpleSchema({ productId: { type: String, label: "Product Id", max: 500 }, userId: { type: String, label: "User Id", max: 500 }, author: { type: String, label: "Author", max: 500 }, submitted: { type: Date, label: "Submitted", max: 500 }, colorName: { type: String, label: "Color Name", max: 500 }, colorHexValue: { type: String, label: "Color Hex Value", max: 500 }, colorHexValueId: { type: String, label: "Color Hex Value Id", max: 500 } }); ColorsCollection.attachSchema(Schema.ColorsCollectionSchema); 

So, in short, when the user changes color on the color page, the color document is updated with a new hexadecimal value (inside the ColorsCollection), and all products that use this color now reflect this new color as a hexadecimal value.

+6
source share
1 answer

Here is the solution I came across. I welcome any alternative methods / best Meteor methods.

Firstly:

I used the reactive publisher (package) as described in this article ( https://gentlenode.com/journal/meteor-6-reactive-and-nonreactive-join-with-mongodb/12 ). This helped a lot since it allows the server to discard changes to the page t that has already been displayed.

The second:

I have implemented the code below. In fact, I find the specific color that the user selected for editing, referring to the identifier that was given to this Meteor entry (which will not change). The value of the select box is set to the color id, and I use the data value to store the actual hex value. It is by no means ideal, although when a user edits a color value, the product element is updated instantly, as well as the values ​​of the selection field.

 Template.productItemTpl.helpers({ productItemColorHexValue: function() { var allColors = ColorsCollection.findOne({colorHexValueId: this.productColorHexValueId}); return allColors.colorHexValue; } }); <template name="productColorsSelectOptionsTpl"> {{#each productColorsSelectOptions}} <option data-colorhexvalue="{{colorHexValue}}" value="{{colorHexValueId}}">{{colorName}} </option> {{/each}} </template> 
+1
source

Source: https://habr.com/ru/post/978337/


All Articles