Nest JS - Serialization not work with nested object - serialization

I want to append a new field called logo_img_url after data manipulation. It works with the object but the nested array object seems not to work. Any recommendations or solution
import { Expose } from 'class-transformer';
import {} from 'class-validator';
import { Entity, Column } from 'typeorm';
import { BaseEntity } from '#common/base/entity.base';
import { getAdminImageUrl } from '#common/util/vault-file.util';
#Entity()
export class Agency extends BaseEntity {
#Expose()
#Column({
type: 'varchar',
length: '255',
nullable: true,
})
public logo_key!: string;
#Expose({ name: 'logoImgUrl' })
logo_img_url = this.logoImgUrl;
#Expose()
get logoImgUrl(): any {
return "http://localhost:30001/". this.logo_key;
}
}
Actaul response:
{
"data": [
{
"logo_img_url": "",
"id": 22,
"logo_url": "9597e74d-aaea-4502-b5cd-b2867504fd80",
},
{
"logo_img_url": "",
"id": 21,
"logo_url": "0a655497-1318-4276-a21f-cfdc259241a2",
},
],
"meta": {
"status_code": 200,
"pagination": {
"totalPages": 1,
"currentPage": 1,
"nextPage": null,
"paginationToken": null,
"previousPage": null,
"totalItems": 9,
"itemsPerPage": 10
}
}
}
Expected result:
{
"data": [
{
"logo_img_url": "http://localhost:3000/9597e74d-aaea-4502-b5cd-b2867504fd80",
"id": 22,
"logo_url": "9597e74d-aaea-4502-b5cd-b2867504fd80",
},
{
"logo_img_url": "http://localhost:3000/0a655497-1318-4276-a21f-cfdc259241a2",
"id": 21,
"logo_url": "0a655497-1318-4276-a21f-cfdc259241a2",
},
],
"meta": {
"status_code": 200,
"pagination": {
"totalPages": 1,
"currentPage": 1,
"nextPage": null,
"paginationToken": null,
"previousPage": null,
"totalItems": 9,
"itemsPerPage": 10
}
}
}

You can use #AfterLoad decorator from typeorm. Its calls the decorated method once the entity is loaded and then one can perform the required manipulations.
logo_img_url:string
#AfterLoad()
async transform(){
this.logo_img_url=`http://localhost:30001/${this.logo_key}`
}

Related

Mongodb aggregation to find outliers

In my mongodb collection documents are stored in the following format:
{ "_id" : ObjectId("62XXXXXX"), "res" : 12, ... }
{ "_id" : ObjectId("63XXXXXX"), "res" : 23, ... }
{ "_id" : ObjectId("64XXXXXX"), "res" : 78, ... }
...
I need to extract id's for the document for which the value of "res" is outlier (i.e. value < Q1 - 1.5 * IQR or value > Q3 + 1.5 * IQR (Q1, Q3 are percentiles)). I have done this using pandas functionality by retrieving all documents from the collection, which may become slow if the number of documents in collection become too big.
Is there a way to do this using mongodb aggregation pipeline (or just calculating percentiles)?
If I understand how you want to retrieve outliers, here's one way you might be able to do it.
db.collection.aggregate([
{ // partition res into quartiles
"$bucketAuto": {
"groupBy": "$res",
"buckets": 4
}
},
{ // get the max of each quartile
"$group": {
"_id": "$_id.max"
}
},
{ // sort the quartile maxs
"$sort": {
"_id": 1
}
},
{ // put sorted quartile maxs into array
"$group": {
"_id": null,
"maxs": {"$push": "$_id"}
}
},
{ // assign Q1 and Q3
"$project": {
"_id": 0,
"q1": {"$arrayElemAt": ["$maxs", 0]},
"q3": {"$arrayElemAt": ["$maxs", 2]}
}
},
{ // set IQR
"$set": {
"iqr": {
"$subtract": ["$q3", "$q1"]
}
}
},
{ // assign upper/lower outlier thresholds
"$project": {
"outlierThresholdLower": {
"$subtract": [
"$q1",
{"$multiply": ["$iqr", 1.5]}
]
},
"outlierThresholdUpper": {
"$add": [
"$q3",
{"$multiply": ["$iqr", 1.5]}
]
}
}
},
{ // get outlier _id's
"$lookup": {
"from": "collection",
"as": "outliers",
"let": {
"oTL": "$outlierThresholdLower",
"oTU": "$outlierThresholdUpper"
},
"pipeline": [
{
"$match": {
"$expr": {
"$or": [
{"$lt": ["$res", "$$oTL"]},
{"$gt": ["$res", "$$oTU"]}
]
}
}
},
{
"$project": {
"_id": 1
}
}
]
}
}
])
Try it on mongoplayground.net.
One more option based on #rickhg12hs's answer, is to use $setWindowFields:
db.collection.aggregate([
{$setWindowFields: {
sortBy: {res: 1},
output: {
totalCount: {$count: {}},
index: {$sum: 1, window: {documents: ["unbounded", "current"]}}
}
}
},
{$match: {
$expr: {$lte: [
{$abs: {$subtract: [
{$mod: [
{$multiply: [
{$add: ["$index", {$round: {$divide: ["$totalCount", 4]}}]}, 2]},
"$totalCount"
]}, 0]}
}, 1]}
}},
{$group: {_id: null, res: {$push: "$res"}}},
{$project: {_id: 0, q1: {$first: "$res"}, q3: {$last: "$res"},
iqr: {"$subtract": [{$last: "$res"}, {$first: "$res"}]}
}},
{$project: {
outlierThresholdLower: {$subtract: ["$q1", {$multiply: ["$iqr", 1.5]}]},
outlierThresholdUpper: {$add: ["$q3", {$multiply: ["$iqr", 1.5]}]}
}
},
{$lookup: {
from: "collection",
as: "outliers",
let: {oTL: "$outlierThresholdLower", oTU: "$outlierThresholdUpper"},
pipeline: [
{$match: {$expr: {$or: [{$lt: ["$res", "$$oTL"]}, {$gt: ["$res", "$$oTU"]}]}}},
{$project: {_id: 1}}
]
}
}
])
See how it works on the playground example

How to get sum of of sums in laravel on to many to many relationship in laravel

I have a User table that have many TeamMember and each TeamMember have many Order. My query look like this at the moment:
$users = User::select('id', 'username')
->with(['userTeamMembers' => function ($query) {
$query->select('team_lead_id', 'team_member_id')
->withSum('completedOrders', 'amount')
->whereHas('completedOrders');
}])
->whereHas('userTeamMembers.completedOrders')
->get()
->toArray();
The output:
[
{
"id": 1,
"username": "user1",
"user_team_members": [
{
"team_lead_id": 1,
"team_member_id": 19,
"completed_orders_sum_amount": "100.00"
},
{
"team_lead_id": 1,
"team_member_id": 34,
"completed_orders_sum_amount": "200.00"
},
]
},
{
"id": 5,
"username": "user5",
"user_team_members": [
{
"team_lead_id": 5,
"team_member_id": 25,
"completed_orders_sum_amount": "50.00"
},
{
"team_lead_id": 5,
"team_member_id": 67,
"completed_orders_sum_amount": "50.00"
},
]
}
]
But what I'm trying to achieve is a result like below:
[
{
"id": 1,
"username": "user1",
"user_team_members_sum": "300.00"
},
{
"id": 5,
"username": "user5",
"user_team_members_sum": "100.00"
}
]
As you can see, all of the team members total are added together compared to the former output. Is the result like above achievable? My Models are like below:
User Model
class User extends Authenticatable
{
...
public function userTeamMembers()
{
return $this->hasMany(TeamMember::class, 'team_lead_id');
}
}
Team Member Model
class TeamMember extends Model
{
....
public function completedOrders()
{
return $this->hasMany(Order::class, 'user_id', 'team_member_id')->select('user_id', 'amount')->where('status', 1);
}
}
// Try this. It could serve your desire output
$users = User::select('id', 'username')
->withSum('userTeamMembers.completedOrders', 'amount')
->whereHas('userTeamMembers.completedOrders')
->get()
->toArray();

Vuex store changes not reactive in components

I have a basic store for inserting and deleting from an array
state: {
assessmentTypes : []
},
mutations: {
setAssessmentTypes(state, assessmentTypes) {
assessmentTypes.forEach(assessmentType => {
state.assessmentTypes.push(assessmentType);
});
},
removeAssessmentType ( state, assessmentTypeId ) {
let assessmentTypeIndex = state.assessmentTypes.map(assessmentType => assessmentType.id).indexOf(assessmentTypeId);
state.assessmentTypes.splice(assessmentTypeIndex, 1)
}
}
I get the state assessmentTypes in computed property in one of my components.
computed:{
assessmentTypes : {
get () {
return this.$store.state.assessmentTypes;
}
}
The problem is I am looping the array in dom for listing a div, but the computed property is not reactive. When I delete or insert a new object into/from the array (through actions), the dom is not rerendering.
Object structure
{
"id": "T7pLDdjmFWAqGiuqB",
"name": "bbb",
"code": "BBB",
"properties": {
combinationOfAssessments: false,
staffCanCreateInstance: false
},
"identifyingContext": {
"semId": "2",
"batchId": "54",
"staffId": "155",
"subjectId": "966",
"subbatchId": "391"
},
"permissions": {
"hod": "1",
"staff": "1"
},
"isActive": "1",
"createdBy": null,
"createdUserName": null,
"createdByUserType": null,
"createdDate": null,
"updatedDate": null,
"updatedBy": null,
"updatedUserName": null,
"updatedByUserType": null,
"propertiesValue": null
}

Inserting data in vuex-orm database that is already normalized

Assuming the data i receive is already normalized, or at least the relations.
How can this data be inserted into the vuex-orm database?
Example JSON data:
{
"carmodel": [
{
"id": 1,
"title": "M3",
"manufacturer_id": 1
},
{
"id": 2,
"title": "a-class"
"manufacturer_id": 2
}
],
"manufacturer": [
{
"id": 1,
"title": "BMW"
},
{
"id": 2,
"title": "Mercedes"
}
]
}
Manufacturer Model and Carmodel are inserted like this:
Manufacturer.insert({ data: response.data.manufacturer })
CarModel.insert({ data: response.data.carmodel })
This example model will not work:
import { Model } from '#vuex-orm/core'
import Manufacturer from '#/models/Manufacturer'
export default class CarModel extends Model {
static entity = 'carModels'
static fields () {
return {
id: this.attr(null),
title: this.string(''),
manufacturer: this.hasOne(Manufacturer, 'manufacturer_id')
}
}
}
Ok, i think i got it. Instead of this.hasOne i have to use belongsTo and use the manufacturer_id from the same model:
import { Model } from '#vuex-orm/core'
import Manufacturer from '#/models/Manufacturer'
export default class CarModel extends Model {
static entity = 'carModels'
static fields () {
return {
id: this.attr(null),
title: this.string(''),
manufacturer_id: this.attr(null),
manufacturer: this.belongsTo(Manufacturer, 'manufacturer_id')
}
}
}

Error when creating a chart via a batch request

I'm trying to create a new chart, following the examples presented in Google sheets API. I'm getting the following error:
HttpError 400 when requesting
https://slides.googleapis.com/v1/presentations/PRESENTATION_ID:batchUpdate?alt=json
returned "Invalid JSON payload received. Unknown name "add_chart" at
'requests[0]': Cannot find field."
Has anyone encountered this before?
Other requests are working normal (replace text, add text, clone presentation, etc)
this request is being copied from the example in Google sheets API.
sourceSheetId is the id where I have the data for the chart saved in.
{
"addChart": {
"chart": {
"spec": {
"title": "Model Q1 Sales",
"basicChart": {
"chartType": "COLUMN",
"legendPosition": "BOTTOM_LEGEND",
"axis": [
{
"position": "BOTTOM_AXIS",
"title": "Model Numbers"
},
{
"position": "LEFT_AXIS",
"title": "Sales"
}
],
"domains": [
{
"domain": {
"sourceRange": {
"sources": [
{
"sheetId": sourceSheetId,
"startRowIndex": 0,
"endRowIndex": 7,
"startColumnIndex": 0,
"endColumnIndex": 1
}
]
}
}
}
],
"series": [
{
"series": {
"sourceRange": {
"sources": [
{
"sheetId": sourceSheetId,
"startRowIndex": 0,
"endRowIndex": 7,
"startColumnIndex": 1,
"endColumnIndex": 2
}
]
}
},
"targetAxis": "LEFT_AXIS"
},
{
"series": {
"sourceRange": {
"sources": [
{
"sheetId": sourceSheetId,
"startRowIndex": 0,
"endRowIndex": 7,
"startColumnIndex": 2,
"endColumnIndex": 3
}
]
}
},
"targetAxis": "LEFT_AXIS"
},
{
"series": {
"sourceRange": {
"sources": [
{
"sheetId": sourceSheetId,
"startRowIndex": 0,
"endRowIndex": 7,
"startColumnIndex": 3,
"endColumnIndex": 4
}
]
}
},
"targetAxis": "LEFT_AXIS"
}
],
"headerCount": 1
}
},
"position": {
"newSheet": True
}
}
}
}
I was expecting the chart to be created and receive a response with chartId, however I'm getting from the request a 400 status:
HttpError 400 when requesting
https://slides.googleapis.com/v1/presentations/PRESENTATION_ID:batchUpdate?alt=json
returned "Invalid JSON payload received. Unknown name "add_chart" at
'requests[0]': Cannot find field."