svelte - using a nested json array with an Each function - arrays

I am using cordova-sqlite-porter to export an SQLite table to JSON and then use the JSON exported using svelte.
My code to export the json is:
let myDB = '';
let vetdrugs = [];
myDB = window.sqlitePlugin.openDatabase({ name: "vetcalculators.db", iosDatabaseLocation: "Documents" });
var successFn = function(json, count){
vetdrugs = JSON.stringify(json);
};
cordova.plugins.sqlitePorter.exportDbToJson(myDB, {
successFn: successFn,
dataOnly:true,
tables:['vetADrugs']
});
The resulting JSON is:
{
"data":{
"inserts":{
"vetADrugs":[
{
"drugradio":"single",
"druglabel":"ml",
"conc3":null,
"Id":2,
"dose":10,
"conc1":null,
"maximum":null,
"desc":"",
"title":"Test0",
"notes":"",
"minimum":null,
"conc":100,
"drugconc":"mg/ml",
"conc2":null
},
{
"drugradio":"single",
"druglabel":"ml",
"conc3":null,
"Id":3,
"dose":10,
"conc1":null,
"maximum":4,
"desc":"",
"title":"Test1",
"notes":"",
"minimum":2,
"conc":100,
"drugconc":"mg/ml",
"conc2":null
},
{
"drugradio":"single",
"druglabel":"ml",
"conc3":null,
"Id":4,
"dose":10,
"conc1":null,
"maximum":4,
"desc":"",
"title":"Test2",
"notes":"",
"minimum":2,
"conc":100,
"drugconc":"mg/ml",
"conc2":null
},
{
"drugradio":"single",
"druglabel":"ml",
"conc3":null,
"Id":5,
"dose":10,
"conc1":null,
"maximum":4,
"desc":"",
"title":"Test3",
"notes":"",
"minimum":2,
"conc":100,
"drugconc":"mg/ml",
"conc2":null
}
]
}
}
}
Unfortunately, the JSON is exported as:
{
"data":{
"inserts":{
"vetADrugs":[]...
And I am not able to export it as just:
{
"vetADrugs":[]...
Normally, in svelte I would use an each function like this:
{#each vetADrugs as drugs}
{drugs.title}
{/each}
But I am not sure how to incorporate the "data" and "inserts" part of the JSON into each function. Any help would be appreciated!
ADDENDUM:
I did try the following with no luck:
{#each vetdrugs.data.inserts.vetADrugs as drug}
<p>
{drug.title}
</p>
{/each}

You can use dot notation in the each block.
{#each data.inserts.vetADrugs as drug}
<p>
{drug.title}
</p>
{/each}

Related

push object in array ngFor

I need to push object in ngFor but I got error Property 'push' does not exist on type 'Observable<MyDataType[]>'.
Stackblitz demo code
HTML
<div *ngFor='let item of myObservableArray | async'>
{{item.value}}
</div>
Component
getData() {
if (!this.myObservableArray) {
this.myObservableArray = this.myService.getData();
this.myObservableArray.push({"id":3, "value":"value_4"});
}
}
Service
mydata: MyDataType[] = [
{"id":1, "value":"value_1"},
{"id":2, "value":"value_2"},
{"id":3, "value":"value_3"}
];
getData():Observable<MyDataType[]>
{
let data = new Observable<MyDataType[]>(observer => {
setTimeout(() => {
observer.next(this.mydata);
}, 4000);
});
return data;
}
}
Demo I added one more method to service to add or update.
addOrUpdate(item:MyDataType){
var elem=this.mydata.find(element=> element.id==item.id);
if(elem){
elem.value=item.value;
}
else{
this.mydata.push(item);
}
}
and call it inside component
this.myService.addOrUpdate({"id":3, "value":"value_4"});

how to dynamically parse Json data using reactjs

I have a requirement to determine a generic standard approach to read the JSON data ( should be able to read any JSON structure) and display in reactjs page.
I know that if we know JSON structure, we can traverse through it and display the data in the page accordingly. But here JSON structure
should be dynamically determined via code and we should not code specifically for each JSON structure.
For example, I have given Sample1.json and Sample2.json files below. My program should be able to parse Sample1.json if I use it and display
them on the page. If I use Sample2.json, still it should be able to parse them and display the data dynamically. We should not have
code specifically like archive_header.tracking_id or stock_ledger_sales_key.version_number...etc.
Can someone please let me know how to handle this scenario?
Sample1.json
{
"archive_header": {
"tracking_id": "914553536-FRM01-20163609140455-000000001",
"archived_timestamp": "2018-05-08T09:14:04.055-05:00"
},
"journal_record_key": {
"location_number": "389234",
"dept_number": "28822"
},
"journal_record_detail": {
"financial_from_item_number": "771",
"financial_to_item_number": "771"
}
}
Sample2.json
{
"stock_ledger_sales_key": {
"version_number": "12",
"account_month_number": "01",
"account_year_number": "2016"
},
"stock_ledger_sales_detail": {
"mature_increase_mtd_percentage": "1.2",
"mature_increase_stdt_percentage": "2.3",
"mature_increase_ytd_percentage": "2"
}
}
You can just iterate over the keys recursively:
function recursively_iterate(object, parent_name="") {
output = ""
for (key in Object.keys(object)) {
if (typeof object[key] == "object") {
output = output + recursively_iterate(object[key], key)
}
output = output + parent_name + "." + key + ": " + object[key] + "\n"
}
return output
}
To display the information as you said, we can do something like this:
const jsonDOM = json => {
return Object.keys(json).map(key => {
return Object.keys(json[key]).map(child => {
return (<div>
<p>{child}</p>
<p>{json[key][child]}</p>
</div>
);
});
});
};
return (<div>
<h2>JSON 1</h2>
{jsonDOM(json1)}
<h2>JSON 2</h2>
{jsonDOM(json2)}
</div>
);
Here is the live demo
Hope it helps :)
You can use JSON.stringify and <pre> tag to output any json you like.
const sample1 = {
archive_header: {
tracking_id: "914553536-FRM01-20163609140455-000000001",
archived_timestamp: "2018-05-08T09:14:04.055-05:00"
},
journal_record_key: {
location_number: "389234",
dept_number: "28822"
},
journal_record_detail: {
financial_from_item_number: "771",
financial_to_item_number: "771"
}
};
const sample2 = {
stock_ledger_sales_key: {
version_number: "12",
account_month_number: "01",
account_year_number: "2016"
},
stock_ledger_sales_detail: {
mature_increase_mtd_percentage: "1.2",
mature_increase_stdt_percentage: "2.3",
mature_increase_ytd_percentage: "2"
}
};
class App extends React.Component {
render() {
return (
<div>
<h3>sample1</h3>
<pre>
<code>{JSON.stringify(sample1, null, 2)}</code>
</pre>
<h3>sample2</h3>
<pre>
<code>{JSON.stringify(sample2, null, 2)}</code>
</pre>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Convert json Array to Object on Vue Js 2

I'm trying to convert my data json from an array to an object to be able to consume the data but something went wrong...
Here is the data json sample:
[
{
"id": 1,
"title": "my title",
"imgHero": "../../path/hero.jpg"
}
]
And here is the Vue component:
<template>
<div class="hero">
<img :src="blog.imgHero" alt="hero image" class="heroImg">
<h3 class="heroTitle">{{ blog.title }}</h3>
</div>
</template>
<script>
import tripsJson from '#/data/trips.json'
export default {
name: 'App',
data () {
return {
array: tripsJson,
blog: {}
}
},
created () {
var obj = this.array.reduce(function (acc, cur, i) {
acc[i] = cur
return acc
}, {})
this.blog = obj
console.log(this.blog)
}
}
</script>
Any help or suggestion is more than welcome. Thx

Angular2 removing duplicates from an JSON array

I have a problem with filter in my JSON array when I move my app to Angular2 . In Angular 1.x that was easier. I used 'unique' in filter and this remove all duplicates.
apps:
{"app":"database_1",
"host":"my_host1",
"ip":"00.000.00.000"
},
{"app":"database_1",
"host":"my_host1",
"ip":"00.000.00.000"
},
{"app":"database_2",
"host":"my_host2",
"ip":"00.000.00.000"
},
{"app":"database_2",
"host":"my_host2",
"ip":"00.000.00.000"
}
Part of html code:
<div *ngFor='#appsUnique of apps '>
<div class="row dashboard-row">
<div class="col-md-2">
<h4>{{appsUnique.app }}</h4>
</div>
</div>
</div>
And result is:
database_1
database_1
database_2
database_2
I want to get result:
database_1
database_2
How can I remove duplicates from an array?
Mybe it can help you
myList = ["One","two","One","tree"];
myNewList = Array.from(new Set(myList ));
I have a solution for this problem :)
Array.from(new Set([{"app":"database_1",
"host":"my_host1",
"ip":"00.000.00.000"
},
{"app":"database_1",
"host":"my_host1",
"ip":"00.000.00.000"
},
{"app":"database_2",
"host":"my_host2",
"ip":"00.000.00.000"
},
{"app":"database_2",
"host":"my_host2",
"ip":"00.000.00.000"
}].map((itemInArray) => itemInArray.app)))
More about Array.from & Set
Thanks all for help :)
You could use following method:
names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
ngOnInit() {
let filteredNames=this.remove_duplicates(this.names);
console.log(filteredNames);
console.log(this.names);
}
remove_duplicates(arr) {
let obj = {};
for (let i = 0; i < arr.length; i++) {
obj[arr[i]] = true;
}
arr = [];
for (let key in obj) {
arr.push(key);
}
return arr;
}
Hope this helps.
You could use Observable approach as well, It is very simple.
let filteredData = [];
let arrayData = [{
"app": "database_1",
"host": "my_host1",
"ip": "00.000.00.000"
},
{
"app": "database_1",
"host": "my_host1",
"ip": "00.000.00.000"
},
{
"app": "database_2",
"host": "my_host2",
"ip": "00.000.00.000"
},
{
"app": "database_2",
"host": "my_host2",
"ip": "00.000.00.000"
}];
Observable.merge(arrayData)
.distinct((x) => x.app)
.subscribe(y => {
filteredData.push(y)
console.log(filteredData)
});
instead of looping over the normal json array, you can create another array in your corresponding typescript class, and alter this as you see fit. In your html, you can then have the following
html
<div *ngFor='let appsUnique of filteredApps'>
<div class="row dashboard-row">
<div class="col-md-2">
<h4>{{appsUnique.app }}</h4>
</div>
</div>
</div>
Next, you need this filteredApps array in your corresponding typescript class.
typescript
let filteredApps = [];
and in a function you can then create that filteredApps, for example in the onInit method.
onInit()
{
filteredApps = // filter logic
}
You will need trackBy.
Try with:
*ngFor="#appsUnique of posts;trackBy:appsUnique?.app"
Hope it helps.

How to select objects that have a certain atribute in a json file in an Angular JS project?

I have a link to an API which lists movies, each movie has title,id etc...
API: http://private-5d90c-kevinhiller.apiary-mock.com/angular_challenge/horror_movies
It also has an offers array inside which contains a 'provider_id' property.
I need to show how many movies are available at which provider.
But I dont know how, the best I came up with was:
{{movie.offers[0].provider_id}}
But that only shows the first provider on each movie.
What I want is to extract how many movies each provider has.
My Html:
<div ng-controller="ProviderController as provider">
<div ng-repeat="movie in provider.movies">
{{movie.offers[0].provider_id}}
</div>
</div>
My Main.js:
app.controller('ProviderController', function($http) {
var provider = this;
provider.movies = [];
$http({
url: 'some/path/horror_movies',
method: "GET",
}).success(function(data) {
provider.movies = data;
});
});
Also this is the structire of the json file:
[{
"id": 140524,
"title": "Dracula Untold",
"offers": [{
"provider_id": 2,
"retail_price": 14.99,
//...
}, {
"provider_id": 2,
"retail_price": 14.99,
}, {
"provider_id": 7,
"retail_price": 14.99,
}, ]
},
{
"id": 138993,
"title": "The Purge: Anarchy",
"offers": [
// ...
]
},
]
Any ideas ? Thanks.
You will need to change the structure of your database to have providers at the top level. A function achieving something like this should iterate over every movies offers, something like this:
function getProviders (movies) {
var providers = [],
movie = {},
offer = {};
for (var i = 0, max = movies.length; i < max; i += 1) {
movie = movies[i];
for (var j = 0; j < movies[i].offers.length; j += 1) {
offer = movie.offers[j];
if (typeof providers[offer.provider_id] === 'undefined') {
providers[offer.provider_id] = { movies: [] };
}
providers[offer.provider_id].movies.push(movie);
}
}
return providers;
}
I started a fiddle here: http://jsfiddle.net/d29tu8fg/1/
Before adding a movie to a provider, you might also want to check, if that movie already exists. You only need to do that though, if – like in your data – a movie can have two different offers from the same provider.
Add the providers to the $scope and in your view show the length:
<div ng-repeat="provider in providers track by $index">
{{provider.movies.length}}
</div>

Resources