Meteor publish user.profile does not show up on the subscriptions - meteor

Meteor.publishComposite('jobs', {
find: function() {
var user = null;
if (this.userId) {
user = Meteor.users.findOne(this.userId);
if ( user && user.profile && user.profile.isAdmin ) {
return Jobs.find({}, { sort: { createdAt: -1 }});
} else if(user && user._id) {
return Jobs.find({'createdBy': user._id});
}
} else {
return this.ready();
}
},
children: [
{
find: function(job) {
// Find post author. Even though we only want to return
// one record here, we use "find" instead of "findOne"
// since this function should return a cursor.
return Meteor.users.find(
{
_id: job.createdBy
},
{
fields: {
'profile': 1,
'createdAt': 1
}
}
);
}
}
]
});
This is the code I'm using from meteor-publishComposite package. I do not get the profile on my subscriptions for some reason. I can get the user.services to show up, but not the user.profile.

Related

Akryum: Vuex#1 for Meteor example app, addTrackers?

I don't really understand any of this from https://github.com/Akryum/meteor-vuex-example/tree/master/imports/vuex/modules: from init(data) all the way to if data in getters at the bottom references to vue instance data or state of vuex.
subModule.addTrackers({
selectedThread() {
let sub;
return {
init(data) {
data.selectedThread = null;
data.posts = [];
},
watch(state) {
// Dynamic subscription
if(sub) {
sub.stop();
}
if(state.selectedThreadId) {
sub = Meteor.subscribe('posts', state.selectedThreadId);
console.log('subscribed posts to thread ', state.selectedThreadId);
}
return {
id: state.selectedThreadId
}
},
update(data, {id}) {
data.selectedThread = Object.freeze(Threads.findOne({
_id: id
}));
data.posts = Object.freeze(Posts.find({
thread_id: id
}, {
sort: {created: -1}
}).fetch());
console.log('posts', data.posts);
},
getters: {
getSelectedThread: data => data.selectedThread,
getPosts: data => data.posts
}
}
}
})

Meteor Tracker autorun fires 2 times

This Meteor client code tries to make the Tracker.autorun to run once but as it appears to be that it has to run twice, once for setting and once for reactiveness.
Which is fine but it is firing 3 times. Once for setting and 2 for reacting even though the server only updated the user.profile.abc once.
To test it, I run this code in the mongodb console and the the iamge attached is what I got which confirms it fires twice.
How can I get it to run only once for responding to the changes in the users collection? Thanks
db.users.update({_id: Meteor.userId()},{$set: {'profile.ABC': ['a','b']}}).pretty()
//client
Meteor.call('cleanABC', (err) => {
if (!err) {
ABCListener();
}
});
ABCListener: () => {
Tracker.autorun(() => {
if (Meteor.userId()) {
console.log('auto run invoked');
if (Meteor.user().profile.ABC) {
const myArray = Meteor.user().profile.ABC;
//myFunction(myArray);
console.log('condition true');
} else {
console.log('condition false');
}
}
});
}
//server
'cleanABC': function() {
return Meteor.users.update({
_id: Meteor.userId()
}, {
$unset: {
'profile.ABC': ''
}
});
}
//and some where else in the code
Meteor.users.update({
_id: userId
}, {
$set: {
'profile.ABC': myArray
}
}, (err) => {
if (!err) {
console.log('just sent the array');
}
});
I think the problem is that you are just calling Tracker.autorun everytime you call the method.
I think if you change your client code to:
//client
ABCListener: () => {
Tracker.autorun(() => {
if (Meteor.userId()) {
console.log('auto run invoked');
if (Meteor.user().profile.ABC) {
const myArray = Meteor.user().profile.ABC;
//myFunction(myArray);
console.log('condition true');
} else {
console.log('condition false');
}
}
});
}
Meteor.call('cleanABC');
it should work.

Meteor - When using check roles wont work

I'm having a problem with a publish function. If I run the code without the roles package it works, however, when I add the roles if statement it doesn't. What am I missing here?
Path: publish.js (working)
Meteor.publish('userProfile', function(id) {
check(id, String);
return Meteor.users.find({_id: id}, {
fields: {
"profile.firstName": 1,
"profile.familyName": 1
}
});
});
Path: publish.js (not working)
Meteor.publish('userProfile', function(group, id) {
if (Roles.userIsInRole(this.userId, ['is_admin'], group)) {
check(id, String);
return Meteor.users.find({_id: id}, {
fields: {
"profile.firstName": 1,
"profile.familyName": 1
}
});
} else {
// user not authorized. do not publish secrets
this.stop();
return;
}
});

Meteor-tabular not displaying subscribed data

I'm using meteor tabular and publish composite addons.
I want to pub/sub user data based on user role, user data is getting send to client however not being displayed by tabular addon (for admin role only, it display fine for super-admin role, see code below).
My publish code:
Meteor.publishComposite('tabular_users', function (tableName, ids, fields) {
this.unblock();
return {
find: function () {
if (Roles.userIsInRole(this.userId, ['super-admin'], 'admin')) {
return Meteor.users.find({_id: {$in: ids}}, {fields: fields});
} else if (Roles.userIsInRole(this.userId, ['admin'], 'property-managers')) {
return Meteor.users.find({ "$and" : [
{ _id: { $in: ids } },
{ "profile.property_manager_id": Meteor.users.findOne(this.userId).profile.property_manager_id }
]}, {fields: fields});
} else {
this.stop();
return;
}
},
children: [
{
find: function(user) {
return PropertyManagers.find(
{ _id: user.profile.property_manager_id }
);
}
}
]
};
});

Meteor.js : SearchSource + Publish composite

I'm currently creating a research engine for my app.
Until now, I used Publish composite + iron router : The user could had filters to search for some specific set of users.
Now, I want him to be able to look for some keywords too. For that I downloaded and tested the great SearchSource package.
The problem is that the SearchSource server side definition only seems to allow to return one cursor.
How could I combine the two logics ? Even if it's tricky, please, share.
Of course I could make an autorunned subscription where I look for every users loaded on the client and then subscribe to the additionnal documents, but it is not really the most performant and beautifull thing to do.
Some data :
Here is my current Publish Composite for filters :
Meteor.publishComposite("findTalkers", function(page, langs){
//console.log("Find Talkers");
//console.log("page : " + page);
//console.log("langs : " + langs);
if (langs.length)
{
return ({
find: function()
{
if (langs && langs.length)
{
var test = {$in: langs};
preSelectedUsers = [],
selector = {
_id: {$ne: this.userId},
"profile.completed": true,
"profile.firstName": {$exists: true},
"profile.languages.native": {$exists: false},
"profile.languages.lang": test
};
Counts.publish(this, "nbUsers", Meteor.users.find(selector, {
fields: {_id: 1}
}), {noReady: false, nonReactive: true});
if (page > 1)
{
preSelectedUsers = Meteor.users.find(selector, {
sort: {'profile.talkname': 1},
limit: 25,
skip: (25 * (page || 1)),
fields: {_id: 1}
}).fetch();
var i = -1;
while (preSelectedUsers[++i])
preSelectedUsers[i] = preSelectedUsers[i]._id;
}
if (page > 1)
selector._id = {$in: preSelectedUsers};
return Meteor.users.find(selector, {
fields: userFields,
sort: {'profile.talkname': 1},
limit: 25
});
}
},
children: [
{
// Finding user's profile picture if it is not url
find: function(user)
{
if (user && user.profile && user.profile.avatar.type != "url")
return Images.find({_id: user.profile.avatar.data}, {sort: {uploadedAt: -1}, limit: 1});
}
}
]
});
}
else
{
return ({
find: function()
{
return Meteor.users.find({_id: "flush"});
}
});
}
});
Here is my research with SearchSource :
Client :
var searchOptions = {
keepHistory: 1000 * 60 * 5,
localSearch: true
},
SearchSources = {
talkersSearch: new SearchSource('users', ['profile.talkname'], searchOptions)
};
Router.map(function(){
this.route('talkers/:page?',
{
template: "talkers",
onBeforeAction: function(pause){
(Meteor.user() && Meteor.user().profile.completed)
? this.next()
: this.render('/profile');
},
waitOn: function(){
var filters = MatesFilter.find().fetch(),
i = -1;
while (filters[++i])
filters[i] = filters[i].value;
if (filters.length)
{
return Meteor.subscribe("findTalkers", (this.params.page || 1), filters, function(){
Session.set('numberuser', Counts.get("nbUsers"));
});
}
return Meteor.subscribe('myself');
}
});
}
Template.talkers.helpers({
getPackages: function() {
return SearchSources.talkersSearch.getData({
transform: function(matchText, regExp) {
return matchText.replace(regExp, "<b>$&</b>")
},
sort: {isoScore: -1}
});
}
}
Template.talkers.events({
"keyup #header-search": _.throttle(function(e) {
Session.set("matesSearch", $(e.target).val().trim());
console.log("Searching for : " + text);
SearchSources.talkersSearch.search(Session.get("matesSearch"), {
page: (this.params.page || 1),
filters: filters
});
}, 200)
}
SERVER :
SearchSource.defineSource('users', function(searchText, options) {
var options = {sort: {"profile.talkname": -1}, limit: 25};
if(searchText)
{
var regExp = buildRegExp(searchText);
selector = { $or: [
{ "profile.talkname": regExp },
{ "profile.bio": regExp }
] };
return Meteor.users.find(selector, options).fetch();
}
return ;
});
All this Gives me two sources from which I can get users. I'd want to get a mean to merge the two ides (a composition of publication INSIDE the search, for example).
Thanks you.

Resources