It's there a way to pass data between two plugin hook methods without using global variables?

NodeBB Plugins
  • I want to pass the return data from plugin.getPosts to plugin.getReplies, and both methods are hooks: that means both are receiving data from the hooks, so I can't just invoke the methods because the data received from the method overrides.

    I just want to filter some posts in getPosts method that I recieve from 'filter:post.getPosts' hook, and then pass the filtered data to getReplies method; this method is a hook too (filter:topics.getPostReplies); I want to do this because I want to compare the two data and return the result.

    I just can solve the problem creating a global variable and assing the filtered data from getPosts to it, and then use the data in getReplies, but I don't think its the optimal way.


  • @aisar-g using a global variable is actually very unlikely to work correctly.

    Can you describe more of what you're trying to do? What is the behavior you're trying to implement?

  • @pitaj Hello,

    I wan't to get all the posts from a topic when I enter the topic, that's why I'm using 'filter:post.getPosts' filter to push the posts to getPosts method.

    In the getPosts method, I filter the posts that I want the user to see: their own posts and the posts that other people reply him. So, let's say that I ended up with 4 posts from the original 10 posts.

    I can just use that data, but the "X Reply" counter in the posts is determinated by the 'filter:topics.getPostReplies' filter, so I need to filter the replies too. So I need to first get all the replies, and then filter them. I'm going to get all the replies with that hook using getReplies method.

    I want to pass the data returned by getPosts method to the getReplies method. That way I can using the posts I want to show to filter all the replies. The problem is that, If I invoke the getReplies method, the posts data that I pass, will be override with the replies that the hook pass it.

    I'm running out of ideas, like using getPostsByPids inside getReplies, but that way it gets to an infinite loop in the console, because i'm using filter:post.getPosts hook to filter the posts.

    The solution I found is passing the filtered posts to a global variable, an then using that variable in getReplies to filter the replies; but I think it can give memory leak problems.

    Thanks for helping me.

  • @aisar-g A global variable won't work because it would persist beyond the call, and you might run into issues where multiple users loading topics at the same time (especially in busy forums) may result in the mixing up of data, which is not good.

    What you want to do is save the results of getPosts to a variable local to your plugin, but inside of an identifier. Later on, in getReplies, you could refer to the cached information. e.g.

    const cache = {};
    getPosts = async () => {
        // your logic here...
       cache[some_identifier] = filteredPosts;
    getReplies = async () => {
        const posts = cache[some_identifier];
        // your logic hhere

    I would also recommend using lru-cache to maintain, so you can invalidate the results easily (or after maybe a couple seconds, even.)

  • @aisar-g I know what you're referring to, though. The ideal scenario would be saving stuff to res.locals and then referring to that data in getReplies.

    Unfortunately, neither of those hooks pass req or res, and while we were looking into something like that before (see: continuation-local-storage), it did not ultimately pan out.

Suggested Topics