Search code examples
javascriptexpresspug

Calling javascript function on load pug - setting localStorage with param


What I am attempting to do is invoke a JS function from a pug template that will set an item on the localStorage. The value of this item will be a param that was passed to the pug template "token".

Similar questions have been asked in the past and I took inspiration from these answers as they seem to be similar:

My resulting code is:

users.js

import setToken from "../src/setToken";

router.post("/signin", (req, res) => {
    ...

    cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: function(result) {
            res.render("congrats", {
                title: "Congrats",
                token: result.getAccessToken().getJwtToken(),
                setToken: setToken
            });
        },
        onFailure: function(err) {
            next(err);
        }
    });
});

setToken.js

export default (token) => {
    console.log("::: setToken :::");
    localStorage.setItem("cognitoToken", token);
};

congrats.pug

extends layout

block scripts
    script
        |   var setToken = #{setToken};
        |   setToken(#{token})

block content
    ...

layout.pug includes a client-side JS script which also has a function storeToken. I have attempted to call that as well but nothing .

Nothing is output to the console and nothing is set in localStorage. I am unsure if this is the best way to even achieve this but it appears my JS is not even being executed.

Is it also best practice to pass this function reference through when rendering the template or to include it on the client?

EDIT

When looking in the markup, I can see that my JS is rendering correctly within the <script> of my template:

<script>
    console.log("token: ", **token value**);
    var setToken = function (token) {
        console.log(&quot;::: setToken :::&quot;);
        localStorage.setItem(&quot;cognitoToken&quot;, token);
    };
    setToken(**token value**)
</script>

EDIT 2

I have 4 pug pages that I load sequentially depending on the stage the user is at registering for Cognito. I have tested injecting JS into the other 3 templates and all of that code works fine. For example:

block scripts
    script(type="text/javascript")
        |   var page = "confirm";

I can then call page in the console which prints out "confirm". I try the same variable declaration in my congrats.pug and returns undefined. So, I imagine, this has something to do with how I render the pages. Here's the comparison of 1 that works and the 1 that doesn't. I cannot see any difference here (extension of users.js):

/*
 * Works
 */
router.post("/confirm", (req, res, next) => {
    const { confirm } = req.body;

    cognitoUser.confirmRegistration(confirm, true, function(err, result) {
        if (err) {
            next(err);
        }
        res.render("signin", {
            title: "Signin"
        });
    });
});
//////////

/*
 * Doesn't work
 */
router.post("/signin", (req, res) => {
    const { username, password } = req.body;
    const authenticationData = {
        Username: username,
        Password: password
    };
    const authenticationDetails = new AuthenticationDetails(authenticationData);

    cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: function(result) {
            res.render("congrats", {
                title: "Congrats",
                token: result.getAccessToken().getJwtToken(),
                setToken: setToken
            });
        },
        onFailure: function(err) {
            next(err);
        }
    });
});
//////////

Solution

  • In the end, for some reason it was the fact that I passed a function reference to my template the way I did. If I take that out, JS worked as it should.

    Setting the token, I decided it was too much overhead & added complication to call a function in an external file so just did it directly within a <script> tag within the template. Here is my resulting working template:

    extends layout
    
    block scripts
        script(type="text/javascript").
            var token = "#{token}";
            localStorage.setItem("cognitoToken", token);
    
    block content
        .container
            .col-md-6.mx-auto.text-center
                .header-title
                h1.wv-heading--title= title
            .row
                .col-md-4.mx-auto
                    p You have successfully authenticated with AWS Cognito, your access token is
                        strong #{token}
    

    Credit to this answer which showed me how to reference a pug param within a <script> tag