cteeters
cteeters

Reputation: 49

Meteor.js moving items from one collection to another

So I'm trying to make a Grocery List app for a project for school. What I want is for users to be able to make a list of items, then as they find them move them to a "Found items" list, while putting in the sale price of the item. I have two Mongo collections "Items" for the items they are looking for, and "Found_items" for the ones they have found. I've having trouble moving the items from Items to Found_items. They do get removed from Items but don't seem to be getting put into Found_items, or at least they aren't showing up on the UI. I'm pretty sure they problem is somewhere in what happens when you click on the "Found" button. My code is below...

project.html

<head>
  <title>Grocery List</title>
</head>

<body>
<div class="container">
  <header>
    <h1>Grocery List</h1>

    <form class="new-item">
      <input type="text" name="text" placeholder="Type to add new items" />
    </form>
  </header>

  <ul>
    {{#each items}}
      {{> item}}
    {{/each}}
  </ul>
</div>
<div class="container">
  <header>
    <h1>Items Found</h1>
  </header>

  <ul>
    {{#each found_items}}
      {{> found}}
    {{/each}}
  </ul>
</div>
</body>

<template name="item">
  <li>
    <button class="found">Got it!</button>

    <input type="number" name="price" placeholder="Sale Price" />

    <span class="text">{{text}}</span>
  </li>
</template>

<template name="found">
  <li>
    <span class="text">{{text}}</span>
  </li>
</template>

project.js

Items = new Mongo.Collection("items");
Found_items = new Mongo.Collection("found_items");

if (Meteor.isClient) {
  // This code only runs on the client
  Template.body.helpers({
    items: function () {
      return Items.find({});
    },
    found_items: function () {
      return Found_items.find({});
    }
  });


  Template.body.events({
    "submit .new-item": function (event) {
      event.preventDefault();

      var text = event.target.text.value;

      Items.insert({
        text: text
      });

      event.target.text.value = "";
    }
  });

  Template.item.events({
    "click .found": function (event) {
      Items.remove(this._id);

      event.preventDefault();

      var price = event.target.price.value;
      var text = event.target.text.value;

      Found_items.insert({
        text: text,
        price: price
      });

    }
  });
}

Any explanation as to what I am doing wrong would be greatly appreciated.

Upvotes: 1

Views: 299

Answers (2)

JeremyK
JeremyK

Reputation: 3240

The only problem is your "click .found" handler, as event.target is the button, which does not have price or text properties.

Change it to:

Template.item.events({
  "click .found": function (event) {

      event.preventDefault();
      var price = Template.instance().find('[name="price"]').value;
      var text = Template.instance().find('.text').textContent;

      Items.remove(this._id);
      Found_items.insert({
        text: text,
        price: price
      });

Also event handlers are passed two arguments, the event object, and the template instance that the handler is defined on. So you can change it to:

Template.item.events({
  "click .found": function (event, template) {
      event.preventDefault();
      var price = template.find('[name="price"]').value;
      var text = template.find('.text').textContent;

      ...

      });

Because this contains the data context used to create this (item) template, you can further simplify to this:

"click .found": function (event, template) {
  this.price = template.find('[name="price"]').value;
  Items.remove(this._id);
  Found_items.insert(this);
}

event.preventDefault() has also been removed, as there is no default action to prevent on this target (It's needed on your other event, being a form submit event).

Upvotes: 2

Michel Floyd
Michel Floyd

Reputation: 20226

Just do Found_items.insert(this)

Make sure you are publishing and subscribing to this collection properly.

Upvotes: 0

Related Questions