Missing methods in TypeScript class - javascript

I have a TypeScript model which contains properties and functions like:
class Person {
name: string
sayHello(){ console.log(name); }
}
When creating its instance I can make use of this sayHello() method as expected.
The problem comes when I store and get the object from the local storage or an external web service.
While the properties are still present the methods have disappeared. (obviously because it’s just text).
Is there any way to restore the completeness of the object to be able to use its functions?
Or otherwise, is there any other technique? For instance, helper class that can work with type.

When you save to a local storage, you will save a JSON representation of the class data; when you get the object back from the local storage, it will be just an object, not an instance of the original class.
You can look for an external library that will help you with this, but the simple solution is to create a new instance of the class and assign the field values to the class using Object.assign:
class Person {
public constructor(public name?: string){}
sayHello() { console.log(name); }
}
let p = new Person("Test");
let data = JSON.stringify(p);
let p2 = new Person()
Object.assign(p2, JSON.parse(data));

Related

Access Javascript class fields in class methods

Opposed to my expectation I can't access my class field myLibrary in the class method initialize().
class ViewController {
myLibrary = new Library();
initialize() {
console.log(myLibrary); // undefined
The only "solution" I found was to declare myLibrary outside of the class as a global variable. Is there a way to declare fields in a class and then, well, use them?
JavaScript classes do not work the same way as Java classes.
To access properties on an object you need to state the object and then access a property on it. They aren't treated as variables in the current scope.
Inside a method, the keyword this will give you the associated object. (See How does the "this" keyword work? for a less simplified explanation).
So you need this.myLibrary instead of just myLibrary.
class Library {
…
}
class ViewController {
constructor() {
this.myLibrary = new Library();
}
log() {
console.log(this.myLibrary);
}
}
const viewController = new ViewController();
viewController.log()

Get the string name of an anonymous object type?

I have a common provider for many of my backend controllers that looks like this:
#Injectable()
export class CommonMasterdataProvider<T> {
private readonly route:string = '/api/';
constructor(private http:HttpClient) {
this.route = this.route + T.name; //?? What can I use to get the type name here?
}
I can inject this into my component controllers but it would be nice if I can get the name of the anonymous type name. Basically I'm looking for the TypeScript version of the c# nameof() operator. Or a Javascript way but it has to work even after minifying code.
I have tried adding a new string parameter to the constructor but this way the Angular injector thrown an exception that it couldn't find anything for the type String.
AFAIK, the generic piece (T) does not get transpiled into JavaScript, so it actually does not exist. This means you won't be able to work with T directly, except as an 'interface' so to speak.
Is there a way you can pass an instance of T or the T's constructor to the constructor of CommonMasterdataProvider ? That way you will be able to get the name.

AngularJS: Use DTO models

Is there a way to have a DTO.
So on my back-end part I have a pretty clear domains, e.g. Client.
class Client {
protected $firstName;
protected $lastName;
}
In fact it is a class, that contain specific properties. I want to have something similar on my front-end part. I want to be sure that the object came to a function is an instance of Client and I can refer to specific Client properties.
Another question - is it an appropriate approach to organize AngularJS (1.5.9) application?. Would it decrease application performance?
P.S. I want to get something like this on my front-end part
function someFunc(client) {
if (!(client instanceof Client)) {
// handle error
}
// here I can refer to client.firstName or client.lastName and not get undefined, as long as it is a required Client properties
}
Thank you!
Javascript is an untyped language. Put that simply, you cannot achieve what you want.
A workaround could be to add a method getType() in your Client class with an Enum returned and check that field in Angular.
If you want instead a "typed" version of JS check TypeScript.
as of ES6 you can use classes and do something like this
var Animal = {
speak() {
console.log(this.name + ' makes a noise.');
}
};
class Dog {
constructor(name) {
this.name = name;
}
}
// If you do not do this you will get a TypeError when you invoke speak
Object.setPrototypeOf(Dog.prototype, Animal);
var d = new Dog('Mitzie');
d.speak(); // Mitzie makes a noise.
check out MDN docs for further details,
MDN - Classes,
MDN - instanceof

how to add function to an object in javascript that can access its variables

I am trying to do some javascript test driven development, and would like to replace a dao with a mock one.
Lets say I have an object myObject that has a private var dao that I would like to create a setter for:
var dao = new RealDao();
function funcUsesDao() {
dao.doStuff();
}
Then in another file I have a handle to an instance of this object and want to add a setter so I can do the following:
var mockDao = {function doStuff() { /*mock code */}};
myObject.setDao(mockDao);
myObject.funcUsesDao(); should use mock dao
Environment specifics are this is node.js and the object I have a handle to is obtained by doing var myObject = require('../myObject');
You would use a constructor for the class, setting the dao to RealDao and then in the setDao you would set that dao to the new dao. Alternately in the constructor you would put a reference to dao, and on null, assign it to a new RealDao(). (at least, that's been my understanding of how people generally assign new interfaces for testing .. via the constructor)
//something like this
function Dao(interface){
this.dao = interface || new RealDao();
}
Otherwise, what you listed above is accurate. you just have to provide the setDao method as you indicated in your code.

Qt programming: How to use custom data type in QVariantMap?

I am writing a Qt app that maps a C++ class to Javascript object in QtWebkit. Firstly let me explain what I am trying to do:
I have a class inherited from QObject:
class myobj : public QObject {
Q_OBJECT
public:
myobj();
~myobj();
pulbic slots:
void getData();
}
And in another class I tried to add myobj instances to QVariantMap:
QVariantMap anotherClass::getObj() {
myobj* obj1 = new myobj();
myobj* obj2 = new myobj();
QVariantMap items;
items.insert(QString("0"), QVariant(*obj1));
items.insert(QString("1"), QVariant(*obj2));
return items;
}
And then I got the following error:
error: no matching function for call to ‘QVariant::QVariant(myobj&)’
So I tried to add declarations:
Q_DECLARE_METATYPE(myobj);
But I got:
error: ‘QObject::QObject(const QObject&)’ is private
Any idea about this?
Like the compiler said, no constructor of QVariant exists that take a myobj as parameter. Have you tried to use the qVariantFromValue function instead?
I think this is what you are searching for.
If you register your custom type with Q_DECLARE_METATYPE(myobj), your class needs a public default constuctor (ok), a public destructor (ok) and a public copy constructor (MISSING which the error message is telling you), see the documentation.

Categories