I am writing an AngularJS app (v1.3.15) using TypeScript 1.5 in Visual Studio 2013. I have run across a problem with TypeScript object properties/accessors and JSON serialization using $http.post(). My AngularJS is pretty solid I think but I am quite new to TypeScript.
My TypeScript class looks like this:
module Wizard.Models {
import Address = Wizard.Models.Address;
"use strict";
export class YourDetailsModel {
public useSecondaryAsPrimary: boolean;
private _primaryFirstName: string;
private _primaryLastName: string;
private _primaryAddressModel: Address = new Models.Address();
get primaryFirstName(): string {
return !this.useSecondaryAsPrimary ? this._primaryFirstName : this.SecondaryFirstName;
}
set primaryFirstName(primaryFirstName: string) {
this._primaryFirstName = primaryFirstName;
}
get primaryLastName(): string {
return !this.useSecondaryAsPrimary ? this._primaryLastName : this.SecondaryLastName;
}
set primaryLastName(primaryLastName: string) {
this._primaryLastName = primaryLastName;
}
get primaryAddressModel(): Address {
return !this.useSecondaryAsPrimary ? this._primaryAddressModel : this.SecondaryAddressModel;
}
set primaryAddressModel(primaryAddressModel: Address) {
this._primaryAddressModel = primaryAddressModel;
}
public SecondaryFirstName: string;
public SecondaryLastName: string;
public SecondaryAddressModel: Address = new Models.Address();
}
}
My intention is that when the object is serialized, all the public members and properties via accessors should be serialized, and the private properties should not. The current behaviour is that some of the private members are being serialized whereas some of the public members are not.
Is this asking too much? There are other ways for me to achieve this so it's not the end of the world if I can't get it working. I don't actually need to fiddle with the model class in this way.
But it's the most elegant way of keeping the model playing its cards close to its chest, so to speak.
Any help appreciated. M.
Is this asking too much? There are other ways for me to achieve this so it's not the end of the world if I can't get it working. I don't actually need to fiddle with the model class in this way
There is no runtime difference between a private and a public member. That is to say that the JavaScript emitted for each is exactly the same.
I suggest using a variable naming convention on top of private/public e.g. public foo and private _foo. Then during serialization you can check if a property name starts with _.
Related
I'm using Nodejs, Typescript, Postgres and TypeORM. Since it's a collaborative project, I'm aiming to protect the data that shouldn't be changed by making all my class properties private.
#Entity("Car")
export class Car {
#Column({ name: "name"})
private _name: string;
....
When I search in my database for a Car which have a specific name, I receive this error message : "Property "name" was not found in "Car". Make sure your query is correct."
My only way to solve this problem is to make my properties public or readonly (but sometimes I need to change the value of the property and readonly doesn't allow it so I cannot use it).
Cannot we not use Typeorm with private Typescript properties ?
The properties of your Entity should be public, since you would use them to query your data and to store information in the database (you can check the docs in order to understand the concept better). You can use the façade pattern, in case you want to expose certain data of your API if you really need to, or you can try to add getters and setters to the class, in order to manipulate such values indirectly. For example:
#Entity("Car")
export class Car {
#Column({ name: "name"})
private _name: string;
....
public setName(name: string) {
this._name = name;
}
public getName(): strintg {
return this.name
}
You really shouldn't take this approach and follow what's stablished on the docs. However, if you decide to take it, try to avoid using TS getters and setters since they have additional implications.
I'm new to TypeScript world, and I've seen examples with this to deal with injected objects and set it to a property of the component (this.anything)
First with public and setting by hand to this.nav
export class XPTO {
constructor(public nav: NavController) {
this.nav = nav;
}
}
and this, with private
export class XPTO {
constructor(private nav: NavController) {
//this.nav is nav?
}
}
in both cases after construct the object this.nav is a NavController object.
What are the differences of both implementations? Or this is the same when compiled to plain javascript?
Actually in your first example the explicit assignment is not needed at all:
export class XPTO {
constructor(public nav: NavController) {
// This line is not required.
// this.nav = nav;
this.someFunction();
}
someFunction(){
console.log(this.nav); // Prints out the NavController.
}
}
Whenever you specify public or private on a constructor parameter a corresponding public/private variable is created on the class and filled with the value of the parameter.
So really, the only difference of the two code samples is that one is private and the other one is public.
The resulting JavaScript will be the same. However, the compiler will throw an error, if you are trying to access private variables in your code.
public and private, as a lot of Typescript features, are only TypeScript modifiers. I'm not sure the compiler names these variables exactly the same, but from a JavaScript point of view, the code will be essentially the same.
The interest of Typescript is to give you features like type checking, it doesn't necessarily always modifies the outputted code.
Is there a way to make property as public in Destructuring for constructors?
Supposed to be there are many properties in Person Class.
Instead of
// to create a Person. new Person('')
class Person {
constructor(public name: string) {
}
}
I want to use destructuring to pass object as constructor parameter and make properties as public.
//new Person({name: ''})
class Person {
constructor({
public name: string //Is there a workaround here?
}) {
}
}
Is there a workaround here?
No currently that is not possible but there is an active discussion around this on this GitHub issue
I have a ManagedBean with a property which gets its value from an EJB. In the JSF, I have a Javascript variable which then gets its value from the ManagedBean property. When I run the project, the Javascript variable is not set.
In the ManagedBean, I tried the below methods but doesn't work:
setting the property's value in the Constructor
setting the property's value in an init() method with the #PostConstruct annotation
setting it in the getMenuData() method.
JSF JavaScript
<script>
YAHOO.util.Event.onDOMReady(function ()) {
// Data to build the menubar
var menuData = [#{userMenu.menuData}];
...
});
</script>
ManagedBean
package com.qrra.PROFIT.web;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import qrcom.profit.ejb.UserMenuFacade;
#ManagedBean
#ViewScoped
public class UserMenuController {
public UserMenuController() {
menuData = usermenu.buildMenuDataByUserProfile("UAT");
}
// #PostConstruct
// public void init() {
// menuData = usermenu.buildMenuDataByUserProfile("UAT");
// }
public void getMenuData() {
return this.menuData;
}
public void setMenuData(String menuData) {
// usermenu.buildMenuDataByUserProfile("UAT");
this.menuData = menuData;
}
private String menuData;
#EJB
private UserMenuFacade usermenu;
}
When I view source, I only see var menuData = [];
Is there a workaround to this?
The constructor approach would fail because it's impossible to inject an EJB in the instance before the instance is constructed, you'd only face a NullPointerException as the EJB is null. The #PostConstruct approach should work fine. The business-logic-in-getter approach will also work fine, but it is plain bad design.
Provided that you're properly preforming the job in the #PostConstruct, your code looks fine. Your concrete problem suggests that usermenu.buildMenuDataByUserProfile("UAT"); just returns an empty string by itself and thus your concrete problem needs to be solved at higher level. You should already have determined it by yourself with help of a debugger and common sense.
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.