Skip to content

Instantly share code, notes, and snippets.

@Gowiem
Created October 31, 2017 15:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gowiem/99b415e9765c78179d2ff9226c0800d6 to your computer and use it in GitHub Desktop.
Save Gowiem/99b415e9765c78179d2ff9226c0800d6 to your computer and use it in GitHub Desktop.
A complicated model tree loading function
import Ember from 'ember';
import DS from 'ember-data';
const { RSVP } = Ember;
const { PromiseObject } = DS;
async function loadSections(form) {
return form.get('formSections');
}
/**
* Maps over the given resolved FormSection models for their questions.
* @param {Array<FormSection>} sections
* @return {Promise<Array<Question>>} Returns a Promise which resolve to a flattened array of all questions for the given sections.
*/
async function loadQuestions(sections) {
const questionPromises = sections.map((section) => {
return section.get('questions');
});
return RSVP.all(questionPromises).then((questionManyArrays) => {
return questionManyArrays.flatten();
});
}
/**
* Maps over the given resolved Questions for their sub questions.
* @param {Array<Question>} questions
* @return {Promise} A promise that resolves when all subquestions for the given questions are properly loaded.
*/
async function loadSubQuestions(questions) {
const subQuestionPromises = questions.map((question) => {
question.get('subQuestions');
});
return RSVP.all(subQuestionPromises);
}
/**
* Ensures the given model is a PromiseObject so we can call `then` on it.
* @param {DS.Model} model Expected to be a subclass of DS.Model.. but maybe it can be any object?
* @return {PromiseObject} Returns the model if it's a PromiseObject or creates and returns a PromiseObject from it if not.
*/
function ensurePromiseObject(model) {
if (model instanceof PromiseObject) {
return model;
} else {
return PromiseObject.create({
promise: async function() { return model; }
});
}
}
/**
* Load the full model tree for the given form.
*
* @param {Form} formToLoad The form object to load. This may be the loaded form model or a PromiseOjbect, code handles both.
* @return {Promise<Form>} Returns a Promise which resolves the given form once all child models are loaded (sections, questions, subQuestions).
*/
export default async function loadFormTree(formToLoad) {
let formPromise = ensurePromiseObject(formToLoad);
const form = await formPromise;
return loadSections(form)
.then(loadQuestions)
.then(loadSubQuestions).then(() => {
return form;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment