Encountered two children with the same key, `[object Object]` - javascript

I am getting the following error : Encountered two children with the same key, [object Object]
I have the following array called cities :
[
{ 'city' : `AIRDRIE`, 'province' : 'AB' },
{ 'city' : `ALBERTA BEACH`, 'province' : 'AB' },
{ 'city' : `ATHABASCA`, 'province' : 'AB' },
{ 'city' : `BANFF`, 'province' : 'AB' },
{ 'city' : `BARRHEAD`, 'province' : 'AB' },
{ 'city' : `BEAUMONT`, 'province' : 'AB' },
{ 'city' : `BLACKFALDS`, 'province' : 'AB' },
...
]
Now I want to filter the array :
const optionsCity = cities.filter(( {province} ) => {
return province === this.state.province
})
which works fine until I try to open my dropdown.. I get error : Encountered two children with the same key, [object Object]
My dropdown is react-dropdown, here is the code :
<Dropdown
options={optionsCity}
onChange={this.updateCity.bind(this)}
value={this.state.city}
placeholder="Select a City" />
Here is my updateCity
updateCity(city) {
this.setState({city: city.name})
}
Anyone knows how to fix ?
I am sorry my English is very bad
Thanks !!

Based on https://github.com/fraserxu/react-dropdown, if you are using an object array of options, you need it to be in a particular format with keys - 'value' and 'label'
{ value: 'one', label: 'One' }
The filter returns an array of objects and not just an array of city names.
You will need to create a new objects array with the above keys or just use a flat array of city names

Related

How to Filter object and get certain field in Javascript

I'm struggle with using filter.
Initial object
This is my object.
[{
isOpen : true,
items : [
{itemId : '', name : 'some name'},
{itemId : 'new', name : 'new name'}
]
},]
Expected Result
I just want to show that the itemId is not an empty string and also isOpen field.
[{
isOpen : true,
items : [
{itemId : 'new', name : 'new name'}
]
},]
What I try
const removeEmptyStringInItems = (item) => item.items?.filter((v) => v.itemId);
const finalItems = myItems.map(removeEmptyStringInItems);
output.
{itemId : 'new', name : 'new name'}
Any ideas for this problem? I really need help!
you could try update the code to this to keep the finalItems format same as the initial value
const removeEmptyStringInItems = (items = []) => items?.filter((v) => v.itemId);
const finalItems = myItems.map((v) => ({...v, items: removeEmptyStringInItems(v.items)}));

How to find data on MongoDB by passing part of array objects

I tried to create an API for filtering the products by sending an array of objects as filters.
this is my Product schema:
const mongoose = require("mongoose");
const { s, rs, rn, rref, ref } = require("../utils/mongo");
let schema = new mongoose.Schema(
{
user: rref("user"),
name: rs,
description: s,
images: [s],
price: rn,
category: ref("category"),
filters: [
{
parent: ref("filter"),
value: s,
name: s,
},
],
subFilter: [
{
parent: s,
value: s,
title: s,
},
],
},
{ timestamps: true }
);
module.exports = mongoose.model("product", schema);
and this one is what I want to send as body to the API
{
category: '62445c3d922d127512867245'
filters: [
{ name: 'filter name 1', value: '62445c3d922d127512861236' },
{ name: 'filter name 2', value: '62445c3d922d127512861458' },
.....
]
}
as you see I want to filter my products based on category Id and an array of filter objects. I tried to write this query but it return an empty array.
this is my query:
filter: async (req, res) => {
try {
const { category, filters } = req.body;
const products = await Product.find({
category,
filters: {
$in: filters,
},
});
res.status(200).json(products);
} catch (err) {
res.status(500).json(err);
}
},
what stored on db
{
"_id" : ObjectId("62643acf19636d7db1804cb3"),
"images" : [
"image-1650735823476۸.jpg"
],
"user" : ObjectId("622606af0f40cb8ea37383dc"),
"name" : "شیر توپی 2 اینچ کلاس 150 پیشگام",
"description" : " برند پیشگام با مدارک و تاییدیه ",
"price" : NumberInt(5000000),
"category" : ObjectId("62445c4d922d127512867246"),
"filters" : [
{
"_id" : ObjectId("62643acf19636d7db1804cb4"),
"parent" : ObjectId("6264307f19636d7db1804b77"),
"value" : "626430bb19636d7db1804b78",
"name" : "Valve Type"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb5"),
"parent" : ObjectId("6264319819636d7db1804b7b"),
"value" : "6264319819636d7db1804b7e",
"name" : "Body Type"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb6"),
"parent" : ObjectId("626431ef19636d7db1804b82"),
"value" : "626431ef19636d7db1804b83",
"name" : "Bore Type"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb7"),
"parent" : ObjectId("6264328519636d7db1804b85"),
"value" : "6264328519636d7db1804b86",
"name" : "Material Type"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb8"),
"parent" : ObjectId("626435de19636d7db1804c10"),
"value" : "626439b619636d7db1804ca7",
"name" : "Trim Material"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb9"),
"parent" : ObjectId("6264367919636d7db1804c17"),
"value" : "6264367919636d7db1804c18",
"name" : "End Conection"
},
{
"_id" : ObjectId("62643acf19636d7db1804cba"),
"parent" : ObjectId("626436a719636d7db1804c1f"),
"value" : "6264378119636d7db1804c28",
"name" : "Size"
},
{
"_id" : ObjectId("62643acf19636d7db1804cbb"),
"parent" : ObjectId("6264389219636d7db1804c6d"),
"value" : "6264389219636d7db1804c6f",
"name" : "Class / Pressure"
}
],
"subFilter" : [
{
"_id" : ObjectId("62643acf19636d7db1804cbc"),
"parent" : "6264328519636d7db1804b85",
"value" : "626433b919636d7db1804b93",
"title" : "Body Material"
}
],
"createdAt" : ISODate("2022-04-23T17:43:43.421+0000"),
"updatedAt" : ISODate("2022-04-23T17:53:29.016+0000"),
"__v" : NumberInt(0)
}
Consider this shrunk down set of inputs that capture the essence of the question. The comments "give away" what we are going to try to find and why. We only show one value for category because matching on that is trivial and not the interesting part of the query.
[
{
"category" : ObjectId("62445c4d922d127512867246"),
"filters" : [
// Matching Valve/value; include this doc
{"name" : "Valve", "value" : "626430bb19636d7db1804b78"},
// ALSO match Body/value; include this doc (but needs only 1 match)
{"name" : "Body", "value" : "6264319819636d7db1804b7e"}
]
}
,{
"category" : ObjectId("62445c4d922d127512867246"),
"filters" : [
// Not target value for Valve name (..79 instead of ...78):
{"name" : "Valve", "value" : "626430bb19636d7db1804b79"},
// ...but correct value for Body, so include this doc
{"name" : "Body", "value" : "6264319819636d7db1804b7e"}
]
}
,{
"category" : ObjectId("62445c4d922d127512867246"),
// No matching Valve or Body so this whole doc is ignored.
"filters" : [
{"name" : "Valve", "value" : "626430bb19636d7db1804b79"},
{"name" : "Body", "value" : "6264319819636d7db1804b7f"}
]
}
,{
"category" : ObjectId("62445c4d922d127512867246"),
// Not even name matches so ignore this too:
"filters" : [
{"name" : "Pipe", "value" : "6264319819636d7db1804eee"}
]
}
]
Assume also we set up inputs coming from the API like this, in their native form i.e. strings NOT ObjectId:
var targ_cat = '62445c4d922d127512867246';
var any_one_of = [
{ name: 'Valve', value: '626430bb19636d7db1804b78' },
{ name: 'Body', value: '6264319819636d7db1804b7e'}
];
We will use $filter as our main function but to do so, we must convert the incoming material into a form required by $filter.
// Convert inbound array of any_one_of into a something designed to work
// in the $filter function by comparing each name/value entry in the
// filters field to the item presented in $$this, meaning take:
// { name: 'Valve', value: '626430bb19636d7db1804b78' },
// and turn it into:
// {$and: [ {$eq:['Valve','$$this.name']}, {$eq:['62643...','$$this.value']} ] }
// Since any one of the entries is considered a hit, we package it all
// into an $or wrapper, not $and.
var or_list = [];
any_one_of.forEach(function(f) {
or_list.push( {$and: [
{$eq:[f['name'], '$$this.name']},
{$eq:[f['value'], '$$this.value']}
]});
});
var or_expr = {$or: or_list};
Now we are ready to query mongoDB:
db.foo.aggregate([
// Get this out of the way quickly; note we must make a new ObjectId!
{$match: {'category': new ObjectId(targ_cat)}}
// The interesting part of the query:
,{$addFields: {filters: {$filter: {input: '$filters', cond: or_expr}}}}
// Only keep those items where $filter found at least one of the
// targets:
,{$match: {$expr: {$gt:[{$size: '$filters'},0]} }}
]);

Get uniq values from an array of object created using lodash

I am new to the react, Here I am trying to get the unique elements from the newly created array of object.
const data = _.uniq(
orderData?.Sessions.map(session => ({
label: `${session.Activity.Name}`,
value: `${session.Activity.Name}`
}))
);
I have tried this but, still, it returns me the array of the object which has the unique elements using any of the two keys.
an object should not be duplicated.
can anyone help me with this?
It should be _.uniqBy(), refer uniqBy
const data = _.uniqBy(
orderData ? .Sessions.map(session => ({
label: `${session.Activity.Name}`,
value: `${session.Activity.Name}`
})), 'label' or 'value'
);
It should be either by label or by value
Example
document.querySelector("body").onload = function() {
// By 'label'
console.log("By label");
console.log(
_.uniqBy(
[
{'label' : 'name', 'value' : 'Test Name 1'},
{'label' : 'name', 'value' : 'Test Name 2'},
{'label' : 'company', 'value' : 'Test Company 1'}
], 'label'
)
)
// By 'vlaue'
console.log("By value");
console.log(
_.uniqBy(
[
{'label' : 'name', 'value' : 'SO User'},
{'label' : 'name', 'value' : 'SO User'},
{'label' : 'company', 'value' : 'Test Company 1'}
], 'value'
)
)
}
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.10/lodash.min.js"></script>
You have to use _.uniqBy(data, 'id');//id that is key you have to remove duplicate value from array
Your Scenario will be used like this
if removed by a label then
const data = _.uniqBy(
orderData ? .Sessions.map(session => ({
label: `${session.Activity.Name}`,
value: `${session.Activity.Name}`
})),'label'
);
if removed by a value then
const data = _.uniqBy(
orderData ? .Sessions.map(session => ({
label: `${session.Activity.Name}`,
value: `${session.Activity.Name}`
})),'value'
);
If you get more details then Link

Filter a custom key or value via mongoose

I Have a Message Schema with 2 type message: text and voice, How Should I get value of text?
text data example:
{
"_id" : ObjectId("5a8ea03d2601be24b086ccd4"),
"userId" : 20,
"text" : "Hi",
"__v" : 0
}
voice data example:
{
"_id" : ObjectId("5a8ea03d2601be24b086ccd4"),
"userId" : 20,
"voice" : "d2601be24bd22601be24b",
"__v" : 0
}
Code:
Message
.find({userId: '20'}, {_id: 0, text: ''})
.exec((err, obj) => {
if (err) {
console.log(err);
}
for (const val of Object.values(obj)) {
console.log(val.text);
}
});
output:
Hi // for text
undefined // for voice
I have All Type of Message in Output, How Should I get all text value? (not voice)?
Couple of options, you could add an if statement within your for loop e.g.
for (const val of Object.values(obj)) {
if(val.text) console.log(val.text);
}
Alternatively you could adjust your database query to only select messages with a non-empty text string e.g.
Message
.find(
{
userId: '20',
text: {
$exists: true,
$ne: ''
},
{_id: 0, text: ''}
)
Note: my query may not be quite right as I didn't test it, but it would be something to that effect. See: Find MongoDB records where array field is not empty for similar concept.

How to get the selected value from Kendo UI grid

I am using Kendo grid. I want to get the value(field-nlv_id) for the multiple row selected if select the rows. Also i want to get the number of selected rows and pass to the controller. Let me know the way to do it.
columns : [
{
'field' : 'nlv_id',
'title' : 'Asset ID'
},
{
'field' : 'due_date',
'title' : 'Partner Due Date'
},
{
'field' : 'link',
'title' : 'Partner'
},
{
'field' : 'playlist_type',
'title' : 'Playlist Style'
},
{
'field' : 'show_code',
'title' : 'Show Code'
},
{
'field' : 'status',
'title' : 'Status'
},
{
'field' : 'retry_count',
'title' : '# Retries'
}
],
scrollable : false,
pageable : {
pageSizes : [ 10, 25, 50 ],
buttonCount : 5,
refresh : true,
messages : {
display : "{0} - {1} of {2} assets",
itemsPerPage : "assets per page",
empty : "No assets to display"
}
},
dataSource : new kendo.data.DataSource({
serverPaging : true,
transport : {
read : getJobs
},
pageSize : 10,
schema : {
total : returnTotalCount
}
}),
selectable : 'multiple',
sortable : true
};
You will need to do an change() event on grid, then you will have selected items, for convinience i did an example using an list with all selected items, so you can easily get numbers of rows selected.
change: function (e, args) {
var currentSelected = this.select();
var dataSource = $grid.dataSource.data();
currentItems = [];
$.map(currentSelected, function (item) {
currentItems.push($grid.dataItem(item).nlv_id) ;
return $grid.dataItem(item).nlv_id;
});
alert(currentItems);
},
You can get count like that
currentItems.length;
EDIT: For convinience i create an example to do, is easier.
Important: you must set you 'nlv_id' in Schema!
http://jsfiddle.net/2ojwwpLf/
hope this help

Categories