SPFx Bing Maps Callback Issue

Copper Contributor

Hi everyone, I've created a custom SPFx webpart with React which allows me to display multiple locations using Bing Maps (the out-of-the-box Bing Maps webpart only accepts a single location).

 

I'm using the Bing Maps V8 web control where you specify a callback function as part of the URL to the script, which gets called when the Bing resources have finished loading. This then allows you to construct the map and render it on the page. Show in the Microsoft docs here…

https://docs.microsoft.com/en-us/bingmaps/v8-web-control/creating-and-hosting-map-controls/setting-m...

 

It's working almost perfectly but I've come up against an issue when my custom webpart is placed on the same page as Microsoft's Bing Maps webpart. The Microsoft webpart appears to be overriding my callback, meaning it never gets called and doesn't load. See below the CallbackOnLoad property of Window.Microsoft.Maps.

 

My callback registeredMy callback registered

 

Callback overriddenCallback overridden

 

For some context here is my function which adds the Bing maps script. I have a couple of global variables which help me ensure it's only loaded once even if there's multiple custom webparts on the page. The callback iterates through each instance of my custom webpart, updating its state and causing it to re-render.

 

private loadBingMaps(): void {
    webpartsWaitingForBingMapsToLoad.push(this);
    if (!bingMapsIsLoading) {
      bingMapsIsLoading = true;
      this.loadScript(scriptUrl);
      let browserWindow = window as any;
      browserWindow.customMapBingMapsCallback = (() => {
        MicrosoftBingMapsWebControl = browserWindow.Microsoft;
        webpartsWaitingForBingMapsToLoad.forEach((webpart: React.Component<ICustomMapProps, ICustomMapState>) => {
          webpart.setState({
            bingScriptLoaded: true
          });
        });
        bingMapsIsLoading = false;
      });
    }
  }

  private loadScript(url: string): void {
    const script = document.createElement("script");
    script.type = "text/javascript";
    script.async = true;
    script.defer = true;
    script.src=url;
    document.getElementsByTagName("head")[0].appendChild(script);
  }

 

Can anyone think of a solution to this? I don't really want to tell my users they can't use the two webparts together :)

 

Thank you, Adam.

 

6 Replies

Hi @Adam Reid ,

I think (but I'm not sure), there is some conflicts because of oob Bing webpart and Bing Maps Web Control use same sdk calls and same approach, and they live in the same page context.

What about use instead Isolated webpart? could it be a workaround?

From page point of view, it is an iFrame, and it could solve your problems.

The scope of isolated webpart is another (security API) but you can easly try.

I"f you're upgrading an existing SharePoint Framework project to v1.8.0 and want to use the isolated permissions capability, you can do it, by setting in the config/package-solution.json file, the isDomainIsolated property to true. You should ensure, that your project contains only web parts."

 

Cheers,

Federico

Hi Federico, thanks for your reply. I'll have a closer look at the isolated webpart. Assume I'll have to implement my own security as I'll loose access to SharePoint http client? I'll weigh up the pros and cons and if I get anywhere with it I'll report back.

Cheers, Adam

Hi @Adam Reid ,

sorry you don't tag me, I don't see your reply :)

What do yo mean about "Assume I'll have to implement my own security as I'll loose access to SharePoint http client?"  

While using isolated webpart, you have already access to SharePoint context, and every other context you need. Isolated webpart it is simply an iFrame in another dns domain, but always on SharePoint context. You need to pay attention to UI approach, because your webpart live inside an iFrame, so you could meet some trouble.

Cheers,

Federico

Sorry @Federico Porceddu :)

 

Thanks for clarifying this...I was under the impression I would lose the SharePoint context inside the iFrame but it's good to know this isn't the case.

 

You mention I could encounter some issues; is there anything obvious I should be aware of?

 

Thanks again, Adam.

Hi @Adam Reid 

I mean usual trouble in UI when you embed iFrames like resize, reload, mobile

etc.

You can already try to use (it is just a flag in config.json) so you 

can see what I mean :)

Please refer to https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/isolated-web-parts for architectural point of view, and come back if you have any questions :)

Cheers

Federico

Thanks @Federico Porceddu. I've now tried this and can confirm it does solve my original issue.

 

Unfortunately, as you suspected, I've come up against some of the issues relating to it being in an iFrame such as unpredictable property panes, css issues, unwanted white space and general slowness. I think I'm going to revert back to what I had before and live with the original limitation than with these issues.

 

Thanks for your help anyway, I learned something new :)

Adam