UNPKG

redux-devshare

Version:

[![NPM version][npm-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Code Climate][climate-image]][climate-url] [![Code Coverage][coverage-i

179 lines (166 loc) 5.27 kB
import { filter, isString, isArray, isObject, map, get, forEach, set, has } from 'lodash' /** * @private * @description Create standardized populate object from strings or objects * @param {String|Object} str - String or Object to standardize into populate object */ export const getPopulateObj = (str) => { if (!isString(str)) { return str } const strArray = str.split(':') // TODO: Handle childParam return { child: strArray[0], root: strArray[1] } } /** * @private * @description Create standardized populate object from strings or objects * @param {String|Object} str - String or Object to standardize into populate object */ export const getPopulateObjs = (arr) => { if (!isArray(arr)) { return arr } return arr.map((o) => isObject(o) ? o : getPopulateObj(o)) } /** * @private * @description Get array of populates from list of query params * @param {Array} queryParams - Query parameters from which to get populates */ export const getPopulates = (params) => { const populates = filter(params, param => param.indexOf('populate') !== -1 || (isObject(param) && param.populates) ).map(p => p.split('=')[1]) // No populates if (!populates.length) { return null } return populates.map(getPopulateObj) } /** * @private * @description Create an array of promises for population of an object or list * @param {Object} firebase - Internal firebase object * @param {Object} populate - Object containing root to be populate * @param {Object} populate.root - Firebase root path from which to load populate item * @param {String} id - String id */ export const getPopulateChild = (firebase, populate, id) => firebase.database() .ref() .child(`${populate.root}/${id}`) .once('value') .then(snap => // Return id if population value does not exist snap.val() ) /** * @private * @description Populate list of data * @param {Object} firebase - Internal firebase object * @param {Object} originalObj - Object to have parameter populated * @param {Object} populate - Object containing populate information * @param {Object} results - Object containing results of population from other populates */ export const populateList = (firebase, list, p, results) => { // Handle root not being defined if (!results[p.root]) { set(results, p.root, {}) } return Promise.all( map(list, (id, childKey) => { // handle list of keys const populateKey = id === true ? childKey : id return getPopulateChild( firebase, p, populateKey ) .then(pc => { if (pc) { // write child to result object under root name if it is found return set(results, `${p.root}.${populateKey}`, pc) } return results }) }) ) } /** * @private * @description Create an array of promises for population of an object or list * @param {Object} firebase - Internal firebase object * @param {Object} originalObj - Object to have parameter populated * @param {Object} populateString - String containg population data */ export const promisesForPopulate = (firebase, originalData, populatesIn) => { // TODO: Handle selecting of parameter to populate with (i.e. displayName of users/user) let promisesArray = [] let results = {} const populates = getPopulateObjs(populatesIn) // Loop over all populates forEach(populates, (p) => { // Data is single parameter if (has(originalData, p.child)) { // Single Parameter is single ID if (isString(originalData[p.child])) { return promisesArray.push( getPopulateChild(firebase, p, originalData[p.child]) .then((v) => { // write child to result object under root name if it is found if (v) { set(results, `${p.root}.${originalData[p.child]}`, v) } }) ) } // Single Parameter is list return promisesArray.push( populateList(firebase, originalData[p.child], p, results) ) } // Data is list, each item has parameter to be populated forEach(originalData, (d, key) => { // Get value of parameter to be populated (key or list of keys) const idOrList = get(d, p.child) // Parameter/child of list item does not exist if (!idOrList) { return } // Parameter of each list item is single ID if (isString(idOrList)) { return promisesArray.push( getPopulateChild(firebase, p, idOrList) .then((v) => { // write child to result object under root name if it is found if (v) { set(results, `${p.root}.${idOrList}`, v) } return results }) ) } // Parameter of each list item is a list of ids if (isArray(idOrList) || isObject(idOrList)) { // Create single promise that includes a promise for each child return promisesArray.push( populateList(firebase, idOrList, p, results) ) } }) }) // Return original data after population promises run return Promise.all(promisesArray).then(() => results) } export default { promisesForPopulate }