I created a small project that lists chat messages (5000 of them). As a first test, I created this message list using Blaze and everything worked fine. Then I used
meteor create --react <my-project-name> command and I started creating a similar sample using React. At the top of the list, I show the total number of messages. In Blaze everything worked fine (the total number is correct and the list is complete and the are shown at the same time). In React, the message list is shown and the total number of messages at the top is gradually updated, like: 1000, 2000, 3500, … 5000. Using withTracker I couldn’t find any documentation about publications and subscriptions readiness (I guess that it could depend on that)…
Do you know how can I fix this?
Here you can find my react sample https://github.com/massimosgrelli/meteor-react-chat-test
Do you know where I can find documentation about withTracker (except the Meteor Guide, which has just a few paragraphs)?
Might be worthwhile to complete the meteor react tutorial
Are you sure you’ve read the whole withTracker section of the guide?
Because React | Meteor Guide shows you how you can detect subscription readiness with example code for a single subscription as well as multiple subscriptions as you can see on this screenshot from that page:
Although, using the client side minimongo to calculate counts would be misleading for the user, or at least serve to only show the number of messages on the screen. If you are intent on showing the total number of messages available on the database (on the server), then you need to come up with a solution that publishes the count.
Luckily, the docs for the publish method at Publish and subscribe | Meteor API Docs show you exactly how to do that:
Alternatively, you can use a package from atmosphere that does just that. I remember a tmeasday:publish-counts package and some successors to it.
thanks for your reply.
I did read withTracker page on the Guide, so I did understand the subscription. I didn’t know that I have to use publication too, though. I suppose I can put in the server directory as usual and including it in the main.js file. Although, I guess that Blaze too uses the same minimongo mechanism, so I don’t understand why in that case it works perfectly without observing changes on the server with a specific publication and exposing count with a trick.
So I suppose that something is managed differently when you use React instead of Blaze. Except for this count example, do I need to create publications in React like I do with Blaze?
EDIT: after including the subscription to
messages.all publication and passing subscription readiness status back to the React component everything worked fine. BTW: The total number of records is now shown correctly at the top of the list, without publishing
count(is it really necessary?), but simply asking for
length. Now it has the exact behavior of the Blaze sample.
If anyone is interested in downloading the updated version of my sample you can find it here https://github.com/massimosgrelli/meteor-react-chat-test
In meteor, all subscriptions on the client require a publication on the server with the same name. There’s only one way you can get away without publications is by using (or not removing from an empty project)
autopublish which publishes all your data to all your clients without setting up any publications or subscriptions.
You may have either accidentally copied over some publication code or have included the autopublish package in your blaze-based version.
Now about the messagelist array length vs published counts; as I’ve tried to explain in my (rather long) previous post, your client will only have the amount of data that it has subscribed to (and published by the server) and unless all data is published you will have a limited set of it, hence the misleading array length, which repreents the length of the data that had been published at the time.
Publishing all the data might make sense for apps that don’t contain too much data for the client and the network, but reasons like performance, capacity, security and such, you end up publishing only a subset of the database that is relevant for that client at that point in time. To mitigate for the lack of possibility to use “implicit” lookups like length of an array, you then need to create more “explicit” calculation and publication of the count.
Now within the meteor context, keeping track of counts and publishing them to the client require tapping into some low level primitives of the publication mechanism. That’s the reason you need to use the observe methods. But, like I’ve also pointed out in my previous post, there are packages (libraries) on atmosphere that make it easy to publish counts from your server collections.
And once again, I’d like to ensure you that non of this is relevant to blaze vs react vs vue vs angular vs whatever ui library/framework you fancy. This is all about meteor’s data system and its client/server data synchronization/delivery mechanisms which are “publication/subscription” and “meteor methods”. You can of course still use more traditional http rest endpoints or a more modern graphql approach if you want to.
Thanks for your clarification.
The initial version of my React test had autopublish package installed, and that’s why I could see some data without any explicit subscriptions.
Ok, I know your previous post was long and clear :), thanks. Understood the “array length vs published counts” part. I thought that with the explicit subscription statement minimongo would wait for all the data before making them available to the UI components. However, got it, I’ll use what you suggested with observeChanges.
And once again, I’d like to ensure you that none of this is relevant to blaze vs react vs vue vs angular vs whatever ui library/framework you fancy.
I’m creating these samples just to understand if I have a real advantage using React over Blaze (which I love). Everybody is drinking the React cool aid these days and I want to understand why (I already read a lot about it). For example, I thought that with 5,000 messages to show, React was faster to render the list elements when you add a new message to the list itself (thanks to its virtual DOM can render just what changed). In my sample it’s not, Blaze is faster than React (I don’t know how to measure the rendering time precisely, but it looks slower). Probably too few records or maybe the wrong case. The only difference between the 2 of them is that in the React example I’m using the insecure package and a client-side insert method. In the Blaze one, I’m using a server-side method.
Can I keep live update using mysql + apollo/graphoql?
It looks like you might want to give Vue a chance because blaze developers of the past who have tried vue (or both vue and react) usually tend to like vue better because of the similarities between the concepts shared and even arguably descended from blaze.
That being said, you can use blaze, react and vue very similarly in terms of architecture but as there are some natural (or most publicized) usage patterns for each of these, vue tends to keep many similarities with blaze.
Also I remember some benchmarks done earlier by @mitar on blaze/react/vue and blaze turned out to be significantly slower, which might be important if you are rendering large lists. Although, there are ways to make large lists render faster in any of these alternatives.
Nonetheless, blaze is still a very mature, powerful and approachable ui library and is being used in many high-profile apps.
Regarding live update with mysql+graphql, sure you can. Graphql has the concept of subscriptions. But it is a little bit more involved to set up and you may find it a little bit scary.
There are two main community packages that aim to make meteor integration seamless, especially making subscriptions easier:
Not that you would need any of these to set up graphql with meteor. They are there for the seamless experience.
You might also be interested in http://vulcanjs.org/ a react+graphql framework based on meteor as well as https://forums.meteor.com/t/starter-kit-with-meteor-1-8-apollo-2-react-16-multilingual-support-pwa-ssr-authentication-styled-components a batteries-included starter kit for apollo/react projects, although afaik this last one lacks subscriptions.