Error extending third party library class 'Record' in Typescript & Nativescript v3

nativescriptcore

#1

I am having issues in extending a third party library class Record in TypeScript + Angular v4 + Nativescript v3.

It reports:
Uncaught (in promise): TypeError: Cannot read property '__extended' of undefined or
System.err: Error: Can not extend an already extended native object.

How when I use Javascript’s Record.extend({}), it seems to work fine.

What am I missing here?


#2

i tried to follow following reference, but apparently no success here.

https://docs.nativescript.org/runtimes/android/generator/extend-class-interface


#3

Can you point give a link or something, which third party class it is - Record? Also the code you are using to extend.


#4

Manoj,

Record is a class in js-data library: http://api.js-data.io/js-data/3.0.0-alpha.19/Record.html

Below is the TypeScript code:

import {
Mapper,
Record,
Schema,
utils
} from 'js-data’
import { store } from “…/store”;

class UserClass extends Record {
}

export const facilityInventoryItemMapper = store.defineMapper(‘user’, {
endpoint: ‘users’,
recordClass: UserClass
}

Note, ‘recordClass’ attribute which will wrap the UserClass in mapper for active record.

Actually the issue happens in TypeScript compilation. If I use javascript extend below, it works fine.

let UserClass = Record.extend({}) // This works fine. Nativescript Typescript compiled version above doesn’t.


#5

Error seems to be due to Nativescript runtime environment. Please note errors in “ts_helpers.js:57:15”. Please see screen shot of error.


#6

Another store.ts file code that you need to reproduce the issue in Nativescript + Angular project.
Just install ‘js-data’ and ‘js-data-http’ dependencies in package.json to reproduce the issue:

/// store.ts
import {
DataStore,
Mapper,
Record,
Schema,
utils
} from 'js-data’
import {HttpAdapter} from ‘js-data-http’

export const adapter = new HttpAdapter({
// http: HttpClient,
basePath: ‘http://localhost:8080/api’,
beforeHTTP: function (config, opts) {
config.headers || (config.headers = {});
config.headers.authorization = Bearer ${localStorage.getItem('token')};

// Now do the default behavior
return HttpAdapter.prototype.beforeHTTP.call(this, config, opts);

}
})
export const store = new DataStore({})

store.registerAdapter(‘http’, adapter, { default: true })


#7

@zeeshan I am unsure what JavaScript library’s functionality you are trying to use, but .extend({}) is reserved to NativeScript’s syntax for extending Android(Java) // iOS (I think) classes through JavaScript, and its incorrect usage is likely what is causing the error you are seeing.


#8

Hi @Pete.K if .extend({}) is reserved for extending Android (Java) classes through Javascript, then what’s the syntax for extending third party Javascript classes through Javascript in Nativescript?

Please elaborate the correct usage in this requirement, in which lets say you have to extend Record class from third party Javascript library (see above for details)?

What I want to work is this:

Class User extends Record { }
Where Record is third party library js-data's Javascript class as mentioned above.

P.S: extend({}) is btw working but class A extends B is not (which I want to work).


#9

The TypeScript class extends syntax should also work when extending non-Android projects, could you provide a sample project where the bug is reproducible?


#10

@Pete.K

I have prepared a sample nativescript project for you that reproduces the error at : https://github.com/zeesulehria/nativescript-extends-bug

The relevant code is in app/core/user.mapper.ts file and userMapper.createRecord() in app.component.ts file. Run the app will produce the error i mentioned above.

This issue is effecting entire application development. This pattern works fine in simple Angular web app. Kindly suggest a solution.

Regards,


#11

@zeeshan I checked your project, Record has a static method called extend (by it’s parent class Component in js-data). So Record.extend({}) should work for you, it doesn’t seem conflicting NativeScript’s extend in both Android and iOS.

You can even use the TypeScript’s extend syntax but I’m not sure what you might miss as the static extend method in Record may be doing something extra internally.

Coming to your typescript example while your constructor method is executed, this._mapper() still returns undefined so obviously it throws error. But in your JavaScript example your init method (where you have written similar contractor code) is never called. So it doesn’t sound meaningful to even compare them.


#12

@manojdcoder, @Pete.K

I even removed the constructor, but I still see the same error. Its as simple as this class User extends Record {} that produces this error.

How can I Typescript extend Record class in nativescript and avoid this error? Please suggest a way out of this.

I have updated git project after constructor removed.


#13

Hello! Any updates on this issue?
I have the similar error.