I have below interface.
interface ProductJson {
id: number;
name: string;
price: number;
}
I want to have multiple alias names for price, like price and alias names: rate, etc. How can I read json data attribute 'rate' for 'price' and also read 'price' too.
You can use a custom serializer to create aliases between fields:
Example using #kaiu/serializer:
class ProductJson {
id: number;
name: string;
#FieldName('rate')
price: number;
}
Or you can also create a getter method and use the serializert to map your JSON to a class instance in order to use your method directly, see https://kaiu-lab.github.io/serializer/ for in-depth stuff.
One way is to maintain a group of attribute names that you want to alias.
And then add the interface property price to the json itself, if it contains the aliased properties like rate or amount.
Now you can simply access price from else where, which should give the same value
Ex:
var price_group = ['price', 'rate', 'amount'];
var some_other_group = []
var resp = {rate: 200, p: 12}
var resp2 = {price: 300, p: 12};
Object.keys(resp).forEach(key => {
if(price_group.indexOf(key) > -1){
resp.price = resp[key]
}
});
console.log(resp.price)
Object.keys(resp2).forEach(key => {
if(price_group.indexOf(key) > -1){
resp.price = resp[key]
}
});
console.log(resp2.price)
I'm not sure you can do that tbh.
You can easily do it by programming your stuff that reads/writes the json to accept stuff like rate, price, moolah and just write it as
{
price: number
}
edit: what i'm saying is you take the user input or any other input that specifies something like {moolah: 30} and you take that '30' and put it on {price: 30} in your json.
Related
I work at an project with typeorm.
In my project I have these entities:
Course.ts
export class Course extends DefaultBaseEntity {
#Column({name: "course_name"})
courseName: string;
#Column({name:"discipline"})
discipline: string;
#Column({default: 0}) rating: number;
}
and RatingsCourse.ts
export class CoursesRatings extends BaseEntity {
#PrimaryGeneratedColumn({type: "bigint"})
public id: number;
// other columns defined here
#Column({type: "bigint"})
userId: number;
#Column({type: 'bigint'}) courseId: number;
#Column() rating: number;
}
the idea it's every course has ratings. when I add a new rating I want to save in the rating field from Course the average ratings value from CoursesRatings
I code something like this :
await CoursesRatings.create({
courseId: ratingBody.courseId,
userId: user.id,
rating: ratingBody.rating
}).save();
const ratingsObjects = await CoursesRatings.find({
where: {
courseId: ratingBody.courseId,
userId: user.id
},
select: ["rating"]
});
const ratings: number[] = ratingsObjects.map(x => x.rating);
const avgRating = ratings.reduce((a, b) => a + b) / ratings.length;
const course = await Course.findOne(ratingBody.courseId);
course.rating = Math.fround(avgRating);
await course.save();
but it take some time.
I want to know how to optimize this code. I appreciate any help. Thanks!
One of the available options for implementing this is creating a database trigger as follows -
CREATE TRIGGER computeAvg
AFTER INSERT ON CoursesRatings
FOR EACH ROW
UPDATE Course
SET rating = (SELECT AVG(rating) FROM CoursesRatings
WHERE CoursesRatings.courseId = Course.id)
WHERE id = NEW.courseId;
If updating the course rating for every insert of user rating proves to be too costly then I would suggest scheduling a CRON job to update the course ratings of all the courses at a specific interval, let us say 1 day. That way it will become less costly in terms of DB operations as compared to the approach earlier suggested.
I know this question is old but for someone that may run into this kind of situation, I believe using a query will solve this.
const avgRating = await this.coursesRatings
.createQueryBuilder('x')
.where('x.courseId = :rating', { rating: ratingBody.courseId })
.select('AVG(rating)', 'avg')
.getRawOne();
With this, you can get access to the average rating, and you have to update Course
await this.course.save({
...course,
rate: String(Number(avgRating.avg).toFixed(1)),
});
I believe it helps... The reason I used String is that rating will be a floating type, not an integer.
I am new to typescript in angular 2 and i stuck with a situation.
I have a json array in this format
needle json
[{"empId":100,"orgId":500}
{"empId":201,"orgId":566}]
The above json is in a particular order and we need to keep that order maintained while looking for those in another json array(Haystack)
Haystack json array
[
{"empCode":21,"fname":"Ashish","Lname":"Shukla"},
{"empCode":22,"fname":"John","Lname":"Mark"},
{"empCode":21,"fname":"Vigil","Lname":"Rocker"},
{"empCode":201,"fname":"Rick","Lname":"Mandez"},
{"empCode":21,"fname":"Erik","Lname":"Francis"},
{"empCode":100,"fname":"Alex","Lname":"Mishra"},
{"empCode":21,"fname":"Feeder","Lname":"Kapoor"},
{"empCode":21,"fname":"Dan","Lname":"Rox"},
{"empCode":21,"fname":"Herb","Lname":"Deen"},
{"empCode":21,"fname":"Nate","Lname":"Diaz"},
{"empCode":21,"fname":"Nick","Lname":"Diaz"},
{"empCode":21,"fname":"Conor","Lname":"Pussy"}
]
Now i need to get those values from haystack array whose id matches in needle keeping the order maintained of the needle
{"empCode":100,"fname":"Alex","Lname":"Mishra"},
{"empCode":201,"fname":"Rick","Lname":"Mandez"}
I have achieved the solution to this problem but i guess my solution is not optimal as i am using many loops. Can some one suggest me a good solution.
PLS NOTE: Order of the employee id should be maintained in result json as of the needle json.
Thanks a lot :)
This should work
public needle: any;
public hayStack: any;
this.needle = [
{"empId": 100, "orgId": 500},
{"empId": 201, "orgId": 566}
];
this.hayStack = [
{"empCode":21,"fname":"Ashish","Lname":"Shukla"},
{"empCode":22,"fname":"John","Lname":"Mark"},
{"empCode":21,"fname":"Vigil","Lname":"Rocker"},
{"empCode":201,"fname":"Rick","Lname":"Mandez"},
{"empCode":21,"fname":"Erik","Lname":"Francis"},
{"empCode":100,"fname":"Alex","Lname":"Mishra"},
{"empCode":21,"fname":"Feeder","Lname":"Kapoor"},
{"empCode":21,"fname":"Dan","Lname":"Rox"},
{"empCode":21,"fname":"Herb","Lname":"Deen"},
{"empCode":21,"fname":"Nate","Lname":"Diaz"},
{"empCode":21,"fname":"Nick","Lname":"Diaz"},
{"empCode":21,"fname":"Conor","Lname":"Pussy"}
];
const needleEmpId = this.needle.map(item => item.empId);
const hayStackEmpCode = this.hayStack.map(item => item.empCode);
const result = hayStackEmpCode.map((id, index) => {
if (needleEmpId.indexOf(id) != -1) {
return this.hayStack[index];
}
}).sort().filter(item => (item != undefined));
console.log(result);
Result
0:{empCode: 100, fname: "Alex", Lname: "Mishra"}
1:{empCode: 201, fname: "Rick", Lname: "Mandez"}
I would like to use curly braces to replace this code:
let rUsers = children.map((user) => {
let rUser= {};
rUser.firstName = user.firstName;
rUser.lastName = user.lastName;
rUser.relation = user.patron.relation;
return rUser;
});
This is what I have:
let rUsers = children.map((user) => {
let rUser = {};
({
firstName: rUser.firstName,
lastName: rUser.lastName,
patron.relation: rUser.relation, // I get an error here
} = user);
return rUser;
}
Except for patron.relation, the rest of the extraction works.
Questions:
How should I extract value of user.patron.relation?
Is there a more succint way of writing the above?
Thanks!
How should I extract value of user.patron.relation?
You would use { … patron: {relation: rUser.relation}, … } as the destructuring target.
Is there a more succint way of writing the above?
If the property names don't match there's not much you can do, but in your particular case you can simplify by destructuring the parameter into multiple variables:
const rUsers = children.map(({firstName, lastName, patron: {relation}}) =>
({firstName, lastName, relation})
);
You can use object destructuring like this:
const {firstName, lastName, patron: {relation}} = user
And relation has been set to the value of user.patron.relation.
You can return the object you want like so:
return {firstName, lastName, relation}
I'm seeing a few things wrong with your code.
patron.relation -> patron isn't defined, and can't be used as a key.
In the second example, rUser is used - I think you just want user.
My understanding of what you're trying to do essentially create a clone? If so, you should be able to do something like this.
let rUsers = children.map(user => {
firstName: user.firstName,
lastName: user.lastName,
relation: user.relation
});
Alternatively, it could be simpler to use Object.assign()
let rUsers = children.map(user => Object.assign({}, user));
I'm using extJS version 4.0 to generate a entry form. On that form there is a save button that sends all the fielddata to php via ajax. As transfer protocol for the data itself I'm using json.
As I need to make a dynamical (general) routine for processing this data (as that one form won't be the only form in that project) I would need that json data grouped somehow. One of the requirements I have is that I need the "fieldnames" to be as they are (as I use the fieldnames I get transmitted to me to access the approopriate coloumns in the database in the automatic save routine).
My question here is is there any way to somehow group the data that is transmitted via json (thus that extJS groups it).
As a simplified example:
On the entryform I'm saving data for 2 tables (1. Person 2. bankaccount) which have the following fields shown on the form:
-firstname
-lastname
for person
and
-account number
-bank number
for bankaccount
(the stores are accordingly)
Is there a way with extJS to group this data acordingly, thus generate something like this?
{"person":[{"firstname": "Mark", "lastname":"Smith"}],"bankaccount":[{"account number":123112,"bank number":1A22A1}]}
Currently I'm getting something like this:
{"firstname": "Mark", "lastname":"Smith","account number":123112,"bank number":1A22A1}
Both person and bankaccount are in their separate stores.
Tnx.
Well, you've two stores: one for 'person' and one for 'bankaccount'.
Ext.define ('Person', {
extend: 'Ext.data.Model' ,
fields: ['firstname', 'lastname']
});
Ext.define ('BankAccount', {
extend: 'Ext.data.Model' ,
fields: ['accountnumber', 'banknumber']
});
var personStore = Ext.create ('Ext.data.Store', {
model: 'Person' ,
data: [
{firstname: 'foo', lastname: 'bar'} ,
{firstname: 'zoo', lastname: 'zar'} ,
{firstname: 'too', lastname: 'tar'} ,
{firstname: 'goo', lastname: 'gar'} ,
{firstname: 'moo', lastname: 'mar'}
]
});
var bankAccountStore = Ext.create ('Ext.data.Store', {
model: 'BankAccount' ,
data: [
{accountnumber: 10000, banknumber: 10000} ,
{accountnumber: 20000, banknumber: 20000} ,
{accountnumber: 30000, banknumber: 30000} ,
{accountnumber: 40000, banknumber: 40000} ,
{accountnumber: 50000, banknumber: 50000}
]
});
Then, you want to dump these stores as JSON. No problem!
Make a container (jsonData) and then fill it up with your stores:
var jsonData = {
person: [] ,
bankaccount: []
};
personStore.each (function (person) {
jsonData.person.push (person.data);
});
bankAccountStore.each (function (bank) {
jsonData.bankaccount.push (bank.data);
});
console.log (Ext.JSON.encode (jsonData));
And this is the output on the console:
{"person":[{"firstname":"foo","lastname":"bar"},{"firstname":"zoo","lastname":"zar"},{"firstname":"too","lastname":"tar"},{"firstname":"goo","lastname":"gar"},{"firstname":"moo","lastname":"mar"}],"bankaccount":[{"accountnumber":10000,"banknumber":10000},{"accountnumber":20000,"banknumber":20000},{"accountnumber":30000,"banknumber":30000},{"accountnumber":40000,"banknumber":40000},{"accountnumber":50000,"banknumber":50000}]}
Is that what you've requested?
Here's the fiddle
I am trying to load some JSON, in which I store a lot of variables about some 100 anaesthetic drugs for pediatric patients.
The actual values get calculated before from patient's weight, age etc.:
Example:
var propofolInductionTitle = propofolName + ' ' + propofol0PercentConcentration + '- Induktion';
var propofol0InductionDosageMG = (Math.round(kg * 2 * 10) / 10) + ' - ' + (Math.round(kg * 5 * 10) / 10);
I then create my drug as a block of json consisting of the variables I need which are later to be replaced by the calculated values. I specifically try to avoid Strings in the JSON to allow for easier localization to english and french when all variables are defined in the math block.
var hypnotikaJSON = {
"thiopentalTitle": [
{"thiopentalBrandName": ""},
{"vialContentTitle": "thiopentalVialContent"},
{"solutionTitle": "thiopentalSolution"},
{"concentrationTitle": "thiopentalConcentration"},
{"dosageString": "thiopentalDosageString"},
{"atWeight": "thiopentalDosageMG"},
{"thiopentalAtConcentration": "thiopentalDosageML"}
],
"propofolInductionTitle": [
{"propofolInductionBrandName": ""},
{"propofolVialContentTitle": "propofolInductionVialContent"},
{"propofolSolutionTitle": "propofolSolution"},
{"propofolConcentrationTitle": "propofolInductionConcentration"},
{"propofolInductionDosageStringTitle": "propofolInductionDosageString"},
{"atWeight": "propofolInductionDosageMG"},
{"propofolAtInductionConcentration": "propofolInductionDosageML"}
],
"propofolSedationTitle": [
{"propofolSedationBrandName":""},
{"propofolVialContentTitle":"propofolSedationVialContent"},
{"propofolSolutionTitle":"propofolSolution"},
{"propofolConcentrationTitle":"propofolSedationConcentration"},
{"propofolSedationDosageStringTitle":"propofolSedationDosageString"},
{"atWeight":"propofolSedationDosageMG"},
{"propofolAtSedationConcentration":"propofolSedationDosageML"}
],
"laryngealMaskTitle": [
{"laryngealMaskSizeTitle":"laryngealMaskSize"},
{"laryngealMaskCuffSizeTitle":"laryngealMaskCuffSize"},
{"laryngealMaskBiggestETTTitle":"laryngealMaskBiggestETT"},
{"laryngealMaskBronchoscopeSizeTitle":"laryngealMaskBronchoscopeSize"}
]
};
My specific need is that the JSON reader has to give me the key AND value of each object as I need both to populate a template. The reason ist that the fields for the drugs are different in parts. Some have additional routes of administration so I have another key:value pair a different drug doesnt have. Some are given both as bolus and per drip, some arent. So no convenient json structure ist possible.
I found an answer by rdougan here that partly allowed me to do just that:
Model:
Ext.define('my.model.Drug', {
extend: 'Ext.data.Model',
config: {
fields: ['name', 'value']
}
});
Custom Json Reader:
Ext.define('Ext.data.reader.Custom', {
extend: 'Ext.data.reader.Json',
alias: 'reader.custom',
getRoot: function (data) {
if (this.rootAccessor) {
data = this.rootAccessor.call(this, data);
}
var values = [],
name;
for (name in data) {
values.push({
name: name,
value: data[name]
});
}
return values;
}
});
Store:
var store = Ext.create('Ext.data.Store', {
fields: ['name', 'value'],
data: hypnotikaJSON,
autoLoad: true,
proxy: {
type: 'memory',
reader: {
type: 'custom'
}
}
});
Panel:
this.viewport = new Ext.Panel({
fullscreen: true,
layout: 'fit',
items: [{
xtype: 'list',
itemTpl: '<p class="description">{name}</p><p class ="values">{value}</p>',
store: store
}]
});
Unfortunately I'm a physician and no programmer, and after a lot of reading I cant find out to apply this to a nested JSON. The custom reader seems to only go for the first level.
I could do it without a reader, without a store with just a lot of plan html around each entry, that has proven to be very very slow though so I would like to avoid it while updating from Sencha Touch 1.1. and better do it right this time.
Could you please point me to a way to parse this ugly data structure?
Thank you
I don't know much about extending JSON readers, so just guessing, but maybe you are supposed override the 'read' method? Then you can go over the JSON as you wish
Also, if you have control over the JSON you should consider changing it.
Usually, the keys in JSON should be the same throughout all items in the array.
keys are not data, they are metadata.
So, if you do have different properties between different drugs, then something like this might be a solution:
[{
name: 'Propofol 1%',
properties: [
{title: 'induction', value: '22-56g'},
{title: 'Sedation', value: '22'},
etc.
]},
{name: 'nextDrug'}
etc..