Open psych0der opened 7 years ago
There is not currently support for nested populates (they only work one level deep for now). Although this has been discussed, and I love the idea. I'll put it onto the roadmap.
Roadmap updated
Thanks. Looking forward to use it soon :)
On Tue, Mar 21, 2017 at 1:48 PM Scott notifications@github.com wrote:
Roadmap http://react-redux-firebase.com/docs/roadmap.html#upcoming-minor-version-v140 updated
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/prescottprue/react-redux-firebase/issues/85#issuecomment-288006285, or mute the thread https://github.com/notifications/unsubscribe-auth/AA4q9aV9hKR2vL4Jnyujm_oDnjaUviGEks5rn4fygaJpZM4MiR8d .
-- Regards Mayank Bhola (+91-9953267725)
@prescottprue is there also a way to expand keys instead of parameters? Say I have:
{
"users": {
"key1": {
"name": "Adam",
"licenses": {
"licenseId1": true
}
},
"key2": {
"name": "Bob"
}
},
"licenses": {
"licenseId1": {
"code": "xyz"
}
}
}
I want to populate the licenses index in my users with the full license objects from the /licenses. Since I'm not populating by a child with a fixed name, would that be possible with your code?
@christianscheuer It depends if you are talking about your own account or just the users list in general.
Users List - link to the example in the docs
const populates = [
{ child: 'licenses', root: 'licenses' }
]
@firebaseConnect([
{ path: '/users', populates }
])
@connect(({ firebase }) => ({
users: dataToJS(firebase, '/users'), // users list not populated
populatedUsers: populatedDataToJS(firebase, '/users', populates), // users with licenses populated
}))
Own Account - link to the example in the docs
const config = {
userProfile: 'users',
profileParamsToPopulate: [
'licenses:licenses'
// or object notation: { child: 'licenses', root: 'licenses' }
]
}
Since this isn't directly related to this issue, feel free to reach out over gitter or create another issue if you have more questions.
For clarity, here is the example I am using to work on this feature.
"todos": {
$todoId: {
"comments": {
$commentId: true
}
},
},
"comments": {
$commentId: {
"owner": $uid
}
},
"users": {
$uid: {
email: 'some@email.com',
displayName: 'Some Guy'
}
}
Populate a list of todos's comments, along with the "child population" of the owner of each comment. The connect syntax might look like so (could change):
const populates = [
{ child: 'comments', root: 'comments' }, // maybe childPopulates: 'owner' on here instead?
{ child: 'comments.owner', root: 'users' },
]
@firebaseConnect([
{ path: 'todos', populates }
])
@connect(({ firebase }) => ({
todos: populate(firebase, 'todos', populates)
})
This feature is still in the works so syntax may change, but the hope is to get it into v2.0.0
.
The syntax looks exactly as expected 😃
@psych0der Good to hear.
The hope is to get this in to v2.0.0
, but it was a but much to squeeze into v2.0.0-beta
.
@prescottprue I see you're planning to add this to 1.6.0, isn't going into 2.0?
@projoneftw It will hopefully eventually make it into v1.6.0
as well v2.0.0
(since some still prefer the immutableJS toJS
syntax).
The roadmap will indicate it under both, but switch the milestone back to v2.0.0
for clarity.
Hi Scott, awesome library! I think this is a vital feature. Is there an eta for when this is likely to make its way on to v2.0.0 ?
Is there a way we can achieve this now without waiting for populates method to be updated ?
@maitham1 Population can be done manually, populate
is just a convenience method. That said, most agree that doing this by hand can get messy.
populate
If you pass populates to your query, the queries needed to retrieve that data and place it in redux will be created.
Usage of populate
in the connect function is up to you:
const populates = [{ child: 'owner', root: 'users' }]
@firebaseConnect([
{ path: 'todos', populates }
])
@connect(
({ firebase, firebase: { data: { users }, ordered: { todos } } }) => ({ // notice I grab ordered instead of data so it is an array
todos: todos ? todos.map(todo => ({ ...todo, owner: users[todo.owner] })) : [],
// equivalent to
// todos: populate(firebase, 'todos', populates)
})
)
If you are trying to create queries for "nested" data, for now you will have to create queries for the needed data:
Continuing example from earlier nested population of owner inside of populated comments (or "nested"):
const populates = [{ child: 'owner', root: 'users' }]
const runNestedPopulate = (populatedTodos) =>
@firebaseConnect([
{ path: 'todos', populates },
// NOTE: The following line will only be needed until nested population is supported
{ path: 'users' } // needed to get users queried on first level population
])
@connect(
({ firebase: { data: { users, todos } } }) => {
const todos = populate(firebase, 'todos', populates, [])
return {
todos: todos.map(todo => ({
...todo,
comments: todo.comments.map(comment => ({
...comment,
owner: users[comment.owner],
})
})
}
})
)
As indicated the future hope would be to do the following:
const populates = [
{
child: 'comments',
root: 'comments',
childPopulates: [ { child: 'owner', root: 'users' } ]
},
]
@firebaseConnect([
{ path: 'todos', populates }
])
@connect(({ firebase }) => ({
todos: populate(firebase, 'todos', populates)
})
NOTE: The examples provided are not tested nor are they necessarily "suggested practice", and are provided to help discuss specifics.
@prescottprue Awesome thanks for this. I have a question isn't this method really inefficient, you're querying your entire user's directory, rather than the specific user you're after?
@maitham1 Yes it is inefficient to do, but will be more than fine for many applications. It can also help if you do type: 'once'
on the users query.
This answer is part of why the future plan is to get nested population working (then only needed queries are run).
Did this feature make it into a preview or anything? Is there a dev version that needs testing?
Hello there,
I have a data structure as follows
Is there a way that I can make nested populates work when I initially load
Obj1
?