madsem
madsem

Reputation: 81

JS this.function is not a function in promise

I'm trying to process a queue, in which I'm calling a class function that is querying an api. But no matter what I try, I get the error

Uncaught (in promise) TypeError: this.getVisitorData is not a function

This is my queue in index.js

# index.js
(async (ppc) => {

    const lander = new landingPage();

    // run the queued calls from the snippet to be processed
    for (let i = 0, l = ppc.queue.length; i < l; i++) {
        await lander.queue.apply(ppc, ppc.queue[i])
    }

})(window.ppc)

This is the class landingPage queue method:

# landing_page.js
// process window.pcc queue
    async queue(method, value, data) {

        if (method === 'init') {

            config.propertyId = value

        } else if (method === 'event') {

            // Do no track if visitor opted out
            if (!await optOut()) {
                new ppcEvent(value, data)
            }

        } else if (method === 'options' && value === 'visitor') {

            const data = await this.getVisitorData()
            this.customizeLander(data)
        }
    }

And this is the class landingPage method to query the api

# landing_page.js
async getVisitorData() {
        const key = 'landing_page_customization'
        let visitor = helpers.isset(window.sessionStorage.getItem(key))

        if (!visitor) {
            try {
                const [geo, device] = await axios.all([axios.get(config.geoEndpoint), axios.get(config.deviceEndpoint)]);

                const visitor = {
                    ...geo.data,
                    ...device.data,
                }

                window.sessionStorage.setItem(key, JSON.stringify(visitor))

                return visitor

            } catch (err) {
                console.log(err.message);
            }
        }

        return JSON.parse(window.sessionStorage.getItem(key))
    }

I even tried removing the async from visitorData, but I'm seeing the same error then. What am I doing wrong here?

Upvotes: 1

Views: 914

Answers (1)

Barmar
Barmar

Reputation: 781741

The first argument to apply() is the value that should be this in the function being called. Since queue is a method of the landingPage class, you should pass an instance of that class as the first argument. Apparently ppc is not a landingPage, but lander is. So change the line to

await lander.queue.apply(lander, ppc.queue[i])

You can also use ES6 spread notation instead of apply:

await lander.queue(...ppc.queue[i]);

Upvotes: 3

Related Questions