Question

This code is from this tutorial: https://waaave.com/tutorial/meteor/design-a-complete-authentication-system-with-meteor/#L11

it's step 6.1 and as far as I can tell there are no errors but for some reason it doesn't work and the "Forgot Password" link does nothing when I click on it. Does anyone know what's wrong?

Javascript:

Template.main.helpers({
    showForgotPassword: function() {
        return Session.get('showForgotPassword');
    }
});

// Sign In Template
Template.signIn.events({
    'submit #signInForm': function(e, t) {
        e.preventDefault();

        var signInForm = $(e.currentTarget),
            email = trimInput(signInForm.find('.email').val().toLowerCase()),
            password = signInForm.find('.password').val();

        if (isNotEmpty(email) && isEmail(email) && isNotEmpty(password) && isValidPassword(password)) {
            Meteor.loginWithPassword(email, password, function(err) {
                if (err) {
                    Session.set('alert', 'We\'re sorry but these credentials are not valid.');
                } else {
                    Sesson.set('alert', 'Welcome back New Meteorite!');

                }
            });
        }
        return false;
    },

      'click #showForgotPassword': function(e, t) {
        Session.set('showForgotPassword', true);
        return false;
    },

});

Html:

<div id="topbar">
            {{> signOut}}
     {{#unless resetPassword}}
         {{#unless currentUser}}
             {{#unless showForgotPassword}}
             {{else}}
                  {{> forgotPassword}}
             {{/unless}}
         {{else}}
          {{/unless}}
     {{else}}
         {{> resetPassword}}
     {{/unless}}
    </div>

<template name="signIn">
            <a class="show-forgot-password" href="javascript:void(0);" id="showForgotPassword">Forgot Password?</a>
    <div class="sign-in" id="signIn">
        <form action="/signin" class="sign-in-form" id="signInForm" method="post">
            <input class="email" id="signInEmail" type="text" name="email" placeholder="Email">
            <input class="password" id="signInPassword" type="password" name="password" placeholder="Password">
            <input class="btn btn-success" id"signInButton" type="submit" value="Sign In">
        </form>
    </div>
    <!-- end .sign-in -->
</template>

<template name="signOut">
    <div class="connected">
        <a class="sign-out" href="/" id="signOut">Sign Out</a>
    </div>
    <!-- end .connected -->
</template>

<template name="signUp">
    <div class="sign-up">
        <form action="/sign-up" class="sign-up-form" id="signUpForm" method="post">
            <input class="username" id="signUpUsername" name="username" placeholder="Username" type="text" >
            <input class="email" id="signUpEmail" name="email" placeholder="Email" type="text" >
            <input class="password" id="signUpPassword" name="password" placeholder="Password" type="password">
            <input class="password-confirm" id="signUpPasswordConfirm" name="password-confirm" placeholder="Confirm" type="password">
            <input class="btn btn-success" type="submit" id="submit" value="Sign up for Chattly">
        </form>
    </div>
    <!-- end .sign-up -->
</template>

<template name="forgotPassword">
    <div class="forgot-password" id="forgotPassword">
        <a class="return-to-sign-in" href="javascript:void(0);" id="returnToSignIn">Return</a>
        <form action="/forgot" class="forgot-password-form" id="forgotPasswordForm" method="post">
            <input class="email" id="forgotPasswordEmail" type="text" name="email" placeholder="Email Address">
            <input class="btn-submit" type="submit" value="Send">
        </form>
    </div>
    <!-- end .forgot-password -->
</template>

<template name="resetPassword">
    <div class="reset-password">
        <h2 class="headline">You're now saved, <span class="bold">follow the light!</span></h2>
        <h3 class="details">You just have to type and confirm your new password to regain access to your dashboard.</h3>
        <form action="/reset-password" class="reset-password-form" id="resetPasswordForm" method="post">
            <input class="password" id="resetPasswordPassword" name="password" placeholder="Your New Password" type="password" >
            <input class="password-confirm" id="resetPasswordPasswordConfirm" name="password-confirm" placeholder="Confirm New Password" type="password" >
            <input class="btn-submit" type="submit" value="Reset">
        </form>
    </div>
    <!-- end .reset-password -->
</template>
Was it helpful?

Solution

At that point (6.1) in the tutorial, you have not yet configured any event handlers for the forgotPassword. It is not working because the code is not there yet.

In the following section, 6.2, the author walks you through sending an email for initiating password recovery:

Template.forgotPassword.events({
    'submit #forgotPasswordForm': function(e, t) {
        e.preventDefault();

        var forgotPasswordForm = $(e.currentTarget),
            email = trimInput(forgotPasswordForm.find('#forgotPasswordEmail').val().toLowerCase());

        if (isNotEmpty(email) && isEmail(email)) {
            Accounts.forgotPassword({email: email}, function(err) {
                if (err) {
                    if (err.message === 'User not found [403]') {
                        Session.set('alert', 'This email does not exist.');
                    } else {
                        Session.set('alert', 'We\'re sorry but something went wrong.');
                    }
                } else {
                    Session.set('alert', 'Email Sent. Please check your mailbox to reset your password.');
                }
            });
        }
        return false;
    },

    'click #returnToSignIn': function(e, t) {
        Session.set('showForgotPassword', null);
        return false;
    },
});

This is a common pattern I've been seeing in recent tutorials.

Instead of giving you a complete app in the beginning and breaking it down, the authors take an iterative approach and build the app piece by piece, which is what you normally would do if you were to build the app.

So it works perfectly as a tutorial. Just be patient until the end :)

UPDATE: Th forgot password form is not showing up because it is supposed to be within a template called main as seen in this code:

<template name="main">
    {{> alert}}
    {{#unless resetPassword}}
        {{#unless currentUser}}
            {{#unless showForgotPassword}}
                {{> signIn}}
                {{> signUp}}
            {{else}}
                {{> forgotPassword}}
            {{/unless}}
        {{else}}
            {{> signOut}}
        {{/unless}}
    {{else}}
        {{> resetPassword}}
    {{/unless}}
</template>

and the following helper takes the session paramater and feeds it to the unless block:

Template.main.helpers({
    showForgotPassword: function() {
        return Session.get('showForgotPassword');
    }
});

but your code does not have that main template, instead you wrapped your code in a generic div and you also seem to have changed some other portions of the code.

<div id="topbar">
            {{> signOut}}
     {{#unless resetPassword}}
         {{#unless currentUser}}
             {{#unless showForgotPassword}}
             {{else}}
                  {{> forgotPassword}}
             {{/unless}}
         {{else}}
          {{/unless}}
     {{else}}
         {{> resetPassword}}
     {{/unless}}
    </div>

Therefore, you can either use the original code from the tutorial, or if you really want to change that code, you can wrap your topbar div with a main template as seen in the original code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top