Compare array of object with an array - javascript

I have a request
const request=additionalFields: [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true }
]
the response i am getting is this
"additionalFields":
{
'PHONE':true,
'COMPANY':true,
'MOBILE':true,
'COUNTRY':true
}
i am not sure how to compare them. i kind of wrote something but even to me it looks wrong
const fields = request["additionalFields"];
for (let i = 0, len = fields.length; i < len; i++) {
expect(request.additionalFields[i].required).to.eql(
response.additionalFields
);

Here's another way. Just filter out anything that doesn't match up, then you'll have an array of differences if there are any.
const request={
additionalFields: [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true }
]
}
const incoming = {
"additionalFields": {
'PHONE': true,
'COMPANY': true,
'MOBILE': false,
'COUNTRY': true
}
}
let differences = request.additionalFields.filter(f => incoming.additionalFields[f.field] !== f.required)
console.log(differences)

const request = [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true }
]
const response = {"additionalFields":
{
'PHONE':true,
'COMPANY':true,
'MOBILE':true,
'COUNTRY':true
}}
for (const [key, value] of Object.entries(response['additionalFields'])) {
const {required, field} = request.find(({field}) => key === field);
if(required === value) { // here you can compare
console.log(key, field, value);
}
}

You need to dereference the response.additionalFields object using the value of field from each entry in request.additionalFields. Something like
for(const { field, required } of request.additionalFields) {
expect(required).to.eql(
response.additionalFields[field]
);
}

You should loop over each field detail in the request and compare the value against the response. Here you go:
const request = {
additionalFields: [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true },
],
};
const response = {
additionalFields: {
PHONE: true,
COMPANY: true,
MOBILE: true,
COUNTRY: true,
},
};
for (let f of request.additionalFields) {
// Observe f is like { field:'PHONE', required: true }
// Next two lines are just for test, please remove and uncomment last one in your use case.
const comparisonResult = f.required === response.additionalFields[f.field];
console.log(`for field ${f.field}, It's ${comparisonResult}`);
// expect(f.required).to.eql(response.additionalFields[f.field]);
}
You can further improve readability by using destructuring, drop a comment if you want to see that.

You can use the for...of syntax to do this.
Here's the documentation.
const request = {
additionalFields: [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true }
]
};
const response = {
additionalFields: {
PHONE:true,
COMPANY:true,
MOBILE: true,
COUNTRY:true
}
}
const requestFields = request['additionalFields'];
const responseFields = response['additionalFields'];
for(const { required, field } of requestFields) {
expect(required).to.eql(responseFields[field]);
}

Related

Mongoose update a deeply nested sub document only having the sub document _id

I have the following schema for a grid (evaluation grid). Grid => Sections => Criteria => Levels and I want to update a single Level element.
const mongoose = require("mongoose");
const levelSchema = mongoose.Schema(
{
title: {
type: String,
required: true,
},
value: {
type: Number,
required: true,
},
},
{ timestamps: true }
);
exports.Level = mongoose.model("Level", levelSchema);
const criterionSchema = mongoose.Schema(
{
title: {
type: String,
required: true,
},
levels: [levelSchema],
},
{ timestamps: true }
);
criterionSchema.virtual("weight").get(function () {
return Math.max(this.levels.map((level) => level.weigth));
});
exports.Criterion = mongoose.model("Criterion", criterionSchema);
const sectionSchema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
criteria: [criterionSchema],
},
{ timestamps: true }
);
sectionSchema.virtual("weight").get(function () {
return this.criteria.reduce((acc, criteria) => acc + criteria.weight, 0);
});
exports.Section = mongoose.model("Section", sectionSchema);
const schema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
sections: [sectionSchema],
code: { type: Number, required: true },
course: {
type: mongoose.Schema.Types.ObjectId,
ref: "Course",
required: true,
},
},
{ timestamps: true }
);
schema.virtual("weight").get(function () {
return this.sections.reduce((acc, section) => acc + section.weight, 0);
});
exports.Grid = mongoose.model("Grid", schema);
I was able to retrieve a specific Level's Grid with this code :
Grid.findOne({"sections.criteria.levels._id": levelId})
So I tried FindOneAndUpdate with this code :
const grid = await Grid.findOneAndUpdate(
{ "sections.criteria.levels._id": req.params.levelId },
{
$set: {
"sections.$[].criteria.$[].levels.$[].title": req.body.title,
},
},
{ new: true });
But, it changed ALL the Levels of the grid.
How can we update a single Level sub, sub, sub document and returns it ?

Fetching documents from DB using a prop which is an object id

I get no results, and I don't know why. (DB has documents with this owner id)
As you can see, I've tried using Types.ObjectId but no success yet.
export const getStores = async (
{ owner, platform }: {
owner: string
platform?: string
}): Promise<StoreMainInfo[]> => {
console.log('owner', owner); // owner 62210e86f36af71f58022971
const stores = await StoreModel.aggregate([
{
'$project': {
'_id': 1,
'platform': 1,
'name': 1,
'category': 1,
'logo': 1,
'urls': 1,
'stats': 1,
}
}, {
$match: { owner: Types.ObjectId(owner) }
},
]);
if (!stores.length) {
throw ApiError.BadRequest('Stores not found.');
}
return stores;
};
// Model:
const StoreSchema: Schema = new Schema({
owner: { type: Types.ObjectId, ref: CollectionNames.user, required: true },
platform: { type: String, required: true },
name: { type: String, required: true },
category: { type: String, required: false },
logo: { type: LogoSchema, required: false },
urls: { type: UrlsSchema, required: true },
stats: { type: StatsSchema, required: true },
suppliers: { type: [SupplierSchema], required: true },
})
export default model<Document & Store>(CollectionNames.store, StoreSchema)

compare arrays returning different results javascript

How do i compare 2 arrays returning different results:
responseFields=[
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true }
]
eventFields=AdditionalFields {
company: BoolValue { value: true },
phone: BoolValue { value: true },
mobile: BoolValue { value: true },
country: BoolValue { value: true }
}
following is what i tried to compare each field but it failed
for (const { field } of responseFields) {
expect(field).to.eql(Object.keys(eventFields)[field]);
}

how can i get array data source, kendo-grid?

I'm getting array of properties and I want to show all of them in grid.
How to do it? Is it possible?
This is my code:
function StartBuild(ProfileProperties) {
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details[i]=[{ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] }];
}
$(document).ready(function () {
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
}
});
$("#grid").kendoGrid({
dataSource: datasource,
pegable: true,
sortable: {
mode: "single",
allowUnsort: false
},
columns: [{
field: "name",
title: "name",
filterable: {
cell: {
enabled:true
}
}
}, {//[Bild, nameP, email,phonework, Mobile, ManagerName]
field: "email",
title: "email"
}, {
field: "phoneWork",
title: "phoneWork"
}, {
field: "Mobile",
title: "Mobile"
}, {
field: "Manager",
title: "Manager"
}],
filterable: {
mode: "row"
},
});
});
}
Only if I write details[0] it shows the first properties otherwise it doesn't show anything.
It looks like there are a couple of problems.
http://dojo.telerik.com/#Stephen/uVOjAk
First, the transport setup is incorrect. pageSize, batch, and schema are not part of the transport configuration...you need to take them out of the transport block and just have them in the datasource block.
You want:
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
}
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
});
Instead of(what you have):
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
}
});
Second, the details needs to be an array of objects, not an array of an array of an object.
You want:
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details.push({ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] });
}
Instead of:
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details[i]=[{ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] }];
}
Two other issues that are not directly causing a problem, but are incorrect are:
Your dataSource.schema configuration does not match your actual data at all. The schema really needs to match the fields of the actual data otherwise it cannot match up the configuration.
You spelled "pageable" wrong in the grid configuration.

Adding new row to grid

I require a Kendo Grid for the user to enter 'n' number of results, then click a button (seperate from the grid control) which will take all the results added to the grid and save them to the database. This should be a simple task considering there are no CRUD operations going on with the grid itself except to add additional, blank rows for data entry...
HOWEVER,
The problem is that the content of the grid is not static and can vary in column size (from 1 to 6) based on user input (my example shows how this will be represented in the form of an array Lots). It seems that most if not all tutorials available seem to focus solely on static content with very little help when it comes to anything else.
So far (with some feedback from Telerik) I have come up with the following...
Set up a Lot Schema i.e. a placeholder for all the data for each Lot in the array:
var Lots = [];
Lots.push({ ID: 13, LotNumber: "158UL" }),
Lots.push({ ID: 14, LotNumber: "646UE" });
var LotResultsSchema = [];
for (var p = 0; p < Lots.length; ++p) {
LotResultsSchema.push({
Result: {
Count: '',
Mean: '',
SD: ''
}
});
}
Set up the overall grid Schema Model ID:
var schemaModel = kendo.data.Model.define({
id: "ID",
fields: {
ID: { editable: false, nullable: true },
ResultDateTime: {
type: "date", validation: {
required: true
}
},
LotResults: LotResultsSchema,
StandardComment: {
ID: {
nullable: true, validation: {
required: false
}
},
Description: {
defaultValue: "<empty>",
validation: {
required: false
}
}
},
ReviewComment: {
ID: {
nullable: true, validation: {
required: false
}
},
Description: {
defaultValue: "<empty>",
validation: {
required: false
}
}
}
}
});
Set up the datasource for the grid based on the schema above:
var gridConfigDataSourceAdd = new kendo.data.DataSource({
data: [],
schema: {
model: schemaModel
}
});
Set up the column schema (again taking into account that there can be multiple columns created based on array size):
var columnSchema = [];
columnSchemaAdd.push({ field: "ResultDateTime", format: "{0:yyyy/MM/dd hh:mm:ss}", editor: dateTimeEditor, title: 'Date Time' });
for (var j = 0; j < Lots.length; ++j) {
columnSchemaAdd.push({
title: Lots[j].LotNumber,
field: Lots[j].ID,
columns: [{
field: "LotResults[" + j + "].Result.Count",
title: 'Count'
}, {
field: "LotResults[" + j + "].Result.Mean",
title: 'Mean'
}, {
field: "LotResults[" + j + "].Result.SD",
title: 'SD'
}]
});
}
columnSchemaAdd.push({ field: "StandardComment", title: 'Comment', editor: standardCommentDropDownEditor, template: "#=StandardComment.Description#" });
columnSchemaAdd.push({ field: "ReviewComment", title: 'Review Comment', editor: reviewCommentDropDownEditor, template: "#=ReviewComment.Description#" });
columnSchemaAdd.push({ command: ["edit", "destroy"] });
Set up the overall grid:
$("#configAddGrid").kendoGrid({
dataSource: gridConfigDataSourceAdd,
height: 550,
navigatable: true,
autoBind: false,
editable: {
mode: "inline"
},
toolbar: ["create"],
columns: columnSchemaAdd
});
Running this code and clicking the 'Add New' button to create a new row produces the following error:
Uncaught TypeError: Cannot read property 'Result' of undefined
I understand why I am getting this error, due to the new item being created with undefined LotResults. What I can't understand is how this can happen when the default values are being set up in the Lot Schema.
Any advice is appreciated, I am hoping someone has used Kendo Grids for the same purpose before as I would really like to get a look at an example which works!
I think the problem is with LotResultsSchema. Instead of creating it as a separate array, can try to merge it to the fields class?
<script>
var Lots = [];
Lots.push({ ID: 13, LotNumber: "158UL" }),
Lots.push({ ID: 14, LotNumber: "646UE" });
var fields1 = {
ID: { editable: false, nullable: true },
ResultDateTime: {
type: "date", validation: {
required: true
}
},
StandardComment: {
ID: {
nullable: true, validation: {
required: false
}
},
Description: {
defaultValue: "<empty>",
validation: {
required: false
}
}
},
ReviewComment: {
ID: {
nullable: true, validation: {
required: false
}
},
Description: {
defaultValue: "<empty>",
validation: {
required: false
}
}
}
};
for (var p = 0; p < Lots.length; ++p) {
fields1['Count' + Lots[p].ID] = {type : "number"};
fields1['Mean'+Lots[p].ID] = {type : "number"};
fields1['SD' +Lots[p].ID] = {type : "number"};
}
var schemaModel = kendo.data.Model.define({
id: "ID",
fields: fields1
});
var gridConfigDataSourceAdd = new kendo.data.DataSource({
data: [],
schema: {
model: schemaModel
}
});
var columnSchemaAdd = [];
columnSchemaAdd.push({ field: "ResultDateTime", format: "{0:yyyy/MM/dd hh:mm:ss}", title: 'Date Time' });
for (var j = 0; j < Lots.length; ++j) {
columnSchemaAdd.push({
title: Lots[j].LotNumber,
field: Lots[j].ID,
columns: [{
field: 'Count' + Lots[j].ID ,
title: 'Count'
},
{
field: 'Mean'+Lots[j].ID ,
title: 'Mean'
}, {
field: 'SD' + Lots[j].ID ,
title: 'SD'
}]
});
}
columnSchemaAdd.push({ field: "StandardComment", title: 'Comment', template: "#=StandardComment.Description#" });
columnSchemaAdd.push({ field: "ReviewComment", title: 'Review Comment', template: "#=ReviewComment.Description#" });
columnSchemaAdd.push({ command: ["edit", "destroy"] });
$("#configAddGrid").kendoGrid({
dataSource: gridConfigDataSourceAdd,
height: 550,
navigatable: true,
autoBind: false,
editable: {
mode: "inline"
},
toolbar: ["create"],
columns: columnSchemaAdd
});
</script>
A sample http://dojo.telerik.com/uHucA

Categories

Resources