Mongo Dynamic Search Keys And Value Query - javascript

How can query in Mongo DB , by the way I am using Keystone JS. I wanted to filter or get result from the Vehicle Model where keys and values from for example { 'Year' => '2019,2018', 'Make' => 'Acura,BMW' } . It will filter where year = 2019 , 2018 same with the Make.
My current code
view.on('init', function (next) {
var q = keystone.list('Vehicle').paginate({
page: req.query.page || 1,
perPage: 10,
maxPages: 10,
filters: {
state: 'published',
},
})
.sort('-publishedDate')
if (locals.filters.searchkeys) {
let urlSearchParams = new URLSearchParams(locals.filters.searchkeys)
for (var key of urlSearchParams.keys()) {
console.log("The Key :" , key)
//this part is where it would be dynamic
q.where('Year').in();
}
}
Search Param
{ 'Year' => '2019,2018', 'Make' => 'Acura,BMW' }
Collection
{ total: 12,
results:
[ { _id: 5d6893cdc02d0e3020f84c85,
DriveType: 'FWD',
FuelType: 'Gasoline Fuel',
ImageList:
'',
Options:
'Traction Control,Stability Control,Front Wheel Drive,Tires - Front All-Season,Tires - Rear All-Season,Aluminum Wheels,Power Steering,4-Wheel Disc Brakes,ABS,Brake Assist,Sun/Moonroof,Generic
Sun/Moonroof,Rear Spoiler,Automatic Headlights,Fog Lamps,Heated Mirrors,Power Mirror(s),Privacy Glass,Intermittent Wipers,Variable Speed Intermittent Wipers,Leather Seats,Power Driver Seat,Bucket Seats,Heated Front Seat(s),Driver Adjustable Lumbar,Passenger Adjustable Lumbar,3rd Row Seat,Pass-Through Rear Seat,Floor Mats,Steering Wheel Audio Controls,Adjustable Steering Wheel,Engine Immobilizer,Tire Pressure Monitor,Power Windows,Power Door Locks,Universal Garage Door Opener,Keyless Entry,Cruise Control,Security System,Climate Control,A/C,Rear A/C,Rear Defrost,AM/FM Stereo,CD Changer,CD Player,Satellite Radio,Entertainment System,Power Outlet,Driver Vanity Mirror,Passenger Vanity Mirror,Driver Illuminated Vanity Mirror,Passenger Illuminated Visor Mirror,Rear Reading Lamps,Driver Air Bag,Passenger Air Bag,Front Side Air Bag,Passenger Air Bag Sensor,Front Head Air Bag,Rear Head Air Bag,Child Safety Locks',
Description: '',
DateInStock: '7/15/2019',
Invoice: 3000,
BookValue: '3686',
MSRP: 0,
SellingPrice: 5592,
Miles: 162111,
Transmission: 'Automatic',
EngineDisplacement: '3.5L',
EngineCylinders: '6',
InteriorColor: '',
ExteriorColor: 'Gray',
Doors: 4,
ModelNumber: 'YF2867JNW',
Trim: 'Ex-L',
Body: 'Convertible',
Model: 'Pilot',
Make: 'Honda',
Year: 2007,
VIN: '5FNYF28677B037628',
Stock: 'K2501A',
Type: 'Used',
image_gallery: [],
__v: 0,
CategorizedOptions: '',
Comment: '',
name: '',
publishedDate: null,
content: [Object],
categories: [],
image: [Object],
state: 'published',
Certified: true } ],
currentPage: 1,
totalPages: 2,
pages: [ 1, 2 ],
previous: false,
next: 2,
first: 1,
last: 1 }

let's say query is request params coming to backend as
let request={'Year':'2019,2018', 'Make':'Acura,BMW'}
let query={}
if(request.Year){
let year=request.Year.split(',') // will give array ['2019','2018']
for(let i=0;i<year.length;i++){ //for making array of nos [2019,2018]
year[i]=parseInt(year[i])
}
query.Year={$in:year} // {$in:['2019','2018']}
}
if(request.Make){
query.Make={$in:request.Make.split(',')} // {$in:['Acura','BMW']}
}
var Vehicle = keystone.list('Vehicle');
let q= Vehicle.model.find(query)
.where('state', 'published')
.populate('author')
.sort('-publishedAt')
.limit(5)
.exec(function(err, posts) {
// do something with posts
});

Related

How can I update the quantity property of a cart item object in this Angular 13 e-commerce app?

I am working on an e-commerce app who's front-end is made in Angular 13.
The below code is intended to sum the prices of the items in the cart:
import { Component, OnInit } from '#angular/core';
#Component({
selector: '.app-top-cart',
templateUrl: './top-cart.component.html',
styleUrls: ['./top-cart.component.css']
})
export class TopCartComponent implements OnInit {
cartItems: any = [
{
id: 1,
title: "iPhone 9",
description: "An apple mobile which is nothing like apple",
price: 549,
discountPercentage: 12.96,
rating: 4.69,
stock: 94,
brand: "Apple",
category: "smartphones",
thumbnail: "https://dummyjson.com/image/i/products/1/thumbnail.jpg",
images: [
"https://dummyjson.com/image/i/products/1/1.jpg",
"https://dummyjson.com/image/i/products/1/2.jpg",
]
},
{
id: 2,
title: "iPhone X",
description: "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...",
price: 899,
discountPercentage: 17.94,
rating: 4.44,
stock: 34,
brand: "Apple",
category: "smartphones",
thumbnail: "https://dummyjson.com/image/i/products/2/thumbnail.jpg",
images: [
"https://dummyjson.com/image/i/products/2/1.jpg",
"https://dummyjson.com/image/i/products/2/2.jpg",
]
},
{
id: 3,
title: "Samsung Universe 9",
description: "Samsung's new variant which goes beyond Galaxy to the Universe",
price: 1248,
discountPercentage: 15.46,
rating: 4.09,
stock: 36,
brand: "Samsung",
category: "smartphones",
thumbnail: "https://dummyjson.com/image/i/products/3/thumbnail.jpg",
images: [
"https://dummyjson.com/image/i/products/3/1.jpg"
]
},
];
constructor() { }
totalPrice: number = 0;
doTotalPrice(){
let total = 0;
this.cartItems.forEach((item: { price: number, quantity: number }) => {
item.quantity = 1;
total += item.price * item.quantity
});
this.totalPrice = total;
}
ngOnInit(): void {
this.doTotalPrice();
}
}
The goal
Whenever a new item is added to the cartItems array, if the item already exists in the array, I don't want duplicate items, I want a quantity update.
Stackblitz
You can see the full code HERE.
The problem
I have not been able to find a way to update item.quantity whenever one more piece of a product is added to the cart.
How can I update the quantity count?
you could create a Map called "basket", the key is the item ID.
when you add an item to the basket you can check if the item doesn't exist in the map, if so, add the item to the map and set quantity to 1.
Otherwise you don't need to add it to the map but increase the quantity.
another solution would be the use of an array and just push the items in the array. In the end you can count the occurences in the array.
Take another approach, where you create an array of available items, and an array of cart items. This should be way clearer to you.
allItems = [{
id: 1,
title: 'iPhone 9',
// ...
}];
cartItems = [];
// ...
addItemToCart(item) {
this.cartItems.push(item);
}
// ...
get totalPrice() {
return this.cartItems.reduce((p, { price }) => p + price, 0);
}

I am trying to loop through an array and find each object that has said keyword in a property

So I want to set this variable to all of the objects in an array in which its category has a certain keyword.
This is what I have so far
let tempMensProducts = tempClothingProducts
.filter(obj => obj.category.includes('Mens'))
export const clothingProducts = [
{
id: 1,
title: 'COMME DES GARCONS TEE',
img: 'img/product-1.png',
img2: 'img/product-1-1.png',
img3: 'img/product-1-2.png',
img4: 'img/product-1-3.png',
luxury: 'All Luxury items are inspected to verify authenticity',
price: 200,
info: ' COMME DES GARCONS PLAY BASIC LOGO TEE',
inCart: false,
count: 0,
total: 0,
fabric: '100% Cotton',
category: 'Mens Fashion'
}
]
You need to pass a callback to map to use it - but here, map isn't required at all. Just use filter.
let tempMensProducts = tempClothingProducts.filter(({ category }) => category.includes("Mens"));
If you try to use map without a callback, it'll result in an error as it tries to call its argument, and if you don't pass one, it'll try to do undefined().
[1, 2, 3].map();
You can split the array by whitespaces and then apply array contains there to sure that it will give you correct result
I mean to say it should not return "Women" when keyword is "men"
let clothingProducts = [
{
id: 1,
title: 'COMME DES GARCONS TEE',
img: 'img/product-1.png',
img2: 'img/product-1-1.png',
img3: 'img/product-1-2.png',
img4: 'img/product-1-3.png',
luxury: 'All Luxury items are inspected to verify authenticity',
price: 200,
info: ' COMME DES GARCONS PLAY BASIC LOGO TEE',
inCart: false,
count: 0,
total: 0,
fabric: '100% Cotton',
category: 'Mens Fashion'
},
{
id: 2,
title: 'COMME DES GARCONS TEE',
img: 'img/product-1.png',
img2: 'img/product-1-1.png',
img3: 'img/product-1-2.png',
img4: 'img/product-1-3.png',
luxury: 'All Luxury items are inspected to verify authenticity',
price: 200,
info: ' COMME DES GARCONS PLAY BASIC LOGO TEE',
inCart: false,
count: 0,
total: 0,
fabric: '100% Cotton',
category: 'woMens Fashion'
}
]
let filter = clothingProducts.filter(c => c.category.split(" ").includes("Mens"));
console.log(filter);

Using reduce to count groups of data within groups of data

As the title says, I'm trying to count groups of data within groups of data: My logic is to group all the data into states, then group date into years. so that the output should look like something like:
state,year,count
mo,1910,2
in,1910,1
il,1910,3
or,1910,4
co,1910,2
nd,1910,1
...
mo,1911,5
in,1911,4
il,1911,6
or,1911,2
co,1911,8
The CSV I'm using has a lot more columns that needed, I'm only interested in the columns state and year. My code below isn't working, any help would be great.
const countStates = filteredData.reduce((m, d) => {
if(!m[d.year]){
m[d.year] = {...d, count: 1};
return m;
}
m[d.state];
m[d.year];
m[d.year].count += 1;
return m;
},{});
const countedStates = Object.keys(countStates).map((k) => {
const item = countStates[k];
return {
state: item.state,
year: item.year,
count: item.count
}
})
Edit
Example of the dataset I'm using:
datetime,city,state,country,shape,duration (seconds),duration (hours/min),comments,date posted,latitude,longitude
10/10/1949 20:30,san marcos,tx,us,cylinder,2700,45 minutes,"This event took place in early fall around 1949-50. It occurred after a Boy Scout meeting in the Baptist Church. The Baptist Church sit",4/27/2004,29.8830556,-97.9411111
10/10/1949 21:00,lackland afb,tx,,light,7200,1-2 hrs,"1949 Lackland AFB&#44 TX. Lights racing across the sky & making 90 degree turns on a dime.",12/16/2005,29.38421,-98.581082
10/10/1955 17:00,chester (uk/england),,gb,circle,20,20 seconds,"Green/Orange circular disc over Chester&#44 England",1/21/2008,53.2,-2.916667
10/10/1956 21:00,edna,tx,us,circle,20,1/2 hour,"My older brother and twin sister were leaving the only Edna theater at about 9 PM&#44...we had our bikes and I took a different route home",1/17/2004,28.9783333,-96.6458333
10/10/1960 20:00,kaneohe,hi,us,light,900,15 minutes,"AS a Marine 1st Lt. flying an FJ4B fighter/attack aircraft on a solo night exercise&#44 I was at 50&#44000&#39 in a "clean" aircraft (no ordinan",1/22/2004,21.4180556,-157.8036111
10/10/1961 19:00,bristol,tn,us,sphere,300,5 minutes,"My father is now 89 my brother 52 the girl with us now 51 myself 49 and the other fellow which worked with my father if he&#39s still livi",4/27/2007,36.5950000,-82.1888889
10/10/1965 21:00,penarth (uk/wales),,gb,circle,180,about 3 mins,"penarth uk circle 3mins stayed 30ft above me for 3 mins slowly moved of and then with the blink of the eye the speed was unreal",2/14/2006,51.434722,-3.18
10/10/1965 23:45,norwalk,ct,us,disk,1200,20 minutes,"A bright orange color changing to reddish color disk/saucer was observed hovering above power transmission lines.",10/2/1999,41.1175000,-73.4083333
10/10/1966 20:00,pell city,al,us,disk,180,3 minutes,"Strobe Lighted disk shape object observed close&#44 at low speeds&#44 and low altitude in Oct 1966 in Pell City Alabama",3/19/2009,33.5861111,-86.2861111
10/10/1966 21:00,live oak,fl,us,disk,120,several minutes,"Saucer zaps energy from powerline as my pregnant mother receives mental signals not to pass info",5/11/2005,30.2947222,-82.9841667
10/10/1968 13:00,hawthorne,ca,us,circle,300,5 min.,"ROUND &#44 ORANGE &#44 WITH WHAT I WOULD SAY WAS POLISHED METAL OF SOME KIND AROUND THE EDGES .",10/31/2003,33.9163889,-118.3516667
10/10/1968 19:00,brevard,nc,us,fireball,180,3 minutes,"silent red /orange mass of energy floated by three of us in western North Carolina in the 60s",6/12/2008,35.2333333,-82.7344444
10/10/1970 16:00,bellmore,ny,us,disk,1800,30 min.,"silver disc seen by family and neighbors",5/11/2000,40.6686111,-73.5275000
And the code I used to filter out the data:
fs.createReadStream('./data/scrubbed.csv')
.pipe(readCSV())
.on('data', (data) => CSV.push(data))
.on('end', () => {
let data = CSV.map((d) => {
return {
year: new Date (d.datetime).getFullYear(),
state: d.state,
country: d.country
}
});
filteredData = data.filter((d) => {
return d.state !== "" && d.country === "us"
})
Which returns this (an example of the dataset):
[ { year: 1949, state: 'tx', country: 'us' },
{ year: 1956, state: 'tx', country: 'us' },
{ year: 1960, state: 'hi', country: 'us' },
{ year: 1961, state: 'tn', country: 'us' },
{ year: 1965, state: 'ct', country: 'us' }...
The above is what I'm trying to group twice using reduce
The below code gets an array of states with the year and using reduce we are getting the count of each state grouped by year as
var data = [
{ year: '1910', state: 'mo', country: 'us' },
{ year: '1910', state: 'in', country: 'us' },
{ year: '1910', state: 'il', country: 'us' },
{ year: '1910', state: 'mo', country: 'us' },
{ year: '1911', state: 'in', country: 'us' },
{ year: '1911', state: 'il', country: 'us' },
{ year: '1911', state: 'mo', country: 'us' },
{ year: '1911', state: 'in', country: 'us' }
];
var organizedData = data.reduce((acc, val, index) => {
acc[val.state] = acc[val.state] || {};
acc[val.state][val.year] = (+acc[val.state][val.year] || 0) + 1;
return acc;
}, {});
console.log(organizedData);

Split object into multiple ordered arrays based on identity of 1 spesific value

Not quite sure if that title was the best I could do.
I'm a pretty new to js and keep running into problems ... I hope some of you have the time to give me a pointer or two on this scenario.
I have several objects that looks pretty much like this - except from the fact that there are 28 instances of every "room" type. I need to split this object into multiple objects - one for each "room" type. In some of my objects there are only one room type - whilst in others there are 3 or 4.
[ { id: 1
created: 2018-12-29T13:18:05.788Z,
room: 'Double Room'
type: 'Standard'
price: 500
},
{ id: 29
created: 2018-12-29T13:18:05.788Z,
room: 'Twin Room'
type: 'Standard'
price: 500
},
{ id: 58
created: 2018-12-29T13:18:05.788Z,
room: 'Family Room'
type: 'Standard'
price: 900
},
]
Oh, and it's important that the instances don't "loose" their order in the array - since it's date related and need to be presentet in an ascending order. And vanilla js only.
Is array.map() the function I'm looking for to solve this problem? Is it posible to do this without iteration?
My final goal is to create some kind of generic function that can sort this out for all my objects.
And guys: happy hollidays!
You could take an object as hash table for the wanted groups. Then iterate the objects and assign the object to the group. If the group does not exist, create a new group with an array.
function groupBy(array, key) {
var groups = Object.create(null);
array.forEach(o => (groups[o[key]] = groups[o[key]] || []).push(o));
return groups;
}
var data = [{ id: 1, created: '2018-12-29T13:18:05.788Z', room: 'Double Room', type: 'Standard', price: 500 }, { id: 29, created: '2018-12-29T13:18:05.788Z', room: 'Twin Room', type: 'Standard', price: 500 }, { id: 58, created: '2018-12-29T13:18:05.788Z', room: 'Family Room', type: 'Standard', price: 900 }],
groupedByRoom = groupBy(data, 'room');
console.log(groupedByRoom);
.as-console-wrapper { max-height: 100% !important; top: 0; }

JSON to AS3 Object issue

I am new to JSON to AS3 Objects and am having issues trying to create an AS3 object that I can reference. Here is the JSON:
{
demo: {
Male: {
21-30: 2,
31-40: 0,
41-50: 0,
51-60: 0,
61-70: 0,
71-80: 0,
81+: 0
},
Female: {
21-30: 7,
31-40: 0,
41-50: 0,
51-60: 0,
61-70: 0,
71-80: 0,
81+: 0
}
},
days: 0
}
Here is the parsing code:
var JSONRequest: URLRequest = new URLRequest();
JSONRequest.method = URLRequestMethod.POST;
JSONRequest.url = "https://www.urlhere.com;
var loader: URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, handleResponse);
loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
loader.load(JSONRequest);
function handleResponse(event:Event):void{
var returnData:String = loader.data;
var parsedData:Object = JSON.parse(returnData);
}
I have tried and successfully looped through the object with for loops, but I don't want to have to do that, I want to be able to access the data as an object or array by accessing the properties in dot syntax. Object[0].property etc...
The really tricky part is that I don't know how large or how deep the data is nested. The one I added here is simple.
Here is more like what I will be getting:
{
products: {
Home & Garden: {
Kitchen: {
202: {
brand: "OXO",
description: "12 piece locktop container set",
descriptionLong: "Prepping, cooking and cleaning",
listPrice: "36.32",
sku: "925776",
upc: "719812032528"
},
238: {
brand: "Excalibur",
description: "Excalibur 2400 4-Tray Dehydrator",
descriptionLong: "Dehydration is the healthiest",
listPrice: "168.54",
sku: "947741",
upc: "029743240009"
},
352: {
brand: "Nostalgia",
description: "OldFashioned Kettle Corn Maker",
descriptionLong: "With the Nostalgia Electrics ",
listPrice: "35.49",
sku: "925843",
upc: "082677300218"
},
370: {
brand: "Joseph Joseph",
description: "Nest Plus Measuring (Set of 5 Cups - Multi Coloured)",
descriptionLong: "Nestâ„¢ Cups are a range of 5",
listPrice: "2.46",
sku: "926733",
upc: "5028420400342"
},
605: {
brand: "Nostalgia",
description: "Margarator-Frozen Drink Maker",
descriptionLong: "Mix up great-tasting margaritas",
listPrice: "140.68",
sku: "925851",
upc: "082677135889"
}
},
Housewares: {
206: {
brand: "Dyson",
description: "Dyson DC44 Animal",
descriptionLong: "DC44 Animal has a detachable",
listPrice: "406.51",
sku: "922846",
upc: "879957006362"
}
}
}
I will also add that I can request the formatting of the JSON I am receiving, so if there is a better way to format the data coming from the server, I am open to that.
Any help would be great.
I want to be able to access the data as an object or array by accessing the properties in dot syntax.
Use JSON.stringify and a replace callback before the parse call to rename the keys so you can access them via dot notation:
function newkey()
{
return "key" + Number(Math.random() * 1000).toFixed() + RegExp.$1
}
//Stringify JSON
var foo = JSON.stringify(parsedData);
/*
Replace numeric keys with a random number without replacing the delimiter
Replace spaces with underscores
*/
var bar = foo.replace(/\d+("?:)/g, newkey).replace(/\s/g,"_")
//Parse resulting string
var baz = JSON.parse(bar);
References
JSON - AS3 API Reference

Categories