-
Notifications
You must be signed in to change notification settings - Fork 409
Allow differentiation between no data and data not yet loaded in the array case #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@jwngr: I've put two options together to get your thoughts. The first (#75) is what you mentioned in #73. Unfortunately its still necessary to have the value handler, since if there is no data at the path, none of the child* events will fire, and we wouldn't be able to differentiate between no data and data not loaded. The second (#76) is a more extreme deviation that might at least be a good discussion. I'm not sure there is much gained from maintaining the array manually. Its definitely neat, but the firebase lib is probably already doing this internally as part of the value event. We need the value event, so the question really is: is one value event that re-runs _createRecord on each child every time it changes more efficient than 4 child events that manually manipulate the array. And to take that a step further, this really made me wonder about a change that would be totally backward incompatible: If we got rid of _createRecord completely, and simply expose the Firebase.DataSnapshot objects directly, a lot of these problems go away:
I suspect this would be the most efficient way, since:
Interested to get your thoughts on this and if you've already ruled some of these ideas out for various reasons. |
Joe, thanks for this. Sorry I haven't gotten around to it yet. I hope to do so at some point this week. |
@jwngr Please feel free to close these. We've since started to do what I was describing last above, where we just basically have a bindSnap mixin, and thats the extent of it. That lets us check if its present, iterate it as an array, or use it as a value. This is working out well for us so far. |
Thanks Joe. Glad you got something working! Sorry for never responding to all of these. None of them really fit into the Firebase model that well unfortunately without making some breaking changes which I don't really want to do right now. Closing for now, but will reconsider these in the future. |
Any progress on this? In particular I would like two things: 1) differentiate between loaded/no data, 2) some way of knowing if all data has been loaded yet. The latter is to be used for e.g. server side rendering or automated tests. |
I think the best way to work around the backwards compatibility issue is to just have an extra "bindAsDataSnapshot" method. That would address my first request, but not my second. |
For posterity sake, here are my comments on the two PRs @joenoon put together since I never initially responded to them directly: #75 - I think the code here is good although I'm not wild about the #76 - This is actually the short term solution I proposed in #36. It most definitely works and simplifies the code, but it does so at the expense of performance, especially for large lists. If you have thousands of records, recreating the array and calling @tirsen - I'm definitely not against making breaking changes if they make sense and simplify the API. I just am not sure I like any of the proposed solutions to this problem. What you really want to do is what I suggest in this Stack Overflow post. Adding a
As I think about this more, @joenoon's initial suggestion in #73 to add some sort of Alright, I've written enough about this for now. I'll re-open this issue and see if we can come to a sensible solution together. So, what do you think? |
I don't think you necessarily need to make breaking changes. You can add a new "bindAsDataSnapshot" method in addition to other two binding types. That said, I've been building rather complex apps with this for a few months now and I do think you need to make some breaking changes. In particular I think the bind methods need to be idempotent: everything else in React is idempotent, when one of your key pieces of infrastructure isn't then things becomes difficult. I had to build idempotency on top of Reactfire and that was getting quite tedious. I've made a fork where I've made some changes necessary to support the app I'm working on. I think the API isn't there yet but in terms of functionality I think this is stuff that is necessary. In terms of API I think it needs a complete overhaul. Mixins are (slowly) getting phased out and replaced by higher order components. I would take inspiration by Relay which is the "modern" way of building React extensions and accomplishes something very similar to Reactfire (although Firebase makes the whole thing both more productive and more powerful). |
Thanks for the feedback. Here are some comments:
I don't like the API of that as I think it will lead to the bad practice of calling
I'm not sure I understand what you are suggesting here. How does this relate to the issue at hand? Also, in 99% of cases you only need to call
Yeah I've been meaning to look into an HOC for ReactFire for a while now but just don't have the time. See #38 for some discussion on this. I think this point is orthogonal to this particular issue though. |
No idempotency is not related to the issue at hand. You just mentioned that you didn't want to make any API breaking changes and I think that in order for reactfire to be useful for complex apps you need to. In particular reactfire is not idempotent which causes all sorts of problem because the rest of React is (i.e. calling setState multiple times with the same value has the same effect as calling it once). Making it idempotent is API breaking since where previously you would throw an error, when you're idempotent you would not. I doubt anyone is relying on that though. You do have to call bind methods again in certain situations. For example when using react-router and navigating internally in the same component you need to update your bindings to point at new things based on your params. Currently you have to unbind before you can do so, but since unbind isn't idempotent either you have to remember if you bound earlier and only unbind if you did. You basically have to build idempotency yourself. It gets annoying quickly. Trust me. :-) Anyway, it's unrelated to this issue but idempotency is good stuff, there should be more of it. :-) |
We have officially deprecated reactfire, as we no longer believe it is the best solution for Firebase developers looking to integrate with React. Please see the |
First crack at fixing this was in #73.
The text was updated successfully, but these errors were encountered: