@nsw.io/data
Version:
This library is useful for easily extracting data out of an expression. It indeed uses [JSONata](https://docs.jsonata.org/overview) library but is wrapped to produce a simpler format/raw data.
191 lines (163 loc) • 4.51 kB
Markdown
# Miner
This library is useful for easily extracting data out of an expression. It indeed uses [JSONata](https://docs.jsonata.org/overview) library but is wrapped to produce a simpler format/raw data.
## Examples
Simple Query
```ts
// given
const data = { test: 'foo' };
const field = 'test';
// when
const result = await miner(data, field);
// then
expect(result).toEqual('foo');
```
Nested Objects
```ts
// given
const data = { test: { test2: 'foo' } };
const field = 'test';
// given
const result = await miner(data, field);
// then
expect(result).toEqual({ test2: 'foo' });
```
Arrays
```ts
// given
const data = { test: [{ myField: 'foo' }, { myField: 'bar' }] };
const field = 'test.myField';
// given
const result = await miner(data, field);
// then
expect(result).toEqual(['foo', 'bar']);
```
Arrays with Filters
```ts
//given
const data = {
test: [
{ category: 'a', myField: 'foo' },
{ category: 'b', myField: 'bar' },
{ category: 'b', myField: 'baz' },
],
};
const field = 'test[category="b"].myField';
// when
const result = await miner(data, field);
// then
expect(result).toEqual(['bar', 'baz']);
```
Complex Queries
```ts
//given
const data = {
test: [
{ category: 'a', myField: 1 },
{ category: 'b', myField: 2 },
{ category: 'b', myField: 3 },
{ category: 'b', myField: 4 },
],
};
const field = '$sum(test[category="b" and myField>2].myField)';
// when
const result = await miner(data, field);
// then
expect(result).toEqual(7);
```
## What is this useful for?
Imagine you have an angular application where you need to render a list of information out of your complex data (tables, lists, summaries). With this tool you can create now an angular pipe
```ts
(name="extract")
export class Extract implements PipeTransform {
transform(data:Record<string, unknown>, field: string): unknown {
return miner(data, field)
}
}
```
Now in your html you can do
```html
<div *ngFor"let item of elements">
<div class="card">
<h1>item | extract: 'product.name'</h1>
<h2>item | extract: 'product.price' | currency<h2>
</div>
<div>
<div class="total">{{ {data:elements} | extract: '$sum(elements.price)' | currency }}</div>
```
And it becomes real useful when you don't now what you are displaying. Or your fields are "dynamic"
Let's say we have a database/document that contains the fields we are displaying in a table
```ts
({
selector:'my-table',
template: 'my-table.html'
})
class MyTable {
columnsResolver = inject(ColumnsResolverService)
dataResolver = inject(MyDataResolver)
columns$: Observable<Column[]>
data$: Observable<Column[]>
ngOnInit() {
this.columns$ = this.columnsResolver.get()
this.data$ = this.dataResolver.get()
}
}
```
Now the HTML
```html
<table *ngIf="columns$ | async as columns">
<tr>
<th *ngFor="let col of columns">
{{col.header}}
<th>
<tr>
<ng-container *ngIf="data$ | async as elements">
<tr *ngFor="let element of elements">
<td *ngFor="let col of columns">
{{element | extract: col.field}}
<td>
</tr>
<ng-container>
</table>
```
And just like that you have a dynamic table based on a set of configurations, as you can see, you don't need to know the column header/fields values NOR structure, as long as `field` contains the proper JSONata expression.
This means that if you have complex data like
```json
{
"Account Name": "Firefly",
"Order": [
{
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Description": {
"Width": 300,
"Height": 200,
"Weight": 0.75
},
"Price": 34.45,
"Quantity": 2
},
{
"Product Name": "Trilby hat",
"ProductID": 858236,
"Description": {
"Width": 300,
"Height": 200,
"Weight": 0.6
},
"Price": 21.67,
"Quantity": 1
}
]
},
]
}
```
You could navigate through all the levels of your information as long as the field passed to the miner is well/properly formatted. For more information about JSONata expression, visit their site at [docs.jsonata.org](https://docs.jsonata.org/overview)
# Contributing
## Building
Run `nx build data` to build the library.
## Running unit tests
Run `nx test data` to execute the unit tests via [Jest](https://jestjs.io).