I’m trying to understand the following use case.
When we use one of DS.Store fetch methods like findAll, findRecord, etc., all of them return a Promise object.
But if later you try to get the previously fetched Promise object and set a new value on one of its attributes, for example:
The question is what is the right way to get around of this, knowing that the above Shop instance has been already fetched and is available in the store.
Use store.peekRecord() method like this:
let shop = store.peekRecord('shop', this.get('currentShop.shop.id'));
shop.set('modifiedBy', this.get('currentUser.user').get('username'));
await shop.save();
I’ve been somewhat stymied by proxy objects as well, and I can’t claim I’ve got it all figured out.
However, I believe there are 2 options for you:
Use shop.get('save')(). I haven’t tried this myself for save() but in theory, any call to get() on a proxy object will get the underlying object’s property by name. In this case, the save method.
Better ember engineers will probably warn you away from this, but I’ve found you can get the underlying object with shop.content. The tricky bit is that if currentShop.shop is an async relationship, it might not be loaded yet when your code runs, in which case you’d want to do await currentShop.shop first.
You could set the relationship up as {async: false} and be sure to always return the shop data in your api response, which would make this object be the real shop object and not a proxy to it.
Why not await as @francesconovy suggested? The correct thing to do here is to resolve the asynchronous boundary, either via a promise.then or use of await. (Same goes for @belgoros)