Custom field publish for users collection is not working properly - meteor

I just added one custom field into default users table. we do publish the specific field and subscribed. when we tried to access the particular field value in the account methods "Accounts.onLogin" it has value on initial login but it lost on reactive refresh.
if (Meteor.isServer) {
Meteor.publish("users",function(){
return Meteor.users.find({_id:this.userId},{fields:{"customField":1}}); // Publish the user with custom fields
});
}
if (Meteor.isClient) {
Meteor.subscribe("users");
Accounts.onLogin(function(){
alert(Meteor.user().customField + ' Comes '); // it has value on initial login but it lost on reactive refresh.
});
}

I think you can only extend profile in Meteor.users.. See this discussion for more: https://forums.meteor.com/t/how-to-add-new-field-on-meteor-users/1065/2

Related

How to e.preventDefault() when clicking on Update in Gutenberg, WordPress

How to e.preventDefault() when clicking on Update in Gutenberg, WordPress?
What I'm trying to do is check something and if there is any error, I will prevent the update process and show the error.
My code:
$(document).on('click', '#editor .editor-post-publish-button', function (e) {
e.preventDefault();
// Show Errors...
});
However, the e.preventDefault() is not preventing the process and the post is getting updated.
With JavaScript, you can use the core WordPress Block API to issue error notices if your own validation logic detects any issues and prevent the post from saving if errors are present, eg:
JavaScript
// Create error notice
wp.data.dispatch('core/notices').createErrorNotice(
'A value is required', // Message displayed to User
{
id: 'my-field', // Used to remove notice and check if notice is present
isDismissible: false,
}
);
// Remove notice
wp.data.dispatch('core/notices').removeNotice('my-field'); // unique id 'my-field'
// Prevent post from saving
wp.data.dispatch( 'core/editor' ).lockPostSaving( 'my-field' );
// Enable post saving
wp.data.dispatch( 'core/editor' ).unlockPostSaving( 'my-field' );
By using native WordPress API, displaying and styling of the notices is taken care of and keeps the UX consistent. The Documentation also has an example of preventing a post from publishing which may be helpful as well.

Displaying form on first login

I'm trying to work out how I can display a form to a user upon their first login to my app ( to fill in profile information) after which they can proceed to the regular site.
Could anyone point me in the right direction?
Thanks
You can make the trick using app startup script:
https://devsite.googleplex.com/appmaker/settings#app_start
Assuming that you have Profile model/datasource, code in your startup script will look similar to this:
loader.suspendLoad();
var profileDs = app.datasources.Profile;
// It would be more secure to move this filtering to the server side
profileDs.query.filters.UserEmail._equals = app.user.email;
profileDs.load({
success: function() {
if (profileDs.item === null) {
app.showPage(app.pages.CreateProfile);
} else {
app.showPage(app.pages.HomePage);
}
loader.resumeLoad();
},
failure: function() {
loader.resumeLoad();
// your fallback code goes here
}
});
If profile is absolute must, I would also recommend to enforce the check in onAttach event for every page but CreateProfile (to prevent navigation by direct link):
// Profile datasource should be already loaded by startup script
// when onAttach event is fired
if (app.datasources.Profile.item === null) {
throw new Error('Invalid operation!');
}
I suggest checking the user profile upon login. If the profile is not present, display the profile form, otherwise, proceed to the regular site.

Meteor JS & Blaze - Show Only Once on Load

I have a partial that show's a notification modal to agree to the site's terms and service that I would only like to show once (once they click I agree it goes away).
Is there anyway to do that with Meteor?
Assuming you want to store a boolean in the DB indicating that the user has accepted the terms (so they never get asked again), you could add a field called hasAcceptedTerms somewhere on the user object (e.g. in the user's profile). Once you do that you could write your template like this:
<template name="myTemplate">
{{#if areTermsVisible}}
(put terms partial here)
{{/if}}
</template>
Where areTermsVisible looks like:
Template.myTemplate.helpers({
areTermsVisible: function() {
var user = Meteor.user();
return user && user.profile && !user.profile.hasAcceptedTerms;
}
});
And the code to record the acceptance looks like:
Template.myTemplate.events({
'click .accept-terms': function() {
var userId = Meteor.userId();
var modifier = {$set: {'profile.hasAcceptedTerms': true}};
Meteor.users.update(userId, modifier);
}
});
Maybe not surprisingly, the best way to deal with cookies policy notification is by using cookies. The problem is not meteor-specific, but there are at least two good atmosphere packages that can help you to deal with the problem:
https://atmospherejs.com/mrt/cookies
https://atmospherejs.com/chuangbo/cookie
What you need to do is basically, set cookie
Cookie.set('userHasAcceptedPolicy', true, { year: 1 });
with whatever arguments you like, and as soon as the user clicks the "accept" button. Then, before you decide if you need to show the policy notification you can use:
Cookies.get('userHasAcceptedPolicy');
to see if there's a need to do so. So it's pretty much the same solution as #DavidWeldon suggested but it does not require referencing the Meteor.user() object, so the user does not need to have an account to accept the policy.
Please note, that - at least in case of mrt:cookies - Cookies.get is a reactive data source, which is quite helpful when it comes to rendering templates.
There's plenty of ways...
This isn't a Meteor specific question.
Template.notifications.events({
'click #close-modal': function(e, t) {
$('#modal').hide();
}
})

First Sign-in after Signup Show Config Page Once Effectively

I'm trying to show a popup or a template page if user has signed in for the first time after sign up basically allowing them configure some stuff on that page before going to dashboard home, It's only needed for convenience and here is what I got (telescope code)
Router.onBeforeAction(hasCompletedChannels);
hasCompletedChannels: function() {
if(!this.ready()) return;
var user = Meteor.user();
if (user && ! userCompletedChannels(user)){
this.render('connectChannels');
} else {
this.next();
}
}
Which I don't really like because this will always run every time, I want it to run just once, And don't even execute the check function. Is it possible to detect first sign in? (After signup)
I think you could just tie it to the specific route. Right now you're tying it to the Router object (every render forces that check as you point out). So if you define your login function to send someone to a specific route after sign-in, you could just verify on that route.
The function Accounts.onLogin gives you a way to do stuff after the login.
Something like
Router.route('profile', {
path: '/profile',
onBeforeAction: function() {
// Check some stoof
// If first time logged in
// render first time template
// else
// this.next() will render the profile page
},
waitOn: function() {
return [
// some subs
];
},
data: function() {
// some data
}
});
I'm assuming that its going to get routed to a page called profile (seems to make sense). You could check for first time logged in by some attribute you use in the user object and the fields you want filled out and force a render of a different template, or a subtemplate. Check out the Iron Router guide for more ideas on ways to configure it.
Best of luck

AngularFire update single object

How to update a single object within node.
{
foo:
{
title: 'hello world',
time: '1000'
}
}
As above, I just want update title.
$firebase(new Firebase(ref).child('foo')).$save(); will update the entire node. Also tried $save('title') but not work.
The reason I just want to update a single object, because some of the ng-model doesn't need to update to firebase.
Heres an example setting the title to "whatever"
$firebase(new Firebase(ref)).$child('foo').$child('title').$set("whatever")
I have recently been working with angularfire and firebase. I am not sure if this is a fix but i dont think you dont need to explicitly select the item property you want to update when you are using the $save() method.
For instance, in my use case i was selecting a user and had an init function that got that whole object
html
<ul ng-repeat="user in vm.users>
<button ng-click="vm.updateUserInit(user)">Edit</button>
</ul>
This then opened up the update form with the users properties. In the controller i took that user and assigned it into a $firebaseObject.
controller
var selectedUser;
vm.updateUserInit = function (user) {
var ref = new Firebase("https://<foo>.firebaseio.com/users/" + user.$id);
selectedUser = $firebaseObject(ref);
}
It justs puts the user into a firebase object as the variable selectedUser to use in the $save.
Then when the user updates the details
html
<button type="button" ng-click="vm.updateUserDetails()">Update User Details</button>
the function already has the selected user as an object to use and anything added will be updated. Anything omitted will not.
controller
vm.updateUserDetails = function () {
selectedUser.firstName = vm.firstName;
selectedUser.$save();
}
The selectedUser.$save(); changes only the first name even though the user has 6 other properties
Not sure if this helps, trying to wrap my head around all of this as well. Check out valcon if you dont already have it. Really nice extension on the chrome inspector for firebase
UPDATE FOR ANGULARFIRE 2
if you create a service for your calls , which could serve all update calls
constructor(private db: AngularFireDatabase) {}
update(fbPath: string, data: any) {
return this.db.object(fbPath).update(data);
}
And then in the page component
this.api.update(`foo`, ({ title: 'foo Title' }) );
Much simpler

Resources