Json parse localstorage typescript

TypeScript types serialisation/deserialization in localstorage

I have a Typescript app. I use the localstorage for development purpose to store my objects and I have the problem at the deserialization. I have an object meeting of type MeetingModel:

export interface MeetingModel < date: moment.Moment; // from the library momentjs >

I store this object in the localStorage using JSON.stringify(meeting) . I suppose that stringify call moment.toJson(), that returns an iso string, hence the value stored is: <"date":"2016-12-26T15:03:54.586Z">. When I retrieve this object, I do:

const stored = window.localStorage.getItem("meeting"); const meeting: MeetingModel = JSON.parse(stored); 

The problem is: meeting.date contains a string instead of a moment ! So, first I’m wondering why TypeScript let this happen ? Why can I assign a string value instead of a Moment and the compiler agree ? Second, how can I restore my objects from plain JSON objects (aka strings) into Typescript types ? I can create a factory of course, but when my object database will grow up it will be a pain in the *** to do all this work. Maybe there is a solution for better storing in the local storage in the first place? Thank you

@suraj Thanks ! It answers my 2nd question ! I will fix my code asap. Any idea regarding my first question ?

IndexedDB stores actual JS objects, and is keyed/indexed for efficiency. However, you will still have to rehydrate your objects somehow.

2 Answers 2

1) TypeScript is optionally typed. That means there are ways around the strictness of the type system. The any type allows you to do dynamic typing. This can come in very handy if you know what you are doing, but of course you can also shoot yourself in the foot.

What is happening here is that the number 1 is casted to any , which to TypeScript means it will just assume you as a developer know what it is and how you to use it. Since the any type is then assigned to a string TypeScript is absolutely fine with it, even though you are likely to get errors during run-time, just like when you make a mistake when coding JavaScript.

Of course this is by design. TypeScript types only exist during compile time. What kind of string you put in JSON.parse is unknowable to TypeScript, because the input string only exists during run-time and can be anything. Hence the any type. TypeScript does offer so-called type guards. Type guards are bits of code that are understood during compile-time as well as run-time, but that is beyond the scope of your question (Google it if you’re interested).

2) Serializing and deserializing data is usually not as simple as calling JSON.stringify and JSON.parse . Most type information is lost to JSON and typically the way you want to store objects (in memory) during run-time is very different from the way you want to store them for transfer or storage (in memory, on disk, or any other medium). For instance, during run-time you might need lookup tables, user/session state, private fields, library specific properties, while in storage you might want version numbers, timestamps, metadata, different types of normalization, etc. You can JSON.stringify anything you want in JavaScript land, but that does necessarily mean it is a good idea. You might want to design how you actually store data. For example, an iso string looks pretty, but takes a lot of bytes. If you have just a few that does not matter, but when you are transferring millions a second you might want to consider another format.

My advise to you would be to define interfaces for the objects you want to save and like moment create a .toJson method on your model object, which will return the DTO (Data Transfer Object) that you can simply serialize with JSON.stringify . Then on the way back you cast the any output of JSON.parse to your DTO and then convert it back to your model with a factory function or constructor of your creation. That might seem like a lot of boilerplate, but in my experience it is totally worth it, because now you are in control of what gets stored and that gives you a lot of flexility to change your model without getting deserialization problems.

Читайте также:  Максимальный размер экрана css

Источник

How to use localStorage in typescript?

For classes with methods you can try this: Question: I am working on a simple «Green Light, Red light» game using Angular, and I am storing players with their score and maxScore using localStorage. The problem is, when I click the button to add or remove a point, it deletes the whole array of players, and creates a new one like the following: I have been working for a couple of days with localStorage

How to use localStorage in typescript?

If I try to assign item (item is an object) to Product by the following code:

localStorage.setItem("Product",JSON.stringify(item)) 

Then Product does not get assigned to the item JSON string.

working demo to retrieve console.log(localStorage.getItem(«Product»));

Typescript — localStorage is not defined (Angular, npm i localstorage-polyfill —save. Step 2: Add these two lines in server.ts file: import ‘localstorage-polyfill’ global [‘localStorage’] = localStorage; Once you are done, run build command (eg: npm run build:serverless) All set now. Start the server again and you can see the issue is resolved.

Typescript local storage compatibility [duplicate]

Does Typescript somehow compatible with local storage ? I set item via:

 localStorage.setItem('someString', JSON.stringify(MyTypescriptObject)); 

which stores object as plain string. For example:

 private _id: string; get id(): string < return this._id; >set id(value: string)
return JSON.parse(localStorage.getItem('someString')); 

If they are not compatible, I don’t see any reason to use Typescript. Even worse, I have to rework all my current code in order to remove it.

The issue does not really have anything to do with local storage, you can save the class in the data in a JSON format, and then you have to restore the data to a new instance of the class.

Читайте также:  Php заполнить строку символами

You can easily add a constructor that takes the json object and applies it over the instance of the class:

class MyTypescript < constructor() constructor(id: string, name: string) constructor(data: Partial) constructor() < if (arguments.length == 1) < let data = arguments[0]; Object.assign(this, data); return >let let name = arguments[1]; this._id = id; this._name = name; > // Alternative to using a constructor, you can use MyTypescript.fromJson(data) public fromJson(data?: Partial) < var result = new MyTypescript(); Object.assign(result, data); return result; >private _name: string; private _id: string; get id(): string < return this._id; >set id(value: string) < this._id = value; >> var obj = new MyTypescript(); obj.id = "10"; var data = JSON.stringify(obj); var obj2= new MyTypescript(JSON.parse(data)); 

More generally if all you are looking is for an object to hold some data, an interface might be a better approach. In Typescript it is overkill to declare a class with properties for a simple data class, a common practice is to declare an interface and assign object literals to variables of that type. And that will work more seamless with JSON

interface MyTypescript < id: string; name: string >var obj : MyTypescript = < id: "10", name: "foo" >; var data = JSON.stringify(obj); var obj2: MyTypescript = JSON.parse(data); 

How can I access localstorage using typescript?, The 0.8.1 version of TypeScript has caused a bug in Web Essentials. There should be a fix in a few days. In the meantime, if you install the 0.8.0 version of TypeScript that works with the current version, or you can compile from command line: tsc —debug c:\myapp\app.ts. Share.

How to store and get an object without destroying the type in localStorage?

I’m working on an AngularJS project with TypeScript.

A person is an object of the Person class. I need to store person object in localStorage and retrieve it with its type.

window.localStorage can store only strings. You can use JSON to serialize your object and retrieve it back.

class Person < constructor(public name:string) < >> let person = new Person('Peter'); localStorage.setItem('person', JSON.stringify(person)); let personFromStorage = JSON.parse(localStorage.getItem('person')) as Person; console.log(< person: person, personFromStorage: personFromStorage >); 

While Martin’s answer works for classes without methods. For classes with methods you can try this:

let personFromStorage = JSON.parse(localStorage.getItem('person')) as Person; let person = new Person(''); Object.assign(person , personFromStorage); 

Typescript — using generics to for localstorage, Typescript — using generics to for localstorage. I’m using the following code set and get strongly typed item with local storage. The set works as expected and puts JSON into local storage. However, when getting the same item out, the casting to the generic type doesn’t seem to work. It doesn’t cause and exception …

Читайте также:  Java format date by pattern

How to edit a value in localStorage with TypeScript

I am working on a simple «Green Light, Red light» game using Angular, and I am storing players with their score and maxScore using localStorage.

I can already read each property from the array stored in the localStorage, but now I am stuck on modifying those values once I click a button.

This is the test array I am currently working with:

This array is stored with a single key named «players», so it is an array of players.

My component looks like this:

game.component.ts

export class GameComponentComponent implements OnInit < highScoreLS: number = this.getHighScoreData(); scoreLS: number = this.getScoreData(); highScore: number = 0; score: number = 0; state: string = 'RUN'; faArrowRightFromBracket = faArrowRightFromBracket; faShoePrints = faShoePrints; constructor() <>ngOnInit(): void <> addPoint() < this.score++; if (this.score >this.highScore) < this.highScore = this.score; >this.changeHighScore(); this.changeScore(); > removePoint() < this.score--; if (this.score < 0) < this.score = 0; >this.changeHighScore(); this.changeScore(); > changeState() < if (this.state === 'RUN') < this.state = 'PAUSE'; >else < this.state = 'RUN'; >> getScoreData() < let localStorageItem = JSON.parse(localStorage.getItem('players') || '[]'); let item = localStorageItem.find( (item: < name: string >) => item.name === 'test1' ); let sc = item.score; return sc; > getHighScoreData() < let localStorageItem = JSON.parse(localStorage.getItem('players') || '[]'); let item = localStorageItem.find( (item: < name: string >) => item.name === 'test1' ); let hs = item.maxScore; return hs; > changeHighScore() < let localStorageItem = JSON.parse(localStorage.getItem('players') || '[]'); let item = localStorageItem.find( (item: < name: string >) => item.name === 'test1' ); item.maxScore = this.highScore; localStorage.setItem('players', JSON.stringify(item)); > changeScore() < let localStorageItem = JSON.parse(localStorage.getItem('players') || '[]'); let item = localStorageItem.find( (item: < name: string >) => item.name === 'test1' ); item.score = this.score; localStorage.setItem('players', JSON.stringify(item)); > > 

And the html looks like this:

game.component.html

 
Hi! 👋

HIGH SCORE: >

>

SCORE: >

Left

The problem is, when I click the button to add or remove a point, it deletes the whole array of players, and creates a new one like the following:

I have been working for a couple of days with localStorage so I do not know exactly what I am missing or what I am doing wrong. My idea is to edit those values, score and maxScore , but I can’t figure it out how.

EDIT The first time I click on add a point, it edits only the maxScore, but once. The next time I click, it gives me this error:

ERROR TypeError: localStorageItem.find is not a function at GameComponentComponent.changeScore (game-component.component.ts:83:33) at GameComponentComponent.addPoint (game-component.component.ts:34:10) 

You’re calling localStorage.setItem with just the single item and not the whole array so every subsequent «finds» you’re trying will fail.

localStorage.setItem('players', JSON.stringify(localStorageItem)); 

Though I have to say, there’s loads of duplicate code in just that one component. You should read some articles on data structures and state management.

HTML5 localStorage useful Functions // JavaScript, Check if localStorage has an Item — TypeScript-Version /** * Check if localStorage has an Item / exists with the give key * @param key the key of the Item */ function localStorage_hasItem(key) < return localStorage.getItem(key) !== null; >Get the amount of space left in localStorage — TypeScript-Version Code samplevar localStorage_isSupported = (function ()

Источник

Оцените статью