Ad
Bing Map Component In React
I want create component to show bing map in React.js with TypeScript.
I know that there is very component in github for this purpose. but I want create this component from scratch for myself.
I created class in react and in componentWillMount
function injected script tag to head
of my html:
componentWillMount() {
const script = document.createElement("script");
var scriptURL = "<script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?key=" + this.props.apiKey + "' ></script>";
const scriptText = document.createTextNode(scriptURL);
script.appendChild(scriptText);
document.head.appendChild(script);
}
when I want create map followed by this document
in componentDidMount
function like this:
componentDidMount() {
var map = new Microsoft.Maps.Map(this.mapElement);
}
I get this error:
Cannot find name 'Microsoft'.
how to I should import 'Microsoft' module to my component?
Ad
Answer
Here is a minimalist implementation of React BingMaps component without any dependencies to BingMaps type definitions.
First a service for loading BingMaps API and Microsoft
type are introduced:
export interface MapWindow extends Window {
Microsoft: any;
}
declare let window: MapWindow;
export let Microsoft: any;
export function loadBingApi(key?: string): Promise<void> {
const callbackName = "bingAPIReady";
let url = `https://www.bing.com/api/maps/mapcontrol?callback=${callbackName}`;
if (key) {
url += `&key=${key}`;
}
return new Promise((resolve, reject) => {
const script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.defer = true;
script.src = url;
window[callbackName] = () => {
Microsoft = window.Microsoft;
resolve();
};
script.onerror = (error: Event) => {
reject(error);
};
document.body.appendChild(script);
});
}
Here is a Map component which accepts mapOptions as a props:
interface IMapProps {
mapOptions?: any;
}
export default class BingMap extends React.Component<IMapProps, any> {
private mapRef = React.createRef<HTMLDivElement>();
public componentDidMount() {
loadBingApi().then(() => {
this.initMap();
});
}
public render() {
return <div ref={this.mapRef} className="map" />;
}
private initMap() {
const map = new Microsoft.Maps.Map(this.mapRef.current);
if (this.props.mapOptions) {
map.setOptions(this.props.mapOptions);
}
return map;
}
}
Usage
<BingMap
mapOptions={{
center: [47.60357, -122.32945],
credentials:
"--BingMaps key goes here--"
}}
/>
Ad
source: stackoverflow.com
Related Questions
- → Import statement and Babel
- → should I choose reactjs+f7 or f7+vue.js?
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → .tsx webpack compile fails: Unexpected token <
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → React Native with visual studio 2015 IDE
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM
- → How do I determine if a new ReactJS session and/or Browser session has started?
- → Alt @decorators in React-Native
- → How to dynamically add class to parent div of focused input field?
Ad