Help updating the correct item

#1

Hi everybody, I’m still new to Meteor (and React for that matter) but so far it has been great. I’m trying to update the price of a single item in a collection but something is off because the item I’m trying to update always gets updated to the last item added to the collection.

Below is how I add an item to the collection…

addItem = e => {
e.preventDefault();
if (this.newItemName.value !== ‘’) {
PantryDB.insert({
name: this.newItemName.value.trim(),
price: this.newItemPrice.value.trim(),
stocked: false
});
}

this.newItemName.value = '';
this.newItemPrice.value = '';

};

…and the form that takes in the info…

    <form className="Pantry__form" onSubmit={this.addItem}>
      <div className="Pantry__form-content">
        <label htmlFor="newItemName">Name: </label>
        <input type="text" ref={input => (this.newItemName = input)} />
        <label htmlFor="newItemPrice" id="marginLabel">
          Price:{' '}
        </label>
        <input type="text" ref={input => (this.newItemPrice = input)} />
      </div>

      <button type="submit">Add Item</button>
    </form>

This all works great and I then map over the DB and return each item in it, each item then has an input element that displays it’s price and calls the update method onChange…

<input
className=“Item__price”
type=“text”
defaultValue={item.price}
id={item._id}
ref={input => (this.price = input)}
onChange={this.updatePrice}
/>

…and the update method that gets called…

updatePrice = e => {
e.preventDefault();
const _id = e.target.id;
const itemToUpdate = PantryDB.find({ _id: e.target.id }).fetch();

PantryDB.update(itemToUpdate[0]._id, { $set: { price: this.price.value.trim() } });

};

Any thoughts? I’m sure I’m not binding the item correctly perhaps but I can’t seem to figure it out! Any help would be greatly appreciated!

Thanks

#2

I’d start by checking that e.target.id has a value. Also you can simplify your code a bit by just using e.target.id directly. Fetching the _id from minimongo using the _id and passing it to the update method is a little redundant.

If you have a repo that can be cloned, I’d be happy to look into the issue.

Style Tip :nail_care:

Wrapping code blocks in triple backticks makes them easier for others to read by displaying them with fixed width fonts, stopping them from wrapping, and adding syntax highlighting.

```
// code here
```

2 Likes
#3

Hi, thank you so much, really appreciate it! I removed the _id variable, thanks. Here is the link to the repo on github…


Or I am ‘johndavidpena’ and the repo is ‘feedin-time’

The problem code is in the imports folder, ui, components, in the pantry component. When I try to update any item it assumes the price property of the last item added.

Thanks for the styling tip as well!

Sincerely,
John

#4

Hey, sorry it took me a while to get back to you…

So I’ve taken a look at your code and the issue you are having pretty simple.

Your issue starts on line 66:

{this.props.pantryDB.map(item => {

Your current context is the Pantry component. With this code you are mapping over each found document and creating jsx for each of them.

                <input
                  className="Item__price"
                  type="text"
                  defaultValue={item.price}
                  id={item._id}
                  ref={input => (this.price = input)}
                  onChange={this.updatePrice}
                />

Now for each item in the map you create this JSX which executes a ref function and sets the Pantry component instance’s price property to a reference to this input tag. When mapping has finally completed, price property is set to a reference to the very final input tag that was created. Therefore when you reference this.price.value in your updatePrice function you always get the value of the very last of these input tags.

Luckily this is a super simple fix… First remove the ref function. then rework your updatePrice method like so…

  updatePrice = e => {
    e.preventDefault();
    PantryDB.update(e.target.id, { $set: { price: e.target.value.trim() } });
  };
#5

Kelly, thanks so much, really appreciate it! Still pretty new to all of this and obviously prone to a lot of mistakes. So glad that there are generous, knowledgeable people out there like yourself.

All the best,

John

3 Likes