Eric Mitjans
Eric Mitjans

Reputation: 2169

setInterval() still triggering after clearInterval() in NodeJS

I have the following code setting and clearing an interval inside a NodeJS script.

Starting interval works fine, but when trying to clear it, the stopping interval console will trigger, but the interval will continue firing every minute.

app.get("/api", async (req, res) => {

    active = req.query.active;
    
    let interval = null;

    if (active == "true") {

        console.log("starting interval");

        interval = setInterval(async function() {
            try {
                const Posts = await getPosts();
                const Comments = await getComments();
                sendPosts().then(() => sendComments());

            } catch (e) {
                throw e;
            };
        }, 60000);

        res.json({ reddit: subreddit, discordChannel: discordChannel, activated: true});

    } else {

        console.log("stopping interval");

        clearInterval(interval);
        interval = null;

        res.json({ reddit: subreddit, discordChannel: discordChannel, activated: false});
    }
    
});

What am I missing?

Upvotes: 0

Views: 383

Answers (2)

Mattias Martens
Mattias Martens

Reputation: 1647

You need to move "let interval" outside of the call to app.get().

Right now the variable is declared inside the closure of the function which means it gets initialized every time a request comes in.

If it's outside the function, the variable becomes part of the global scope and its value will be remembered between requests.

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 370689

Your interval variable is declared inside the route handler. Every time the route is called, a new interval variable is created. Reassigning that variable inside one invocation of the route does not change its value during other invocations of the route. You need:

let interval = null;
app.get("/api", async (req, res) => {
    // ...

You should also catch errors properly - your current approach will result in unhandled rejections here:

    interval = setInterval(async function() {
        try {
            const Posts = await getPosts();
            const Comments = await getComments();
            sendPosts().then(() => sendComments());

        } catch (e) {
            throw e;
        };
    }, 60000);

Only throw if there's something that can handle it up the call stack - if not, you should do whatever you reasonably can with the error at that point and stop without throwing.

Upvotes: 1

Related Questions