I'm using Bing maps v8 to do geocoding. at first this code was not in a class. I've ended up adding the code in a class, because of this error:
typescript cannot redeclare block-scoped variable 'map'
Because I'm using a class now I'm having problems with 'this.'. After reading about 'this' in TypeScript, I've changed my functions using Instance functions (instance arrow functions):
/// <reference path="./../scripts/MicrosoftMaps/Microsoft.Maps.d.ts" />
/// <reference path="./../scripts/MicrosoftMaps/Modules/Search.d.ts" />
/// <reference path="./../scripts/typings/jquery/jquery.d.ts" />
class BMGeocode {
map: Microsoft.Maps.Map;
searchManager: Microsoft.Maps.Search.SearchManager;
public loadMap = () => {
this.map = new Microsoft.Maps.Map('#map', {
credentials: 'xxx',
center: new Microsoft.Maps.Location(51.087299, 2.976770),
zoom: 10
});
}
public search = () => {
if (!this.searchManager) {
Microsoft.Maps.loadModule('Microsoft.Maps.Search', function () {
this.searchManager = new Microsoft.Maps.Search.SearchManager(this.map) ; // PROBLEM: searchManager is never set?
});
}
// remove any previous results from the map.
this.map.entities.clear();
// get the users query and geocode it.
let query: string = (<HTMLInputElement>document.getElementById("txtInput")).value;
this.geocodeQuery(query);
}
private geocodeQuery = (query: string) => {
var userData = { name: 'Maps Test User', id: 'XYZ' };
let searchRequest: Microsoft.Maps.Search.IGeocodeRequestOptions = {
where: query,
userData: userData,
count: 5,
bounds: this.map.getBounds(),
callback: function (r: any) {
// PROBLEM: r undefined.
if (r && r.results && r.results.length > 0) {
var topResult = r.results[0];
if (topResult) {
this.addPin(topResult.location);
$('#txtInput').focus().select();
}
}
},
errorCallback: function (e: any) {
// If there is an error, alert the user about it.
alert("No results found.");
}
};
// make the geocode request:
this.searchManager.geocode(searchRequest);
}
// .. other stuff in class
}
let geo: BMGeocode = new BMGeocode();
function onGeocodeClick() {
geo.search();
}
$(function() {
geo.loadMap();
$('#geocode').click(onGeocodeClick);
})
I think I've detected the problem why it doesn't work, as the searchManager is always null or undefined. However I don't know how to solve it.
This line from the 'search' function works but doesn't seem to set the searchManager variable:
this.searchManager = new Microsoft.Maps.Search.SearchManager(this.map);
the searchManager is not set, so I can't make a request:
// make the geocode request:
this.searchManager.geocode(searchRequest);
How can this be solved in TypeScript?
Update: this doesn't seem to work either:
public search = () => {
if (!this.searchManager) {
var self = this;
Microsoft.Maps.loadModule('Microsoft.Maps.Search', function () {
self.searchManager = new Microsoft.Maps.Search.SearchManager(self.map); // PROBLEM!!
self.search();
});
} else {
// remove any previous results from the map.
this.map.entities.clear();
// get the users query and geocode it.
let query: string = (<HTMLInputElement>document.getElementById("txtInput")).value;
this.geocodeQuery(query);
}
this.searchManager = new Microsoft.Maps.Search.SearchManager(this.map) ;noImplicitThisflag, which will help flag places where you may be losing a reference tothis.