B. Ma
B. Ma

Reputation: 231

Can a function access its variables from previous invocation?

I am little bit confused with scopes and async functions. I understand its cores but I don't know if my problem has anything to do with it, or it is something else. A created a custom plugin:

(function ($) {
    createCalendar = options => {
        let elementID = randomString(32);

        endLoad = () =>{
            console.log(elementID);
            $(`#${elementID} .inner .loader`).css('display', 'none');
        }

        [...]

        getTimes(url)
            .then((response) => {
                console.log(elementID);
                endLoad();
            })
    }
}(jQuery))

I invoke this function multiple times, because I create 4 or 5 calendars on a page. Each has a different ID. It's a 32 characters long string, so it's unlikely to be the same. In the function I call the getTimes async function and in its callback function I want to remove the loader in the calendar - each calendar has its loader. However, it only removes the last calendar's loader. If I try to log the element IDs, I get different results. The console.log in the then gives me correct value, so after rendering 5 calendars, and each has finished its loading, it logs 5 different strings. However just after this console.log has been executed comes the endLoad function, and it logs the same value - the last calendar's id for each calendar. I thought because the async getTimes function is is a function which has it's own scope and the variable is defined with let it cannot access the createdID from previous invoke which is theoretically a different function. Or does the the JS considers it the same function because the same function was called multiple times? Or my problem is rooted in somewhere else?

Upvotes: 0

Views: 82

Answers (1)

Cedric Cholley
Cedric Cholley

Reputation: 2043

When you declare a variable without any keyword (var, let, const) it becomes global (same as doing window.endLoad = …). In your case, for every calendar the variable endLoad is overwriten. You need endLoad to be scoped to the arrow function.

(function ($) {
    createCalendar = options => {
        let elementID = randomString(32);

        const endLoad = () =>{
            console.log(elementID);
            $(`#${elementID} .inner .loader`).css('display', 'none');
        }

        [...]

        getTimes(url)
            .then((response) => {
                console.log(elementID);
                endLoad();
            })
    }
}(jQuery))

Upvotes: 1

Related Questions