Ads SDK: ads is not shown when call OwAd from remounted component

Related app/team name (not a must if you want to keep it private): Trucky Overlay but reported from others too (see Slack https://overwolfdevs.slack.com/archives/C2NP5F4BV/p1605906365457400)
Issue Description:
It’s a React app. I have a top level Component (DesktopWindow) containing multiple components. One of them, Profile, contains an ad container. When the component is mounted, initialize the AD SDK injecting it into the body and wait for onload. At onload, call new OwAd with the container to show the ad.
It works.
If i move to another component, e.g. GamesList, so the Profile component, is unmounted and the new one is mounted, when i back to Profile component, so is remounted, calling again new OwAd doesnt show the ad, simply does nothing.

I’ve tried to call removeAd when the Profile component is unmounted or defining a new random container id each time the Profile component is mounted but without results.

It seems there is some kind of limitations to show again an Ad in the same page once the Ad SDK is loaded.

Can you reproduce it (exact steps to reproduce): see above

Impact for my app: [e.g. x% of the users complained about it, it’s a show-stopper]: High, losing ads view
Do you currently have a workaround?
No

See the working code:

Profile.js componentDidMount:

var adDivId = ‘ad-div-’ + Math.random();

 this.adsService = new AdsService({
                    adContainer: adDivId, enableDevelopmentAd: config.ENABLE_TEST_AD, adUnit: AdsUnit.TESTING["400x300_Video"], autoShowAd: true,
                    onAdRemoved: () => this.setState({ adLoaded: false }),
                    onAdRefreshed: () => this.setState({ adLoaded: true }),
                    onDisplayAdLoaded: () => {
                        this.setState({ adLoaded: true })
                    }
                });

Profile.js componentWillUnmount

componentWillUnmount() {

    this.adsService.removeAd();

    this.adDivContainer.current.innerHTML = "";

}

my AdsService implementation:

I don’t have anything to add except a +1 that this is affecting my app as well. I’m using the test ad becuase we’re not at a point of release yet. My implementation for ads is slightly different, but more or less identical in concept to what @dowmeister posted.

Hi @dowmeister , and thanks for the feedback.

We will check the issue and we will update you here.

Thanks.

As shared by Gilmat via DM, i’ve discovered it’s “by design”. The new OwAd() must be called only once per page load.

For me, at implementation level, this is clearly wrong: if i can instance a new object, i expect this object is locally to the class i’m executing, not globally. Should be a singleton or global object or, at most, bound to window.

Furthermore, i’ve discovered the div id container must be the same across all component loads because it remains “saved” on the OwAd instance and, afaik, cannot change it.

The solution i’ve found, not elegant in frameworks like React, is to save the OwAd instance in the window object and then “recover” it from the window at next component load and then call the refreshAd()

Example:

if (typeof window.owAdReference == ‘undefined’) {

        this.owAd = new OwAd(document.getElementById(this.options.adContainer), adOptions);

        window.owAdReference = this.owAd;

    }

    else

    {

        truckyService.writeLog('Ad instance already defined in window, refreshing');

        this.owAd = window.owAdReference;

        this.refreshAd();

    }

IMHO, this behaviour should be changed.

@dowmeister, your feedback is essential, and we are always improving the API, and I agree that there is still room for more improvement in the Ads API, including some new features that will save you, as a dev, the need to implement the logic by yourself (for example - to implement the OwAd() as a singleton, etc.)

Anyway, the most important thing is that you found a solution. I remind you that our official recommendation for apps is to use the background controller as a service bus and a router of information between your app’s windows.