0

So far my groupedItems is rendered properly in the template. But when I click on the add to cart link, which triggers the addToCart action. The template does not render the new item... I have to manually refresh the page to see it.

I check Ember Inspector, Data tab. The newly added item was appended to the list. So, if reflects in the data store, shouldn't it reflect/render in the template as well?

The newly added item was also persisted in the database.

If I change my model hook in the routes to items: this.store.find('item'), instead of items: this.store.find('item', { status: 'queued' }). Everything works...

I suspect it is the way my computed property, groupedItems, is being managed. Any pointers?

// Routes
import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    return Ember.RSVP.hash({
      // items: this.store.find('item'),
      // items: this.store.find('item').filterBy('status', 'queued'),
      items: this.store.find('item', { status: 'queued' }),
      // products: this.store.find('product', { status: 'available' })
    });
  },

  // You can use model.items to get items, etc
  // Since the model is a plain object you can just use setProperties
  // http://stackoverflow.com/questions/16463958/how-to-use-multiple-models-with-a-single-route-in-emberjs-ember-data
  setupController: function(controller, model) {
    // model.reload;
    controller.setProperties(model);
  },

  actions: {
    addToCart: function(product) {
      var _this = this;

      var item = _this.store.createRecord('item');
      item.set('product', product);

      item.save().then(function() {
        // _this.transitionTo(fromRoute);
      });
    }
  }
});

// Controller
import Ember from 'ember';

export default Ember.Controller.extend({
  groupedItems: function () {
    var result = [];

    this.get('items').forEach(function(item) {
    // this.get('items').filterBy('status', 'queued').forEach(function(item) {
      var hasProductId = result.findBy('productId', item.get('product.id'));

      if(!hasProductId) {
         result.pushObject(Ember.Object.create({
            productId:        item.get('product.id'),
            product:          item.get('product'),
            item:             item,
            numberOfProducts: 0,
            subtotalInCents:  0
         }));
      }

      var productFromResult = result.findBy('productId', item.get('product.id'));

      productFromResult.set('numberOfProducts', productFromResult.get('numberOfProducts') + 1);

      item.get('product').then(function(product){
        productFromResult.set('subtotalInCents', productFromResult.get('subtotalInCents') + product.get('amountInCents'));
      });
    });

    return result;
  }.property('items.@each')
});

// Template / hbs
<ul>
  {{#each groupedItems}}
    <li>
      <a href="#" {{action "addToCart" product}}>Add</a>
      / <a href="#" {{action "removeFromCart" item 'index'}}>Remove</a>
      {{numberOfProducts}} {{product.name}} P{{cents-to-pesos product.amountInCents}} / each
    </li>
  {{/each}}
</ul>
Christian Fazzini
  • 19,613
  • 21
  • 110
  • 215

4 Answers4

1

To have new records synced automatically you should use store.filter instead of store.find. Check out the ember docs for more details: http://emberjs.com/api/data/classes/DS.Store.html#method_filter

andrei1089
  • 1,038
  • 6
  • 8
  • Having `items: this.store.filter('item', function(item) { return item.get('queued'); }).then(function(queuedItems) { return queuedItems; })` in the model hook doesn't even trigger an API request to the `items` endpoint – Christian Fazzini Feb 03 '15 at 09:39
  • Try with `items: this.store.filter('item', { status: 'queued' }, function(item) { return item.get('status') === 'queued'})`. – andrei1089 Feb 03 '15 at 09:43
  • `store.find` also allows you to throw a filter into it. It makes you think. Whats the whole point of `store.find` when it can't update the store when new items are added? – Christian Fazzini Feb 03 '15 at 13:13
0

Maybe it's your setupController method. The default behavior for setupController is to set the model attribute of the controller. Here, you instead only setProperties.

While this should set the values initially to the right controller values, it probably just sets those values to be Ember Arrays, and so they have no idea you created a new item.

After you create your item (or even after you save it), you should try adding it to the items array of your controller, by calling something like this.get('items').pushObject(item).

DanF
  • 589
  • 4
  • 23
0

Your problem is that your model is the result of an RSVP.hash.

That means your controller's model looks like this:

{ items: [your items..]}

So that means you can't say this.addItems(items), you'd have to say this.get('model').items.pushObjects(items).

Your route only can have one "model", and if it's a hash, then items is just a key on that hash.

DanF
  • 589
  • 4
  • 23
-1

You might be interrupting the promise's resolution. Try something like:

item.save().then(function(result) {
  return result;
  // _this.transitionTo(fromRoute);
});
DanF
  • 589
  • 4
  • 23