[![Build Status](https://scrutinizer-ci.com/g/Rebolon/json-reviver/badges/build.png?b=master)](https://scrutinizer-ci.com/g/Rebolon/json-reviver/build-status/master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Rebolon/php-sf-flex-webpack-encore-vuejs/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/Rebolon/php-sf-flex-webpack-encore-vuejs/badges/quality-score.png?b=master) [![Known Vulnerabilities](https://snyk.io/test/github/rebolon/json-reviver/badge.svg?targetFile=package.json)](https://snyk.io/test/github/rebolon/json-reviver?targetFile=package.json)
When you work on a Frontend application with an API, you usually receive JSON string in HTTP. This is a pain to get back this JSON into real entities. And it's a worst pain when this JSON contain nested entities. This happens also when you try to restore JSON from LocalStorage !
So if you want to restore entities, with all their prototype, there is a lot to do. This is where this package can help you.
Install the package npm install @rebolon/json-reviver --save
For all required entities, just implements EntityInterface from this package (this is just for typings).
Then write a Reviver for all required entities. This reviver must extends ItemAbstractReviver or ListAbstractReviver (for entities that are just an association between different entities).
eg:
// json object restored from localStorage or received from API call
{
"book": {
"title": "Zombies in western culture",
"editors": [{
"publicationDate": "1519664915",
"collection": "printed version",
"isbn": "9781783743230",
"editor": {
"name": "Open Book Publishers"
}
}, {
"publicationDate": "1519747464",
"collection": "ebooks",
"isbn": "9791036500824",
"editor": {
"name": "Open Book Publishers"
}
}]
"serie": {
"name": "Open Reports Series"
}
}
}
// entities that represents a Book (for other entities look at tests/fixtures/entities folder
class Book implements EntityInterface {
id: number
title: string = ''
description?: string = ''
indexInSerie?: number
editors: Array<Editors>
serie?: Serie
addEdition(edition: Editors) {
if (typeof this.editors == 'undefined') {
this.editors = []
}
this.editors.push(edition)
}
setEdition(edition: Editors) {
this.editors = []
this.editors.push(edition)
}
}
// the reviver for the book
class BookReviver extends ItemAbstractReviver
{
protected editorsReviver
protected serieReviver
constructor (
editorsReviver: EditorsReviver,
serieReviver: SerieReviver
) {
super()
this.editorsReviver = editorsReviver
this.serieReviver = serieReviver
}
// The name of the node in the json string/object
getNodeName(): string {
return 'book'
}
// The entity for which the reviver works
getNewEntity(): Object {
return new Book()
}
// List of props (int, string, date, bool) of the entity
public getEzPropsName()
{
return ['id', 'title', 'description', 'indexInSerie', ]
}
// List of props that links to other entities (relations Many To Many)
// And configuration of how to restore them
public getManyRelPropsName(): Object
{
return {
'editors': {
'reviver': this.editorsReviver,
'setter': 'addEdition',
'cb': function (relation, entity) {
Accessor('book', relation, entity)
},
},
}
}
// List of props that links to other entities (relations Many To One)
public getOneRelPropsName(): Object
{
return {
'serie': {
'reviver': this.serieReviver,
'registryKey': 'serie',
},
}
}
}
// In your application you just have to do this to restore the entities:
// those 3 are mandatory for nested entities: Book constructor require SerieReviver and EditorsReviver, and the EditorsReviver nees EditorReviver to restore its own editor sub entity (have a look at tests/fixtures/reviver/library)
const editorReviver = new EditorReviver()
const serieReviver = new SerieReviver()
const editorsReviver = new EditorsReviver(editorReviver)
const bookReviver = new BookReviver(editorsReviver, serieReviver)
const bookReviver = new BookReviver()
const book = bookReviver.main(myJsonStringOrObject)
// you can now use all feature of Book entity from your `book` constant
You can also restore array of object like this (root node book
is not mandatory):
[{
"book": {
"title": "Zombies in western culture"
}
},
{ "book": {
"title": "Another book with Zombies in western culture"
}
]
Run npm run test
to execute the unit tests via Karma.
With typescript package it appears that .ts files should not be published (more info here:https://ljn.io/posts/publishing-typescript-projects-with-npm/). In fact we have to transpile .ts into javascript files. During this process we also need to generate module files (the famous .d.ts). Those files will be published and it will allow typescript compiler to use the .js file finely.
To do this: