Created
October 31, 2017 15:07
-
-
Save Gowiem/99b415e9765c78179d2ff9226c0800d6 to your computer and use it in GitHub Desktop.
A complicated model tree loading function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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