2

I am using following environment

NodeJS: 5.7.1

Mongo DB: 3.2.3

MongoDB (NodeJS Driver): 2.1.18

TypeScript: 1.8

I have created an Object using Typescript as

class User {
  private _name:string;
  private _email:string;
  public get name():string{
    return this._name;
  }
  public set name(val:string){
    this._name = val;
  }
  public get email():string{
    return this._email;
  }
  public set email(val:string){
    this._email = val;
  }
}

Using mongodb driver API, I am trying to insert object as

var user:User = new User();
user.name = "Foo";
user.email = "foo@bar.com";
db.collection('users').insertOne(user)
.then(function(r){..}).catch(function(e){..});

When I query from mongo console, to check the values inserted, using db.users.find({}).pretty();

it gives me following output.

{
"_name":"Foo",
"_email":"foo@bar.com",
"name":"Foo",
"email":"foo@bar.com"
}

Why the private variables are getting stored? How can I prevent it from storing private variables.

EDIT: 1 Since, I couldn't stop developing the application, I have used a workaround for the time being. The domain object now has an additional method toJSON which provides the structure, which I wish to store in MongoDB. e.g.

public toJSON():any{
return {
"name":this.name
...//Rest of the properties.
};
}

I am calling toJSON() on composed object as well.

CuriousMind
  • 3,143
  • 3
  • 29
  • 54
  • 2
    Private variable is the same as public variables when compiled to js for performance reason. http://stackoverflow.com/questions/12713659/typescript-private-members – Zen May 12 '16 at 11:48
  • So what is the recommended approach to insert only public variables? – CuriousMind May 12 '16 at 12:55

1 Answers1

2

To really control things, I suggest to have a method in each of your persistable objects which returns the data you want to save for that object. For example:

class User {
    private _name: string;
    private _email: string;

    public get name(): string{ 
        eturn this._name;
    }

    public set name(val: string) {
        this._name = val;
    }

    ublic get email(): string{
        return this._email;
    }

    public set email(val: string){
        this._email = val;
    }

    public getData(): any {
        return {
            name: this.name,
            email: this.email
        }
    }
}

You probably have more than just the User that you want to persist, you can make things a bit more generic:

interface PersistableData {}

interface Persistable<T extends PersistableData> {
    getData(): T;
}

interface UserPersistableData extends PersistableData {
    name: string;
    email: string;
}

class User implements Persistable<UserPersistableData> {
    // ...

    public getData(): UserPersistableData {
        return {
            name: this.name,
            email: this.email
        }
    }
}

You then just do:

db.collection('users').insertOne(user.getData())
Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299