I'm working with Ionic 3 to build a simple map application, in order to present the map I'm using leaflet (typed version) with the OpenStreet map tiles
I want to give the possibility to the user to download and cache the map, thus I found leaflet-offline here and wanted to use it since it allows me to use my localstorage to store the images.
Now my problem arise with the fact that I'm trying to mix typescript with javascript and I can not figure out how to make it work correctly.
What I have done and what is the problem:
I installed leaflet typed version and then leaflet-offline javascript version.
Now I imported them as follows inside my page:
import * as leaflet from 'leaflet';
import 'leaflet-offline';
Now if I try to use the library as explained in the example I get a typescript error which indicates me that the property offline is not in the object TileLayer.
leaflet.tileLayer.offline('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', tilesDb, {
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
subdomains: 'abc',
minZoom: 13,
maxZoom: 19,
crossOrigin: true
}).addTo(this.map);
In order to avoid this I added
export namespace tileLayer {
function wms(baseUrl: string, options?: WMSOptions, offline?: any): TileLayer.WMS;
function offline(url?: any, tilesDb?: any, options?: any): any;
}
the function offline
is in the namespace of tileLayer itself.
Current problem At the moment when I try to run the application everything works fine except for the actual map, I can't see it and the error that I get when I look into it is the following:
ERROR TypeError: Cannot read property 'then' of null at NewClass.getTileUrl (vendor.js:163411) at NewClass.createTile (vendor.js:163389) at NewClass._addTile (vendor.js:79419) at NewClass._update (vendor.js:79310) at NewClass._setView (vendor.js:79171) at NewClass._resetView (vendor.js:79129) at NewClass.fire (vendor.js:68787) at NewClass._move (vendor.js:72343) at NewClass._onZoomTransitionEnd (vendor.js:72800) at NewClass._catchTransitionEnd (vendor.js:72732)
I'm sure I'm doing some stupid mistake, but I lost a lot of time on this issue.
Anyone have some clue on how to go solve this?
The short answer is definitely YES ! but you need some intermediate steps ! Please note that ,you can write plain old JavaScript in a TypeScript project without any problems since JavaScript is a subset of TypeScript ,you only need these steps if you are planning to use an external JavaScript library with TypeScript .
TypeScript is a superset of typed JavaScript (optional) that can help build and manage large-scale JavaScript projects. It can be considered JavaScript with additional features like strong static typing, compilation, and object-oriented programming.
Just like object-oriented languages such as Java and C#, TypeScript classes can be extended to create new classes with inheritance, using the keyword extends . In the above example, the Employee class extends the Person class using extends keyword.
The extends keyword is used to create a child class of another class (parent). The child class inherits all the methods from another class. Inheritance is useful for code reusability: reuse properties and methods of an existing class when you create a new class.
You can see in the source https://github.com/robertomlsoares/leaflet-offline/blob/master/src/TileLayer.Offline.js
that you fail at:
var resultPromise = this._tilesDb.getItem(dbStorageKey).then(function (data) {
So the call to
_tilesDb.getItem(dbStorageKey)
is returning null, at which point the code tries to call 'then' on null.
Since the tilesDB is something that you are supposed to be providing yourself, you can put a breakpoint in your getItem function to see what is going on. At some point you are returning null from your getItem function.
What getItem is supposed to do:
// return Promise that has the image Blob/File/Stream.
The key supplied to getItem is the url you supplied with a regex substitution applied to it (see _getStorageKey in same source file)
Cannot read property 'then' of null
Typescript gives this error when then
receives null
from the function it's applied on. So check that you are not missing return statement if your function is custom.
Now instead of adding layer to map directly at the time of say initialization. for that try to replace your existing code with
const offlineLayer = leaflet.tileLayer.offline('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', tilesDb, {
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
subdomains: 'abc',
minZoom: 13,
maxZoom: 19,
crossOrigin: true
});
offlineLayer.addTo(this.map)
check the reference of the map either this.map
or whatever the refernce in your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With