2

I have the following typescript model object user

export class User {

constructor(
    private _name: string,
    private _email: string
)  {}


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

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

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

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

}

I store the object via this code:

let user = new User('myName', 'myEmail');
localStorage.setItem('user', JSON.stringify(user));

If I look into the local storage there is the following string:

{"_name":"myName","_email":"myEmail"}

How do I get the user object again?

let user: User = JSON.parse(localStorage.getItem('user'));
console.log(user.name); // logs undefined. Should log 'myName'
console.log(user._name); // this logs 'myName'. But according to the typescript documentation this should NOT work!

I guess this has something to to with the underscores the object is stored with. How can I receive the object correctly?

Rose Nettoyeur
  • 885
  • 1
  • 16
  • 29
  • `JSON.parse` returns plain js object (not of type `User`). You should create `User` instance manually and initialize it. [This](http://stackoverflow.com/questions/38100853/typescript-deserializing-json-into-collection-with-multiple-types/38104840#38104840) might be helpful. – Aleksey L. Jul 15 '16 at 16:34

2 Answers2

2

You need to implement some serialize and deserialize methods in your model.

class User {
    static public deserialize(serialized) {
        const {name, email} = JSON.parse(serialized);
        return new User(name, email);
    }    

    constructor(
        private _name: string,
        private _email: string
    )  {}


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

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

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

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

    public serialize() {
        return JSON.stringify({name: this.name, email: this.email});
    }

}

let user = new User('myName', 'myEmail');
localStorage.setItem('user', user.serialize());

let user1: User = User.deserialize(localStorage.getItem('user'));
Maxx
  • 1,740
  • 10
  • 17
0

Thanks to this answer to another post, I came up with this solution based on JSON.parse()'s reviver parameter:

const data = JSON.parse(json, function (key, value) {
    if (key.startsWith('_')) {
        this[key.slice(1)] = value
        return
    }
    return value
})

This works the other way around too with JSON.stringify()'s replacer parameter.

Note that the callback won't work with an arrow function since they don't have their own binding to this

johnnyBoy
  • 115
  • 2
  • 12