We recently migrated our Meteor application to Meteor 3.0. We are using custom Blaze templates for the account forms. In our main {{> atForm }} template, we include the {{> atOauth}} template. After migrating, however, it appears that the div for the {{> atOauth}} template is rendering, but has no child elements. Here is a screenshot where you can see the empty div in the developer console:
Some additional context:
- Although the oauth button is not displaying properly, it does seem to be making the usual http requests to Google on render as it did before.
- Relevant packages that we have:
- accounts-ui@1.4.3
- accounts-ui-unstyled@1.7.2
- accounts-google@1.4.1
- accounts-oauth@1.4.5
- accounts-base@3.0.0 - It’s worth noting that if we add the {{> loginButtons}} template from the Meteor docs, it does work and we can sign in with Google, but I’d like to avoid switching to that.
- Here is our custom template that replaces {{> atForm }}
<template name="myAtForm">
{{#unless hide}}
<div class="at-form">
{{#if showError}}
{{> atError}}
{{/if}}
{{#if showResult}}
{{> atResult}}
{{/if}}
{{#if showMessage}}
{{> atMessage}}
{{/if}}
{{#if showPwdForm}}
{{#if showOauth}}
{{> atOauth}}
<div style="font-size: 16px; margin-top: 30px; margin-bottom: 5px; text-align: center; color: #282738; font-family: mukta;"> Or...</div>
{{/if}}
{{> atPwdForm}}
{{/if}}
{{#if showTermsLink}}
{{> atTermsLink}}
{{/if}}
{{#if showResendVerificationEmailLink}}
{{> atResendVerificationEmailLink}}
{{/if}}
</div>
{{/unless}}
</template>
- The {{# if showAuth}} does seem to be working properly based on console.logs. Even if I remove the if statement so that {{> atOauth}} should display no matter what, it still doesn’t display
- Here is our AccountsUIWrapper.jsx:
import { useLocation } from 'react-router-dom';
import { Template } from 'meteor/templating';
import { Blaze } from 'meteor/blaze';
import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import '../styles/accounts.css';
import './at_bootstrap.css';
import './atForm.html';
import './myAtSocial.html';
import './myAtTextInput.html'
import './hiddenField.html';
Template.prototype.customReplaces = function customReplaces(otherTemplate) {
var self = this;
function replaceRender(template) {
// String template names can be provided and template object is looked up
if (typeof template === 'string') {
template = Template[template];
}
if (!template) {
return;
}
template.renderFunction = self.renderFunction;
}
// Accept an array as otherTemplate argument
if (Array.isArray(otherTemplate)) {
otherTemplate.forEach(replaceRender);
return;
}
replaceRender(otherTemplate);
};
AccountsTemplates.configure({
privacyUrl: `${Meteor.settings.public.HOMEPAGE}/privacy-policy`,
termsUrl: `${Meteor.settings.public.HOMEPAGE}/terms-of-use`,
continuousValidation: true,
negativeFeedback: true,
negativeValidation: true,
positiveValidation: true,
positiveFeedback: true,
showValidating: true,
texts: {
button: {
signUp: "Register"
}
}
//showForgotPasswordLink: true
});
AccountsTemplates.removeField('email');
AccountsTemplates.addField({
_id:'email',
type: 'email',
required: true,
displayName: 'email',
placeholder: {
signIn: "Enter your email",
signUp: "Enter your email"
},
re: /.+@(.+){2,}\.(.+){2,}/,
errStr: 'Invalid email',
});
AccountsTemplates.removeField('password');
AccountsTemplates.addField({
_id: 'password',
type: 'password',
placeholder: {
signUp: "Enter your password",
signIn: "Enter your password"
},
required: true,
minLength: 6,
re: /(?=.*\d)(?=.*[a-z])(?=.*[0-9])(?=.*[A-Z])(?=.*[^A-Za-z0-9]).{6,}/,
errStr: 'At least 1 digit, 1 lowercase, 1 uppercase, and 1 special char',
});
const AccountsUIWrapper = () => {
const containerRef = useRef(null);
const location = useLocation();
useEffect(() => {
if (location.pathname === "/signin") {
AccountsTemplates.setState("signIn");
} else if (location.pathname === "/signup") {
AccountsTemplates.setState("signUp");
} else if (location.pathname === "/forgotpwd") {
AccountsTemplates.setState("forgotPwd");
} else if (location.pathname === "/resetpwd") {
AccountsTemplates.setState("resetPwd");
}
Template["atForm"].helpers({
showOauth: function () {
return !Session.get("hideOauth");
}
});
Template.myAtForm.customReplaces("atForm");
// Template.myAtSocial.customReplaces('atSocial');
Template["atTextInput"].helpers({
equals: function(a, b) {
return a === b;
}
});
Template["atTextInput"].events({
'focus #at-field-email'(event, instance) {
instance.$('#email-icon').css("display", "none");
instance.$('#email-icon-selected').css("display", "flex");
},
'focus #at-field-password'(event, instance) {
instance.$('#password-icon').css("display", "none");
instance.$('#password-icon-selected').css("display", "flex");
},
'focus #at-field-password_again'(event, instance) {
instance.$('#password-again-icon').css("display", "none");
instance.$('#password-again-icon-selected').css("display", "flex");
},
'blur #at-field-email'(event, instance) {
instance.$('#email-icon').css("display", "flex");
instance.$('#email-icon-selected').css("display", "none");
},
'blur #at-field-password'(event, instance) {
instance.$('#password-icon').css("display", "flex");
instance.$('#password-icon-selected').css("display", "none");
},
'blur #at-field-password_again'(event, instance) {
instance.$('#password-again-icon').css("display", "flex");
instance.$('#password-again-icon-selected').css("display", "none");
},
});
Template["myAtTextInput"].customReplaces("atTextInput");
const view = Blaze.render(Template.atForm, ReactDOM.findDOMNode(containerRef.current));
return () => {
Blaze.remove(view);
if (Meteor.isProduction) {
analytics.identify(Meteor.userId());
}
};
}, [location]);
return <span ref={containerRef} />;
};
export default AccountsUIWrapper;