ember.js
ember.js copied to clipboard
[Bug] hasMany related records referenced with {{each}} helper are not await able
🐞 Describe the Bug
{{each}} helper while iterating a hasMany array returns an array of Model objects rather then an expected array of Proxy Model Objects. This causes issues with components within the block not re-rendering or operating off of the hydration of the loaded record.
🔬 Minimal Reproduction
Setting up a simple model representation that would mimic my experience. The code below may have simple syntax errors so apologies, as it was hand typed not copy and pasted.
# primary model loaded in route
export default class Project extends Model {
@hasMany('book', {async: true}) books
}
# secondary model
export default class Book extends Model {
@belongsTo('author', {async: true}) author
get authorId() { return this.belongsTo('author').id(); }
}
# example component
export default class TheBook extends Component {
constructor() {
this.super(...arguments);
this.doAsync();
}
async doAsync() {
console.info(this.args.book.authorId, this.args.book.isLoaded) // null, false
let book = await this.args.book
console.info(book.authorId, book.isLoaded) // null, false
}
}
# example template referencing 'each' and 'hasMany'
{{#each this.model.books as |book|}}
<TheBook @book={{book}} />
{{/each}}
😕 Actual Behavior
In the doAsync method the passed in reference is not await/then able. A workaround for this is to wrap the block in a check, but this prevents any type of rendering until all the hydration is complete which is not optimal.
{{#each this.model.books as |book|}}{{#if book.isLoaded}}
<TheBook @book={{book}} />
{{/if}}{{/each}}
🤔 Expected Behavior
Because related records are always treated as promises, I would expect a proxy model to be yielded to the block that way if the related record was not hydrated you could await for the record to load.
# example component function expected behavior
async doAsync() {
console.info(this.args.book.authorId, this.args.book.isLoaded) // null, false
let book = await this.args.book
console.info(book.authorId, book.isLoaded) // <an id>, true
}
🌍 Environment
- Ember: - 3.28.5
- Node.js/npm: -14.19,2
- OS: - unix
- Browser: - chrome
➕ Additional Context
Add any other context about the problem here.