How to wait for Meteor.users when changing a profile field

I use the profile field in the collection defined by the Meteor.users system to store information about the last user of the message read on each communication channel with the following structure:

profile : { lastMsgRead : [ {channelId: 'YYEBNEI7894K', messageCreatedAt: '14578970667"} {channelId: 'GERYUE789774', messageCreatedAt: '14578999845"} ] } 

I found that reading lastMsgRead is not working due to the fact that on the client the array is still empty while reading. I will correctly publish this field for the client through:

 Meteor.publish(null, function() { return Meteor.users.find({}, {fields: {_id: 1, username: 1, emails: 1, profile :1}}); 

and I read its value from the client library located in the lib directory as follows:

 var chHistory = Meteor.user().profile.lastMsgRead; 

Debugging my code looks like this: the changes I make in the profile field were not distributed to all clients at the time I read them. Therefore, I need to wait until the Meteor.users subscription is ready, but I do not have its handle - you will receive it automatically from the framework.

How to wait until the Meteor.users subscription is ready?

+6
source share
4 answers

Since the meteorite does not provide you with a handle to the current subscription, there is no obvious way to wait for data. Here are a few options:

use guard

A typical way to solve this problem is to add guards to your code. In your template (s) that are experiencing this problem, you can write something like:

 var user = Meteor.user(); var lastMsgRead = user && user.profile && user.profile.lastMsgRead; 

If you find that you write a lot of this code, you can include it in a general function:

 var extractProfileValue = function(key) { var user = Meteor.user(); return user && user.profile && user.profile[key]; }; 

And use it as follows:

 var lastMsgRead = extractProfileValue('lastMsgRead'); 

show spinner

You can check the user profile in the template itself:

 <template name='myTemplate'> {{#unless currentUser.profile}} // show spinner or loading template here {{else}} // rest of template here {{/unles}} </template> 

If you need this experience on all of your pages, you can add it to your layout template.

backup publisher

WARNING: I have not tried this

One way to get a custom subscription descriptor is to simply add the redundant publisher and subscribe to it:

 Meteor.publish('myProfile', function() { return Meteor.users.find(this.userId, {fields: {profile: 1}}); }); 

Then in your router:

 waitOn: function () { return Meteor.subscribe('myProfile'); } 
+6
source

You publish too much unnecessary data. You should publish only what you need. Meteor.user () returns the user object if the user is logged in. In your null post, you filter using this.userId . You can wait at this publication at the template level or with the Iron Router.

0
source

Since you are using zero or “automatic” publishing, there is one really simple fix for this problem and that to add meteorhacks: fast-render for your application. It will send all automatically published data using the initial html application, so that it is available immediately after the page loads.

0
source

You need to read http://docs.meteor.com/#/full/meteor_user again.

On the client, this will be a subset of the fields in the document that are published from the server (other fields will not be available on the client). By default, the server publishes a username, email address, and profile (writable by the user). SeeMeteor.users is more for fields used in user documents.

You can add a helper that will return the data.

I would also delete your post as it already took care of that.

Meteor.user (). profile.blah

-1
source

Source: https://habr.com/ru/post/987366/


All Articles