@@ -176,6 +176,29 @@ export const dataToJS = (data, path, notSetValue) => {
176176
177177 return data
178178}
179+
180+ /**
181+ * @private
182+ * @description Build child list based on populate
183+ * @param {Map } data - Immutable Map to be converted to JS object (state.firebase)
184+ * @param {Object } list - Path of parameter to load
185+ * @param {Object } populate - Object with population settings
186+ */
187+ export const buildChildList = ( data , list , populate ) =>
188+ mapValues ( list , ( val , key ) => {
189+ let getKey = val
190+ // Handle key: true lists
191+ if ( val === true ) {
192+ getKey = key
193+ }
194+ // Set to child under key if populate child exists
195+ if ( dataToJS ( data , `${ populate . root } /${ getKey } ` ) ) {
196+ return dataToJS ( data , `${ populate . root } /${ getKey } ` )
197+ }
198+ // Populate child does not exist
199+ return val === true ? val : getKey
200+ } )
201+
179202/**
180203 * @description Convert parameter under "data" path of Immutable Map to a
181204 * Javascript object with parameters populated based on populates array
@@ -188,71 +211,61 @@ export const dataToJS = (data, path, notSetValue) => {
188211 * import { connect } from 'react-redux'
189212 * import { firebaseConnect, helpers } from 'react-redux-firebase'
190213 * const { dataToJS } = helpers
214+ * const populates = [{ child: 'owner', root: 'users' }]
191215 *
192- * const fbWrapped = firebaseConnect(['/todos'])(App)
216+ * const fbWrapped = firebaseConnect([
217+ * { path: '/todos', populates } // load "todos" and matching "users" to redux
218+ * ])(App)
193219 *
194220 * export default connect(({ firebase }) => ({
195221 * // this.props.todos loaded from state.firebase.data.todos
196222 * // each todo has child 'owner' populated from matching uid in 'users' root
197- * todos: populatedDataToJS(firebase, 'todos', [{ child: 'owner', root: 'users' }] )
223+ * todos: populatedDataToJS(firebase, 'todos', populates )
198224 * }))(fbWrapped)
199225 */
200226export const populatedDataToJS = ( data , path , populates , notSetValue ) => {
201227 if ( ! data ) {
202228 return notSetValue
203229 }
204230
205- const pathArr = `/data ${ fixPath ( path ) } ` . split ( / \/ / ) . slice ( 1 )
206-
207- if ( data . getIn ) {
208- if ( ! toJS ( data . getIn ( pathArr , notSetValue ) ) ) {
209- return toJS ( data . getIn ( pathArr ) )
210- }
211- const populateObjs = getPopulateObjs ( populates )
212- // reduce array of populates to object of combined populated data
213- return reduce (
214- map ( populateObjs , ( p , obj ) =>
215- // map values of list
216- mapValues ( toJS ( data . getIn ( pathArr ) ) , ( child , i ) => {
217- // no matching child parameter
218- if ( ! child [ p . child ] ) {
219- return child
220- }
221- // populate child is key
222- if ( isString ( child [ p . child ] ) ) {
223- if ( toJS ( data . getIn ( [ 'data' , p . root , child [ p . child ] ] ) ) ) {
224- return {
225- ... child ,
226- [ p . child ] : toJS ( data . getIn ( [ 'data' , p . root , child [ p . child ] ] ) )
227- }
231+ const populateObjs = getPopulateObjs ( populates )
232+ // reduce array of populates to object of combined populated data
233+ return reduce (
234+ map ( populateObjs , ( p , obj ) => {
235+ // single item with iterable child
236+ if ( dataToJS ( data , path ) [ p . child ] ) {
237+ return {
238+ ... dataToJS ( data , path ) ,
239+ [ p . child ] : buildChildList ( data , dataToJS ( data , path ) [ p . child ] , p )
240+ }
241+ }
242+ // list with child param in each item
243+ return mapValues ( dataToJS ( data , path ) , ( child , i ) => {
244+ // no matching child parameter
245+ if ( ! child [ p . child ] ) {
246+ return child
247+ }
248+ // populate child is key
249+ if ( isString ( child [ p . child ] ) ) {
250+ if ( dataToJS ( data , ` ${ p . root } / ${ child [ p . child ] } ` ) ) {
251+ return {
252+ ... child ,
253+ [ p . child ] : dataToJS ( data , ` ${ p . root } / ${ child [ p . child ] } ` )
228254 }
229- // matching child does not exist
230- return child
231255 }
232- // populate child list
233- return {
234- ...child ,
235- [ p . child ] : mapValues ( child [ p . child ] , ( val , key ) => { // iterate of child list
236- let getKey = val
237- // Handle key: true lists
238- if ( val === true ) {
239- getKey = key
240- }
241- // Set to child under key if populate child exists
242- if ( toJS ( data . getIn ( [ 'data' , p . root , getKey ] ) ) ) {
243- return toJS ( data . getIn ( [ 'data' , p . root , getKey ] ) )
244- }
245- // Populate child does not exist
246- return val === true ? val : getKey
247- } )
248- }
249- } )
250- ) , ( obj , v ) =>
256+ // matching child does not exist
257+ return child
258+ }
259+ // populate child list
260+ return {
261+ ...child ,
262+ [ p . child ] : buildChildList ( data , child [ p . child ] , p )
263+ }
264+ } )
265+ } ) , ( obj , v ) =>
266+ // reduce data from all populates to one object
251267 Object . assign ( { } , v , obj ) ,
252- )
253- }
254-
255- return data
268+ )
256269}
257270
258271/**
0 commit comments