Load data from storage into class object (complex model)

Hello,

I have an object (the main one of my app) defined like this:

export class Recipe {
  name: string = "";
    
  type: Type = new Type();
  difficulty: Difficulty = new Difficulty();
  addicionalInfo : AdditionalInfo = new AdditionalInfo();

constructor() {
  }
}

And then I save them to localStorage with JSON.stringify.

How can I / What’s the best approach to load them back from storage?

That is, do the JSON.parse and when I do myobject.type it returns an object of my class Type, with it’s methods and so on.

Do I need to implement a load() method or is there something that will parse it?
I’ve searched this forum, angular docs and the web but found nothing…

Regards

This is indeed a interesting and new thing for JavaScript developers. What you are looking for is serialization and de-serialization. You can do it manually by either defining a method on the class to create new instances from existing data and one to export all class fields into a json doc or you simply use a module that handles this for you. I’ve tried cerialize and was quite happy. In provides nice decoraters.

What i would not do is to use the constructor for that since you might want to use him for something else. :slight_smile:

https://github.com/weichx/cerialize

BUT in the end i switched to redux. Which is a different and promising approach! There is already a localstorage save available to hold persist your store there. But a cleaner solution would be to store in in pouchdb or sqlite.

1 Like

Hi,

wow, thanks for your fast reply on this!
:wink:

I’ve tried to deserialize my raw JS object into my Recipe object.
It worked for all attributes except for an array:

@deserializeAs(Ingredient, 'ingredients') public ingredients: Array<Ingredient>;

I got no ingredients at all.
If I output the raw object, ingredients look like:

 ingredients : Array[2]
    0 : Object
    1 : Object
    length  :  2

What am I missing?
Will keep trying.

EDIT: OK, now I got the ingredients, but as a raw JS object and not as instances of my Class…

Changed the ingredients declaration in my Class to

@autoserialize ingredients: Array<Ingredient> = new Array<Ingredient>();

will keep trying again.

Try to provide more code to get better answers we need the class and the call.

Here is a snippet of mine (serializeAs is for correct pouchdb field naming)
Card.ts

  export class Card {
        @deserializeAs('_id') @serializeAs('_id') private _id:string;
        @deserializeAs('_rev') @serializeAs('_rev') private _rev:string;
        @deserializeAs('set') @serializeAs('set') private _set:string;
        @deserializeAs('type') @serializeAs('type') private _type:CardType;
        ...
    }

CardService.ts adding a card (from class to JSON)

   add(card:Card) {
        return this._db.post(Serialize(card));
    }

CardService.ts receiving a card (from JSON to Class):

getByCardId(id:string) {
    return this._db.get(id).then(card => Deserialize(card, Card))
}

E: for nested stuff: ( Class Member _result is Array of Results)

@deserializeAs(Result, 'results') @serializeAs(Result, 'results') private _results:Result[] = [];

Got it…

Damn, jus needed to read the documentation carefully.
On arrays we must specify the Type, like this:

@autoserializeAs(Ingredient) ingredients: Array<Ingredient> = new Array<Ingredient>();

Thanks again for your help! @CanKattw

You’re welcome! This is a really important thing in TypeScript. If you can spare some time do look at Redux and learn what immutability means. Especially when Ionic upgrades to the new router and you can timetravel trough the whole applications state. :slight_smile: