Finding an element in an array and adding it to another javascript - javascript

Below is a snippet of the JSON file that I'm working with and in the array "target_indices" you'll see the indices of the data that I want to extract. I seem to be stuck in matching up if the field_index has my target index in it, I want to add it to the const schools. Any help here would be appreciated!
"fields": [{"type":"int","id":"_id"},{"type":"text","id":"Centre Code"},{"type":"text","id":"Centre Name"},{"info":{"notes":"","type_override":"","label":""},"type":"text","id":"Centre Type"},{"type":"text","id":"Centre Status"},{"type":"text","id":"Host Centre Code"},{"type":"text","id":"Host Centre Name"},{"type":"text","id":"Official Low Year Level"},{"type":"text","id":"Official High Year Level"},{"type":"text","id":"Officer In Charge Title"},{"type":"numeric","id":"School Band"},{"type":"timestamp","id":"Show Holiday Date"},{"type":"text","id":"Internet Site"},{"type":"text","id":"Phone Number"},{"type":"text","id":"Restrict Contact Outside Teaching Hours"},{"type":"text","id":"Fax Number"},{"type":"text","id":"Actual Address Line 1"},{"type":"text","id":"Actual Address Line 2"},{"type":"text","id":"Actual Address Line 3"},{"type":"numeric","id":"Actual Address Post Code"},{"type":"text","id":"Postal Address Line 1"},{"type":"text","id":"Postal Address Line 2"},{"type":"text","id":"Postal Address Line 3"},{"type":"numeric","id":"Postal Address Post Code"},{"type":"text","id":"Education Geographic Region"},{"type":"text","id":"Federal Electorate"},{"type":"text","id":"State Electorate"},{"type":"text","id":"Local Government Area"},{"type":"text","id":"Statistical Area Level2"},{"type":"numeric","id":"Statistical Area Level2 Code"},{"type":"text","id":"Remoteness Area"},{"type":"text","id":"Enrolment Effective Date"},{"type":"numeric","id":"All Student Count"},{"type":"text","id":"Campus All Student Count"},{"type":"numeric","id":"ABN"},{"info":{"notes":"","type_override":"","label":""},"type":"text","id":"Sector"},{"type":"text","id":"Non-State Sector"},{"type":"numeric","id":"Longitude"},{"type":"numeric","id":"Latitude"}],
"records":
[2,"0591","Abercorn State School","State School","Open","","","Prep Year","Year 6","Principal",5,"2020-08-10T00:00:00","www.abercornss.eq.edu.au","(07) 4167 5190","Y","(07) 4167 5135","","957 Wuruma Dam Road","Abercorn",4627,"957 Wuruma Dam Road","Abercorn","",4627,"Central Queensland","Flynn","Callide","North Burnett (R)","Monto - Eidsvold",319021508,"Outer Regional Australia","2019 July",18,"",22101246877,"State","",151.127031,-25.135955],
[3,"1275","Abergowrie State School","State School","Open","","","Prep Year","Year 6","Principal",5,"2020-07-03T00:00:00","www.abergowriess.eq.edu.au","(07) 4777 4672","N","(07) 4777 4686","","5 Venables Road","Abergowrie",4850,"5 Venables Road","Abergowrie","",4850,"North Queensland","Kennedy","Hinchinbrook","Hinchinbrook (S)","Ingham Region",318011465,"Remote Australia","2019 July",4,"",87244066343,"State","",145.88351,-18.474697],
fetch('./qldopendata-json/school_locations.json')
.then(response => {
return response.json();
})
.then(schoolData => {
const schools = [];
const target_indices = [2,7,8,12,13,17,18,19,37,38];
schoolData.records.forEach((school_value) => {
const tidied_school = {};
schoolData.fields.forEach((field_name, field_index) => {
tidied_school[field_index] = school_value[field_index]
if (field_index in target_indices){ //this is where i need help
schools.push(tidied_school);
}
})
console.log(schools);
})
})

You can use reduce().
Example below:
const schoolData = { fields: [ { type: "int", id: "_id" }, { type: "text", id: "Centre Code" }, { type: "text", id: "Centre Name" }, { info: { notes: "", type_override: "", label: "" }, type: "text", id: "Centre Type", }, { type: "text", id: "Centre Status" }, { type: "text", id: "Host Centre Code" }, { type: "text", id: "Host Centre Name" }, { type: "text", id: "Official Low Year Level" }, { type: "text", id: "Official High Year Level" }, { type: "text", id: "Officer In Charge Title" }, { type: "numeric", id: "School Band" }, { type: "timestamp", id: "Show Holiday Date" }, { type: "text", id: "Internet Site" }, { type: "text", id: "Phone Number" }, { type: "text", id: "Restrict Contact Outside Teaching Hours" }, { type: "text", id: "Fax Number" }, { type: "text", id: "Actual Address Line 1" }, { type: "text", id: "Actual Address Line 2" }, { type: "text", id: "Actual Address Line 3" }, { type: "numeric", id: "Actual Address Post Code" }, { type: "text", id: "Postal Address Line 1" }, { type: "text", id: "Postal Address Line 2" }, { type: "text", id: "Postal Address Line 3" }, { type: "numeric", id: "Postal Address Post Code" }, { type: "text", id: "Education Geographic Region" }, { type: "text", id: "Federal Electorate" }, { type: "text", id: "State Electorate" }, { type: "text", id: "Local Government Area" }, { type: "text", id: "Statistical Area Level2" }, { type: "numeric", id: "Statistical Area Level2 Code" }, { type: "text", id: "Remoteness Area" }, { type: "text", id: "Enrolment Effective Date" }, { type: "numeric", id: "All Student Count" }, { type: "text", id: "Campus All Student Count" }, { type: "numeric", id: "ABN" }, { info: { notes: "", type_override: "", label: "" }, type: "text", id: "Sector", }, { type: "text", id: "Non-State Sector" }, { type: "numeric", id: "Longitude" }, { type: "numeric", id: "Latitude" }, ], records: [ [ 2, "0591", "Abercorn State School", "State School", "Open", "", "", "Prep Year", "Year 6", "Principal", 5, "2020-08-10T00:00:00", "www.abercornss.eq.edu.au", "(07) 4167 5190", "Y", "(07) 4167 5135", "", "957 Wuruma Dam Road", "Abercorn", 4627, "957 Wuruma Dam Road", "Abercorn", "", 4627, "Central Queensland", "Flynn", "Callide", "North Burnett (R)", "Monto - Eidsvold", 319021508, "Outer Regional Australia", "2019 July", 18, "", 22101246877, "State", "", 151.127031, -25.135955, ], [ 3, "1275", "Abergowrie State School", "State School", "Open", "", "", "Prep Year", "Year 6", "Principal", 5, "2020-07-03T00:00:00", "www.abergowriess.eq.edu.au", "(07) 4777 4672", "N", "(07) 4777 4686", "", "5 Venables Road", "Abergowrie", 4850, "5 Venables Road", "Abergowrie", "", 4850, "North Queensland", "Kennedy", "Hinchinbrook", "Hinchinbrook (S)", "Ingham Region", 318011465, "Remote Australia", "2019 July", 4, "", 87244066343, "State", "", 145.88351, -18.474697, ], ], };
const targetIndices = [2, 7, 8, 12, 13, 17, 18, 19, 37, 38];
const schools = schoolData.records.reduce((a, b) => {
const requiredObject = targetIndices.reduce((acc, t) => {
acc.push(b[t]);
return acc;
}, []);
a.push(requiredObject);
return a;
}, []);
console.log(schools);

Hope this helps you out. You will need to create the target_indices_names manually with this, there is probably another way to do it dynamically, but since it is only 10 properties.
var schoolData = '[[2,"0591","Abercorn State School","State School","Open","","","Prep Year","Year 6","Principal",5,"2020-08-10T00:00:00","www.abercornss.eq.edu.au","(07) 4167 5190","Y","(07) 4167 5135","","957 Wuruma Dam Road","Abercorn",4627,"957 Wuruma Dam Road","Abercorn","",4627,"Central Queensland","Flynn","Callide","North Burnett (R)","Monto - Eidsvold",319021508,"Outer Regional Australia","2019 July",18,"",22101246877,"State","",151.127031,-25.135955],'+
'[3,"1275","Abergowrie State School","State School","Open","","","Prep Year","Year 6","Principal",5,"2020-07-03T00:00:00","www.abergowriess.eq.edu.au","(07) 4777 4672","N","(07) 4777 4686","","5 Venables Road","Abergowrie",4850,"5 Venables Road","Abergowrie","",4850,"North Queensland","Kennedy","Hinchinbrook","Hinchinbrook (S)","Ingham Region",318011465,"Remote Australia","2019 July",4,"",87244066343,"State","",145.88351,-18.474697]]'
var parsedSchoolData = JSON.parse(schoolData);
const schools = [];
const target_indices_names = ['one','two','three','four','five','six','seven','eight', 'nine', 'ten'];
const target_indices = [2,7,8,12,13,17,18,19,37,38];
parsedSchoolData.forEach(element => {
// New Object
var obj = new Object();
// Pass through all Target Indices
target_indices.forEach(neededIndex => {
console.log(neededIndex);
var propertyName = target_indices_names[target_indices.indexOf(neededIndex)];
// Set Property to Value
obj[propertyName] = element[neededIndex];
});
// Push/Add the created Object to the list
schools.push(obj);
});
console.log(schools[0]);

Related

Express - Find an object in MongoDB by id and save its data to array

I have two models: Meal and Ingredient. Here are the schemas:
const mealSchema = new Schema({
title: { type: String, required: true },
image: { type: String, required: false },
ingredients: [{
ingredient: { type: mongoose.Types.ObjectId, required: true, ref: 'Ingredient' },
amount: { type: Number, required: true }
}],
})
const ingredientSchema = new Schema({
name: { type: String, required: true },
unit: { type: String, required: true },
category: { type: String, required: false },
is_vege: { type: Boolean, required: true }
});
When I create the meal, I provide the ingredients as an array in POST request body.
const createMeal = async (req, res, next) => {
const { title, ingredients } = req.body;
// ingredientArray consists of objects with two keys:
// <String> ingredient - id of the associated ingredient in database
// <Number> amount - amount of the ingredient
ingredientArray = JSON.parse(ingredients)
const createdMeal = new Meal({
title,
image: req.file.path,
ingredients: ingredientArray
});
try {
await createdMeal.save();
} catch (err) {
const error = new HttpError('Error occurred, try again later', 500);
return next(error);
}
res.status(201).json(createdMeal);
}
This is the object that is created:
{
"_id": "62ea4531bd7e04fa740e2fee",
"title": "Spaghetti",
"image": "uploads\\images\\8da09ec6-3684-4af5-a513-f90155ddafd8.jpeg",
"ingredients": [
{
"ingredient": "62ea37251212c738a0ce9cee",
"amount": 100,
"_id": "62ea4531bd7e04fa740e2fef",
"id": "62ea4531bd7e04fa740e2fef"
},
{
"ingredient": "62ea371ab9392f3e0107c541",
"amount": 10,
"_id": "62ea4531bd7e04fa740e2ff0",
"id": "62ea4531bd7e04fa740e2ff0"
}
],
"__v": 0,
"id": "62ea4531bd7e04fa740e2fee"
}
I need my "ingredients" list to find the actual ingredient in the database and save its complete data so that the result would look something like this:
"ingredients": [
{
"ingredient": "62ea37251212c738a0ce9cee",
"amount": 100,
"name": "Pasta",
"unit": "g",
"category": "pastas",
"is_vege": true,
"_id": "62ea4531bd7e04fa740e2fef",
"id": "62ea4531bd7e04fa740e2fef"
},
{
"ingredient": "62ea371ab9392f3e0107c541",
"amount": 200,
"name": "Tomato",
"unit": "g",
"category": "vegetables",
"is_vege": true,
"_id": "62ea4531bd7e04fa740e2ff0",
"id": "62ea4531bd7e04fa740e2ff0"
}
]
EDIT: Ideally, the ingredient should be found BEFORE saving, because I want to run some calculations before the meal ends up in the database.
I figured it out. It took a single line of code:
let createdMeal = new Meal({
title,
image: req.file.path,
prep_time,
ingredients: ingredientArray
});
createdMeal = await createdMeal.populate({ path: 'ingredients.ingredient' });
Documentation:
https://mongoosejs.com/docs/populate.html

Filter an array of objects based on another [TS/JS]

I have two dropdowns - where each dropdown should filter an objects key. The dropdowns should not exclude each other, or both values from dropdown should work indenpentedly from each other (ie both dropdown values does not need to be true for filtering).
When I select an item from the dropdown, I get one array with two objects, for each dropdown:
[
{
"name": "Type",
"value": [
"calibration"
],
"selected": [
{
"text": "calibration"
}
]
},
{
"name": "Function group",
"value": [
"1 - Test",
"2 - Programming"
],
"selected": [
{
"text": "1 - Test"
}
]
}
]
Above shows two objects, for the two different dropdowns - one with name "type" and one with "Function group".
The "value" in the object above is all of the dropdown items.
"selected" holds the selected item from the dropdown and the filtering should be based on that.In this case we have selected "calibration" and "Test".
The "type" dropdown should filter on the data "category" field while the "function group" should filter on "groupDescription" field. The data that needs to be filtered based on the mentioned keyes and selected values looks like this:
const mockData = [
{
operationDetails: {
id: '5119-03-03-05',
number: '41126-3',
description: 'Clutch wear, check. VCADS Pro operation',
category: 'calibration', //type dropdown
languageCode: 'en',
countryCode: 'GB'
},
functionDetails: {
groupId: 411,
groupDescription: 'Test', //function group dropdown
languageCode: '',
countryCode: ''
},
lastPerformed: '2021-02-22',
time: 20,
isFavorite: false
}
,
{
operationDetails: {
id: '5229-03-03-05',
number: '41126-3',
description: 'Defective brake pad',
category: 'calibration', ///type dropdown
languageCode: 'en',
countryCode: 'GB'
},
functionDetails: {
groupId: 411,
groupDescription: 'Programming', //function group dropdown
languageCode: '',
countryCode: ''
},
lastPerformed: '2020-01-22',
time: 20,
isFavorite: false
}
]
Playground with mock data and response example from dropdown here.
How to filter the data based on the values from the dropdown objects, for each key its responsible for?
It's not the prettiest code, but it does work. The one thing that you'd want to watch out for is the regex. It would be better to not have to parse and do a straight match like category, but if your cases are static then you should be able to figure out if this will work every time. It would also be nice to have a field key in filterDetails so you know which field to try to match in the actual data and you could program that in.
const filterDetails = [
{
name: "Type",
value: ["calibration"],
selected: [
{
text: "calibration",
},
],
},
{
name: "Function group",
value: ["1 - Test", "2 - Programming"],
selected: [
{
text: "Test",
},
],
},
];
const mockData = [
{
operationDetails: {
id: "5119-03-03-05",
number: "41126-3",
description: "Clutch wear, check. VCADS Pro operation",
category: "calibration", //type
languageCode: "en",
countryCode: "GB",
},
functionDetails: {
groupId: 411,
groupDescription: "Test", //function group
languageCode: "",
countryCode: "",
},
lastPerformed: "2021-02-22",
time: 20,
isFavorite: false,
},
{
operationDetails: {
id: "5229-03-03-05",
number: "41126-3",
description: "Defective brake pad",
category: "calibration", ///type
languageCode: "en",
countryCode: "GB",
},
functionDetails: {
groupId: 411,
groupDescription: "Programming", //function group
languageCode: "",
countryCode: "",
},
lastPerformed: "2020-01-22",
time: 20,
isFavorite: false,
},
];
console.log(
"filtered mockData: ",
mockData.filter(({ operationDetails, functionDetails }) => {
let groupDescriptionMatch = false;
let categoryMatch = false;
for (const details of filterDetails) {
if (
details.name === "Type" &&
details.selected[0].text === operationDetails.category
)
categoryMatch = true;
if (details.name === "Function group") {
let parsedGroup = details.selected[0].text.match(/[a-zA-Z]+/g);
if (parsedGroup[0] === functionDetails.groupDescription) {
groupDescriptionMatch = true;
}
}
}
return groupDescriptionMatch && categoryMatch;
})
);

How to query an array in mongodb

Was trying to filter an array with another condition to query my MongoDB database
I have tried using the elemMatch to match exactly with the query, but it not working out.
Here is my code
my shipment schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const ShipmentSchema = new Schema({
warehouseNo:{
type: String,
ref: 'users.unitNo'
},
packages:[
{
category:{
type: String
},
quantity:{
type: String
},
description:{
type: String
},
trackingno:{
type: String,
},
date:{
type: Date,
default: Date.now
},
length:{
type: Number
},
width:{
type: Number
},
height:{
type: Number
},
weight:{
type: Number
},
fee:{
type: Number,
},
status: {
type: String,
default: "In warehouse"
},
},
],
shippingMode:{
type: String,
},
date:{
type: Date,
default: Date.now
}
});
module.exports = Shipments = mongoose.model('shipments', ShipmentSchema);
Here is my node js.
// #route GET api/user/package
// #desc Get all package
// #access Private
router.get('/package',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const errors = {};
Shipments.findOne({warehouseNo : req.user.unitNo})
.then(shipments => {
if (shipments.packages.length === 0) {
errors.nopackages = 'There are no packages for you yet';
return res.status(404).json(errors);
}
res.json(shipments.packages);
})
});
The code above bring every record in my mongoddb, but if i tried the below, where i ask it to fillter by package status. i got a code crash error
// #route GET api/user/package
// #desc Get all package
// #access Private
router.get('/package',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const errors = {};
Shipments.find({warehouseNo : req.user.unitNo, "packages.status": "In warehouse"})
.then(shipments => {
if (shipments.packages.length === 0) {
errors.nopackages = 'There are no packages for you yet';
return res.status(404).json(errors);
}
res.json(shipments.packages);
})
});
i expect to get something like this
{
"status": "In warehouse",
"date": "2019-09-11T10:19:02.834Z",
"_id": "5d78ca160e47be29e13253b5",
"category": "liquid",
"quantity": "10 pieces",
"description": "garri",
"trackingno": "MHS085533395",
"weight": 123,
"length": 12,
"height": 12,
"width": 13
}
instead i got this
[
{
"status": "Shipped",
"date": "2019-09-11T10:17:46.485Z",
"_id": "5d78c9ca0e47be29e13253b4",
"category": "liquid",
"quantity": "10 pieces",
"description": "garri",
"trackingno": "SDG561920753",
"weight": 123,
"height": 12,
"width": 13
},
{
"status": "In warehouse",
"date": "2019-09-11T10:19:02.834Z",
"_id": "5d78ca160e47be29e13253b5",
"category": "liquid",
"quantity": "10 pieces",
"description": "garri",
"trackingno": "MHS085533395",
"weight": 123,
"length": 12,
"height": 12,
"width": 13
}
]
You should use $elemMatch inside the key packages, i.e. db.getCollection('shipments').find( {warehouseNo: "123"},
{ packages: { $elemMatch: { status: "In warehouse" }}}).
For Example:
I have a collection as below:
{
"_id" : 1.0,
"name" : {
"first" : "John",
"last" : "Backus"
},
"birth" : ISODate("1924-12-03T05:00:00.000Z"),
"death" : ISODate("2007-03-17T04:00:00.000Z"),
"contribs" : [
"Fortran",
"ALGOL",
"Backus-Naur Form",
"FP"
],
"awards" : [
{
"award" : "W.W. McDowell Award",
"year" : 1967.0,
"by" : "IEEE Computer Society"
},
{
"award" : "National Medal of Science",
"year" : 1975.0,
"by" : "National Science Foundation"
},
{
"award" : "Turing Award",
"year" : 1977.0,
"by" : "ACM"
},
{
"award" : "Draper Prize",
"year" : 1993.0,
"by" : "National Academy of Engineering"
}
]
}
Using query like this:
db.getCollection('bios').find( {_id: 1.0 },
{ awards: { $elemMatch: { year: 1967.0 }}})
Gave me a result:
{
"_id" : 1.0,
"awards" : [
{
"award" : "W.W. McDowell Award",
"year" : 1967.0,
"by" : "IEEE Computer Society"
}
]
}
Hope this will help you.
You defined warehouseNo as reference from other table. It must be some ID. Please make sure you are comparing the same

JQXMenu Databind with JSON

I am developing an application where I need to fetch the menu items from a text file.
I am new to JQX.
But while displaying the records its showing nothing.
My Text File(LeftMenu.txt) as below:
[{
"text": "Menu1",
"id": "1",
"parentid": "-1"
},
{
"text": "Menu2",
"id": "2",
"parentid": "-1"
},
{
"text": "Menu3",
"id": "3",
"parentid": "-1"
}
]
==========================================================================
The code is here under
// prepare the data for Left Menu
var urlleftpanel = "../../Public/sampledata/leftmenu.txt";
var sourceleftmenu =
{
datatype: "json",
datafields: [
{ name: 'id' },
{ name: 'parentid' },
{ name: 'text' }
],
id: 'id',
url: urlleftpanel
};
// create data adapter.
var dataAdapter1 = new $.jqx.dataAdapter(sourceleftmenu);
// perform Data Binding.
dataAdapter1.dataBind();
var records = dataAdapter1.getRecordsHierarchy('id', 'parentid', 'items', [{ name: 'text', map: 'label' }]);
var records = da.records;
$('#jqxWidget').jqxMenu({ source: records , height: 53, theme: theme, width: '95px' });
=====================================================================================
Please Help its very urgent
Thanks in Advance
Try setting async: false in the source object.
var sourceleftmenu =
{
datatype: "json",
async: false,
datafields: [
{ name: 'id' },
{ name: 'parentid' },
{ name: 'text' }
],
id: 'id',
url: urlleftpanel
};

get values from different arrays javascript

I am using yahoo's placemaker to extract location names from text. From this I get a callback function which gives me 2 different types of arrays.
this is the code am using but I CANT ANY of the values I want.
Placemaker.getPlaces(text,function(o){
if (typeof o.match!=='undefined' && o.match.length==1){
latitude=o.match.place.centroid.latitude, longitude=o.match.place.centroid.longitude;
console.log(latitude,longitude);}
if(typeof o.match !=='undefined'&& o.match.length==2){
latitude=o[match].place.centroid.latitude,
longitude=o[match].place.centroid.longitude;
console.log(latitude,longitude);
}
The first array looks like this
({
match: {
place: {
woeId: "29007292",
type: "Town",
name: "Jubila, West Bengal, IN",
centroid: {
latitude: "23.1626",
longitude: "87.7889"
}
},
reference: [{
woeIds: "29007292",
placeReferenceId: "2",
placeIds: "1",
start: "14",
end: "20",
isPlaintextMarker: "1",
text: "jubila",
type: "plaintext",
xpath: null
}, {
woeIds: "29007292",
placeReferenceId: "3",
placeIds: "1",
start: "82",
end: "88",
isPlaintextMarker: "1",
text: "jubila",
type: "plaintext",
xpath: null
}]
}
})
and the other one like this
({
match: [{
place: {
woeId: "23424950",
type: "Country",
name: "Spain",
centroid: {
latitude: "39.8949",
longitude: "-2.98831"
}
},
reference: {
woeIds: "23424950",
placeReferenceId: "1",
placeIds: "1",
start: "64",
end: "70",
isPlaintextMarker: "1",
text: "Espa\xF1a",
type: "plaintext",
xpath: null
}
}, {
place: {
woeId: "24865675",
type: "Continent",
name: "Europe",
centroid: {
latitude: "52.9762",
longitude: "7.85784"
}
},
reference: {
woeIds: "24865675",
placeReferenceId: "2",
placeIds: "2",
start: "93",
end: "99",
isPlaintextMarker: "1",
text: "Europa",
type: "plaintext",
xpath: null
}
}]
})
change
if (typeof o.match!=='undefined' && o.match.length==1){
to
if (typeof o.match!=='undefined'){
For second:
for(var i in o.match) {
console.log(o.match[i].place.centroid.latitude); //wil show all lat's in loop
}
or if you want first lattitude only:
console.log(o.match[0].place.centroid.latitude); //will show only first lat

Categories

Resources