Dynamic table component that automatically list each property value of the current Object data iteration (ngFor directive); - html

Going to the point, I'm creating a table component that receives an Object containing all information that the dynamic table needs, including head information and so on. My mission is to make it possible for every row (data), my table doesn't need to know the property name, only list its value straight away.
I did some console tests and it seems to work around those lines:
const dataList = [
{ name: 'Eugene', age: 20, alive: true },
{ name: 'Game Master', age: 40, alive: false },
{ name: 'Camel', age: 22, alive: true }
];
for(let data of dataList) {
console.log("All data info");
console.log(data);
for(let propertyValue of Object.values(data)) {
console.log(propertyValue);
}
}
The Results:
VM1123:2 All data info VM1123:3 {name: 'Eugene', age: 20, alive:
true} VM1123:6 Eugene VM1123:6 20 VM1123:6 true
VM1123:2 All data info VM1123:3 {name: 'Game Master', age: 40,
alive: false} VM1123:6 Game Master VM1123:6 40 VM1123:6
false VM1123:2 All data info VM1123:3 {name: 'Camel', age:
22, alive: true} VM1123:6 Camel VM1123:6 22 VM1123:6
true
I'm trying to achieve the same result, but this time iterating between ngFor directive, like below:
<tr *ngFor="let data of tableConfig.data; let i = index">
<td *ngFor="let propValue of Object.values(data)"> {{ propValue }}</td>
But, the problem is that I can't access the 'Object' class inside the component HTML.
Property 'Object' does not exist on type 'PaginationTableComponent'.

Add method to get your object values like
getValues(data): any{
return Object.values(data);
}
In template :
<td *ngFor="let propValue of getValues(data)"> {{ propValue }}</td>
Demo

Related

Filter Data before Rendering Highcharts

I have a Highcharts Gantt chart which is pulling parsed JSON data from a MySQL table.
The data spans 4 years, but I need to filter it so that it only shows data for 2022.
The issue is that I cannot use the standard Highcharts data filter as it does not remove empty rows without any data.
I would like to filter the data before the chart is even rendered so that rows without bars are not shown at all. Is that possible?
It is really easy, you just need to filter your JSON data before creating a chart. A simplified process will be like below:
const receivedData = [{
name: 'Start prototype',
start: '2021-04-11',
end: '2021-04-17'
}, {
name: 'Test prototype',
start: '2022-04-11',
end: '2022-04-17'
}, {
name: 'Develop',
start: '2022-06-11',
end: '2022-07-11'
}, {
name: 'Run acceptance tests',
start: '2022-09-11',
end: '2022-09-21'
}];
const filteredData = receivedData.filter(
dataEl => new Date(dataEl.start) > new Date('2022')
);
// THE CHART
Highcharts.ganttChart('container', {
series: [{
name: 'Project 1',
data: filteredData.map(({
name,
start,
end
}) => ({
name,
start: new Date(start).getTime(),
end: new Date(end).getTime()
}))
}]
});
Live demo: https://jsfiddle.net/BlackLabel/0vhdg5jw/

Quasar Q-Table and Data from Array (IndexedDB & Dexie)

I am new to Quasar and Javascript and I'm trying to get data from my database (IndexedDB using Dexie) into my q-table.
I have the skeleton of the q-table and I'm getting the data from Dexie, in the form of an Array, but I don't know how to display the data in the table and I would love some help.
I've read about maybe having to use computed, and/or the map option but I don't know enough about either of those to use them. I've been googling and reading the Quasar docs and I'm still not sure what to do. I don't know if I can put it in a codepen since it's getting data from a database.
I have this live online at https://entrypaws.com/ you may have to hit shift-reload to get the latest version as my host has an online cache it keeps, though I've cleared it. This small table section is reachable by clicking the 'view test table' link in the left sidebar.
Here is my html:
<q-page>
wholething: {{ this.thePersonArray }} // this displays correc
<br/><br/>
hmmm: {{ this.thePersonArray[0].f_lastName }}
<q-table
title="Treats"
:rows="rows"
:columns="columns"
row-key="name"
binary-state-sort
>
<template v-slot:body="props">
<q-tr :props="props">
<q-td key="name" :props="props">
{{ props.row.name }}
</q-td>
<q-td key="lname" :props="props">
{{ props.row.lname }}
</q-td>
<q-td key="dogbreed" :props="props">
<div class="text-pre-wrap">{{ props.row.dogbreed }}</div>
</q-td>
<q-td key="phone" :props="props">
{{ props.row.phone }}
</q-td>
</q-tr>
</template>
</q-table>
</q-page>
</template>
and this is my script:
import { ref } from "vue"
import theDB from "../components/dexiedb.js"
const columns = [
{
name: 'name',
label: 'First Name',
field: row => row.name, // f_lastname:
},
{ name: 'lname', label: 'Last Name', field: 'lname'},
{ name: 'dogbreed', label: 'Dog Breed', field: 'dogbreed'},
{ name: 'phone', label: 'Phone', field: 'phone'},
]
const rows = [
{
name: 'Susan',
lname: 'Smith',
dogbreed: 'Danish-Swedish Farmdog',
phone: '801.810.9990',
},
{
name: 'James',
lname: 'Jones',
dogbreed: 'Kromfohrlander',
phone: '801.930.9999',
},
]
export default {
name: "testtable",
setup() {
return {
columns,
rows
}
}, // end setup
data() {
return {
thePersonArray: [],
}
}, // end data
created() {
this.getTheUsers()
}, // end mounted
methods: {
getTheUsers() {
this.thePersonArray = []
console.log(" getTheUsers 1 ", this.thePersonArray)
this.thePersonArray.push({f_lastName: "Dreamer"}) // if the array is not initialized i seem toget an error
theDB.personTable
.orderBy('f_lastName')
.each((personOBJ) => {
this.thePersonArray.push(personOBJ)
console.log(" inside: ", this.thePersonArray)
}).then(() => {
// Transaction committed.
console.log(" People: Transaction committed")
}).catch(err => {
// Transaction aborted.
console.log(" People: Transaction aborted")
})
console.log(" after done: ", this.thePersonArray)
}
}, // end methods
} // end export
</script>```
I'd love some help. I'm completely stuck.
[1]: https://entrypaws.com/
Try making thePersonArray reactive by using ref
data() {
return {
thePersonArray: ref([]),
}
},
then assign the new array to thePersonArray.value
getTheUsers() {
this.thePersonArray.value = []
I think you might be able to push directly with thePersonArray as I think Vue maps/ wraps/ proxies these methods (whatever they call it :) ), so try
this.thePersonArray.push({f_lastName: "Dreamer"})
and if that doesnt work try
this.thePersonArray.value.push({f_lastName: "Dreamer"})
but I think the first will work

Angular 4 dropdown multiselect not showing property data

I just installed angular 4 multiselect dropdown to show the data that i am getting from JSON script using services. I am getting the data in my property but now i want to show it in a multiselect dropdown so that i can use multiple values and assign them to my next property. So in the below code i am calling a method of getSubject and it is returning me the data in this.subject property.
this._curriculumService.getSubject(this.appSession.tenant.tenancyName)
.finally(() => {this.saving = false;})
.subscribe((result: listResultDtoOfSubjectDto) => {
this.subjects = result.items;
this.id = this.subjects.map(a => a.code);
this.itemName = this.subjects.map(a => a.name);
})
Now i want to show this data inside inside angular 4 dropdown multiselect and here is a code for that in my component.ts file. The problem is that the dropdown asked for a specific id and name of the property and only then it will be able to show the data in dropdown but in my case i have a name and code returning in this.subjects. So how can i show my data in this dropdown
optionsModel: number[];
myOptions: IMultiSelectOption[];
this.myOptions = [
{ id: 1, name: 'Physics' },
{ id: 2, name: 'English' },
{ id: 3, name: 'English' },
{ id: 4, name: 'Programming'}
];
HTML Code
<div class="form-line focused">
<div class="col-sm-4">
<div class="form-group form-float">
<div class="form-line focused">
<ss-multiselect-dropdown
[options]="myOptions"
[(ngModel)]="optionsModel"
(ngModelChange)="onChange($event)">
</ss-multiselect-dropdown>
</div>
</div>
</div>
</div>
So for that don't declare type of your myOptions as IMultiSelectOption[], instead keep it any or whatever you're receiving from service. As this plugin requires each options to have the id thus, you can add that property to myOptions objects after it's received from service response. So, make sure that property should be unique valued (e.g. subject code).
Let this.subjects is an array of objects you got from service:
optionsModel: number[];
subjects: any;
this.subjects = [
{ code: 11, name: 'Physics' },
{ code: 12, name: 'English' },
{ code: 13, name: 'English' },
{ code: 14, name: 'Programming'}
];
this.subjects.forEach(function(e) { e.id = e.code });
The last line will add id property to each object with value same to subject code. Now the dropdown will work as expected.
Demo Example

Joi : validate object of variable number of keys

I am trying to write a validation method for the following object ( associative array ):
{
"10:00": {
discount: 10,
time: "10:00",
},
"11:00": {
discount: 11,
time: "11:00",
},
...
....
}
Using Joi (https://github.com/hapijs/joi) What i got so far is this:
Joi.object().keys(
{time:{
discount: Joi.number(),
time: Joi.string(),
}}
),
which is obviously wrong and failing with : ValidationError: child "discounts" fails because ["10:00" is not allowed, "11:00" is not allowed]
can anyone suggest how to write validation for objects with variable number of keys ( associative array )
sorted it out after reading through : Is there a way to validate dynamic key names?
Joi.object().pattern(/^/, [
Joi.object({
discount: Joi.number(),
time: Joi.string()
})
])

Accessing an included object

I have the following JSON Object, which is the result of a loopback model (Classifications), with a relationship with another model (Labels).
My call to get the classifications is:
modClassification.findOne({
where: { id: classificationid },
include: 'labels' },
function( err, classification ){ ...
And this returns classification with something like
{ id: 'b01',
title: 'population',
country_id: 1,
labels:
[ { column_id: 'b1',
classification_id: 'b01',
classification_title: 'population',
dsporder: 1,
label: 'Total_Persons_Males',
country_id: 1,
id: 1 },
{ column_id: 'b2',
classification_id: 'b01',
classification_title: 'population',
dsporder: 2,
label: 'Total_Persons_Females',
country_id: 1,
id: 2 } ] }
which is what I would expect.
I now need to loop over the labels and access it's properties, but this is where I am stuck.
classification.labels[0] = undefined..
I have tried looping, each and whatever I can find online, but can't seem to get to each labels properties.
Can someone tell me what I am doing wrong/need to do?
Thanks
When you are including related models inside a findOne call, you need to JSONify the result before accessing the related records:
classification = classification.toJSON()
Then you should be able to access the included label items as you expect.
See https://docs.strongloop.com/display/public/LB/Include+filter, specifically the "Access included objects" section.
Note this does not work the same when you retrieve more than one result in an array. In that case you'll need to perform toJSON() on each item in the array.