简体   繁体   中英

Why can't I pass functions from Express.js to EJS like I pass other variables?

I am working on a blogging application (click the link to see the GitHub repo) with Express , EJS and MongoDB.

Trying to paginate the posts I got stuck with passing newerPosts and olderPosts to the view. I am passing them just like the posts variable (and other variables):

exports.getPosts = async (req, res, next) => {
    //pagination params
    var perPage = 10;
    var currPage = req.body.page ? parseInt(req.body.page) : 1;

    const newerPosts = function() {
        currPage = currPage + 1;
        console.log(currPage);
    }

    const olderPosts = function() {
        currPage = currPage - 1;
        console.log(currPage);
    }

    const posts = await Post.find({}, (err, posts) => {
            if (err) {
                console.log('Error: ', err);
            } else {
                res.render('default/index', {
                    moment: moment,
                    layout: 'default/layout',
                    website_name: 'MEAN Blog',
                    page_heading: 'XPress News',
                    page_subheading: 'A MEAN Stack Blogging Application',
                    posts: posts,
                    newerPosts: newerPosts,
                    olderPosts: olderPosts
                });
            }
        })
        .sort({
            created_at: -1
        })
        .skip((currPage - 1) * perPage)
        .limit(perPage)
        .populate('category');
};

In the view:

    <div class="px-1">
        <a class="btn btn-primary" href="#" onclick=<%="olderPosts()"%>>&larr; Older Posts</a>
    </div>

     <div class="px-1">
        <a class="btn btn-primary" href="#" onclick=<%="newerPosts()"%>>Newer Posts &rarr;</a>
     </div>

Yet, I get the Uncaught ReferenceError: newerPosts is not defined error message from the browser.

What am I doing wrong? What is the closest working alternative?

You can do the following: make a new ejs file called functions.ejs :

<script>
  function test(){console.log(1)}
</script>

and then use <%- include('functions'); %> <%- include('functions'); %> inside the template you are rendering. Use it at the start so that the function is defined when calling it.

In the corresponding route, use:

res.render('default/index', {
  ...,
  name: 'test'
});

Inside your template can do the following:

<button onclick="<%=name%>()"> <%= btnText %> </button>

BUT, when I look at the function you want to pass, I see that you want to change the state of your application by using currPage = currPage + 1; . This wont work, since as soon as the page is rendered there is no reference to currPage in the html anymore, cause everything is static html by then.

If you want to change pages etc. you will need to implement some frontend logic.

Check this one:

const posts = await Post.find({}, (err, posts) => {
xxxx ... res.render()
})

I think here you need to make some changes in the logic of Promise usage... Think about - what happens if error appears? where you handle it? and more interesting - after promise return result - where you exit from your function? ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM