Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extends typescript library with javascript

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: '&copy; <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?

like image 659
Zeno Trevisan Avatar asked Apr 28 '18 08:04

Zeno Trevisan


People also ask

Can you use JavaScript libraries with TypeScript?

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 .

What does TypeScript add to JavaScript?

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.

How do I use TypeScript extends?

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.

How do you use extends in JavaScript?

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.


2 Answers

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)

like image 55
Sean F Avatar answered Oct 22 '22 14:10

Sean F


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: '&copy; <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.

like image 24
Gaurav Paliwal Avatar answered Oct 22 '22 14:10

Gaurav Paliwal