Ember - No Data in hasMany Relationship On Initial Load
Ember - No Data in hasMany Relationship On Initial Load
ember-cli - 3.20, ember-data - 3.30
I am trying to modify the data in a hasMany relationship in the controller setup but the relationship has no data. However, all the data is there after the page is fully loaded (i.e. in my template/actions, all relationship data is there)
I have a Quiz application with Many-Many relationship with Questions.
models/Quiz.js
import { computed } from '@ember/object';
import DS from 'ember-data';
const { attr, hasMany, Model } = DS;
export default Model.extend({
description: attr('string'),
questions: hasMany('question', {async: true}) //also tried with async false
});
models/Question.js
export default Model.extend({
question: attr('string'),
quizzes: hasMany('quiz', {async: true}) //also tried with async false
});
Go to url '/quiz/1' and Route calls findRecord on quiz
routes/quizzes/quiz.js
import Route from '@ember/routing/route';
export default Route.extend({
model(params) { return this.store.findRecord('quiz', params.quiz_id); }
});
controllers/quizzes/quiz.js
import { computed } from '@ember/object';
import Controller from '@ember/controller';
export default Controller.extend({
quiz: computed.alias('model'),
//also attempted in setupController/afterModel in router
modelChanged: function() {
let quiz = this.get('quiz');
let questions = quiz.get('questions'); //questions has no data
questions.then(questions => {
Promise.all(questions.map(question => {
//modify questions/answers here
}));
});
}.observes('model')
actions: {
getQuestions() {
let questions = this.get('quiz.questions'); //questions now has data
}
})};
I have tried to get the question data in both setupController() and afterModel() with no luck.
Note:
The quizzes are nested routes able to select between each quiz to display. So if you navigate from '/quiz/1' to '/quiz/2' and then back to 'quiz/1', the question data is available in the observer, setupController, afterModel, etc. So, the second time you access a specific quiz, the data is available in setup. (data is always available in template/actions).
Any ideas?
2 Answers
2
Temporary Workaround:
Use an observer on 'quiz.questions' along with a flag to check if first time hitting observer.
import { computed } from '@ember/object';
import Controller from '@ember/controller';
export default Controller.extend({
quiz: computed.alias('model'),
areAnswersSet: false,
observeQuestions: function() {
let questions = this.get('quiz.questions');
if (!this.areAnswersSet && questions.length !== 0) {
this.toggleProperty('areAnswersSet');
questions.forEach(question => { //modify question });
}
}.observes('quiz.questions.')
Drawback: Observer will still get called on every questions change. Only needed on initial load.
quiz.questions.isFulfilled
quiz.{questions,questions.isFulfilled}
quiz.questions.
There were a few bugs in Ember Data 3.3.0 that were related to relationships. It’s worth upgrading to Ember Data 3.3.1 to see if your issue goes away ...
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
As the questions relationship is async, you maybe could also observe
quiz.questions.isFulfilled
, to only run once per load (may need to observe asquiz.{questions,questions.isFulfilled}
to recognize change to a different model.questions). Or dynamically add the observer forquiz.questions.
on model change and remove it once fired. See addObserver/removeObserver.– Enno
Jul 17 at 11:46