I am trying to increment a value in an object by 1, but I cannot seem to figure it out. I have a mongoose Schema set up as follows:
const userSchema = new Schema({
_id: Schema.Types.ObjectId,
userId: String,
items: Object
});
Which stores data as follows:
items: {
"1234": 1,
"5678": 4
}
Where 1234 and 5678 are item IDs, and 1, 4 are the quanitity of that item the user has. As an example, I need to increment "1234": 1 by 1, to return "1234": 2, and leaving "5678" : 4 unchanged.
I have tried:
let newItem = "1234";
let userProfile = await User.findOneAndUpdate({
userId: userID
}, {
$inc: {
items: {
newItem: 1
}
}
});
Which returns an error: The field 'items' must be an array but is of type object.
I have also tried:
$inc: {
"items": {
newItem: 1
}
}
Which returns: Cannot increment with non-numeric argument: {items: { newItem: 1 }}, and:
$inc: {
`items.${newItem}`: 1
}
Which returns
`items.${newItem}`: 1
^^^^^^^^^
SyntaxError: Unexpected template string
Figured it out. To use a variable in the keyname, wrap a template in []
$inc: {
[`items.${newItem}`]: 1
}
Related
This question already has answers here:
How to filter object array based on attributes?
(21 answers)
Closed last year.
Below is the array with objects:
myArray:[
{"name":"Ram", "email":"ram#gmail.com", "userId":"HB000006"},
{"name":"Shyam", "email":"shyam23#gmail.com", "userId":"US000026"},
{"name":"John", "email":"john#gmail.com", "userId":"HB000011"},
{"name":"Bob", "email":"bob32#gmail.com", "userId":"US000106"}
]}
I tried this but I am not getting output:
item= myArray.filter(element => element.includes("US"));
I am new to Angular.
let filteredArray = myArray.filter(function (item){
return item.userId.substring(0,2).includes('US')
})
Console.log(filteredArray)
//Output
[ { name: 'Shyam', email: 'shyam23#gmail.com', userId: 'US000026' },
{ name: 'Bob', email: 'bob32#gmail.com', userId: 'US000106' } ]
As noted by #halfer - You need to filter on the property that you are interested in - in this case - 'userId' - you can do this by simply adding the property into the code you already had tried and it will log out the specified items - or alternatively - you can make a utility function that takes the array, property and target string as arguments and this will allo2w you to search / filter other arrays and by any property and target string .
These two options are shown below and both log out the same results.
const myArray = [
{"name":"Ram", "email":"ram#gmail.com", "userId":"HB000006"},
{"name":"Shyam", "email":"shyam23#gmail.com", "userId":"US000026"},
{"name":"John", "email":"john#gmail.com", "userId":"HB000011"},
{"name":"Bob", "email":"bob32#gmail.com", "userId":"US000106"}
]
// option 1 - direct filtering
const matchingItems = myArray.filter(element => element.userId.includes("US"));
console.log(matchingItems);
// gives - [ { name: 'Shyam', email: 'shyam23#gmail.com', userId: 'US000026' }, { name: 'Bob', email: 'bob32#gmail.com', userId: 'US000106' } ]
//option 2 - create a function that takes arguments and returns the matches
const matches = (arr, prop, str) => {
return arr.filter(element => element[prop].includes(str));
}
console.log(matches(myArray, 'userId', 'US'));
// gives - [ { name: 'Shyam', email: 'shyam23#gmail.com', userId: 'US000026' }, { name: 'Bob', email: 'bob32#gmail.com', userId: 'US000106' } ]
I have an array extracted from Mongo in the following form
[
{
_id: 60d51d210e5e4e297066132a,
MemberName: 'Name of Member',
MemberRank: 25,
MemberFDR: 6.43,
MemberImageurl: 'uploads/images/gauravverma.jpg'
},
{
_id: 60d5c619c163f23195e01d00,
MemberName: 'Name Of Member',
MemberRank: 24,
MemberFDR: 6.5,
MemberImageurl: 'uploads/images/shashikhanna.jpeg'
},
]
After extracting the original array, I am looping through the array, extracting the name of the member and then doing some more queries in the DB. The length of this returned query, is the count and I want to add it in the original object like so
[
{
_id: 60d51d210e5e4e297066132a,
MemberName: 'Name of Member',
MemberRank: 25,
MemberFDR: 6.43,
MemberImageurl: 'uploads/images/gauravverma.jpg',
Count: 3(whatever the length of the array will be)
},
{
_id: 60d5c619c163f23195e01d00,
MemberName: 'Name Of Member',
MemberRank: 24,
MemberFDR: 6.5,
MemberImageurl: 'uploads/images/shashikhanna.jpeg'
Count: 5(whatever the length of the array will be)
},
]
My query returns the value perfectly, I am struggling with how to insert the value in the original object.
let memberName
let countOfCurrentChallengeMatches
for(let i=0; i<challengeList.length; ){
console.log("hi i am here 1")
memberName = challengeList[i].MemberName
console.log(memberName)
try {
console.log(memberName)
countOfCurrentChallengeMatches = await MatchRegister.find({
$and: [
{ $or: [{ChallengingPlayer: memberName},{ChallengedPlayer: memberName}] },
{ $or: [{ChallengeStatus: 'Awaiting Score Approval'},{ChallengeStatus: 'Accepted'},{ChallengeStatus: 'Completed'}, {ChallengeStatus: 'Issued'}] },
{ChallengerMonth: cMonth},
],
},'_id ChallengingPlayer ChallengedPlayer ChallengerMonth ChallengerYear ProposedChallengeDate ProposedChallengeTime ChallengeMatchLocation ChallengeStatus MatchFormat RejectionReason')
.sort({ProposedChallengeDate: 1}).exec()
} catch (err) {
const error = new HttpError(
'Something went wrong, could not update member.',
500
);
return next(error);
}
// Here is where i want to insert the value in the object
i++
}
I have tried options like, push, add and a few other options from google, but nothing works.
Just example below. Have you tried this example yet?
var arrOfObj = [{
name: 'eve'
}, {
name: 'john'
}, {
name: 'jane'
}];
var result = arrOfObj.map(function(el) {
var o = Object.assign({}, el);
o.isActive = true;
return o;
})
console.log(arrOfObj);
console.log(result);
Hey this simple line worked. Not sue why I missed it in my research
challengeList[i].count = countOfCurrentChallengeMatches.length
I have a list of objects with the following required keys:
Date, Time, Price
I want to add an optional key "order" and if one of these objects contains that optional key, they all must. How would I go about validating that with joi?
You can create a schema dynamically depending on the array that is going to be validated. If the array has some objects that have order property then schema should require this property from every object in the array, otherwise, schema should treat this property as optional:
const schemaFactory = input =>
Joi.array().items(
Joi.object().keys({
Date: Joi.required(),
Time: Joi.required(),
Price: Joi.required(),
order: input.some(item => item.hasOwnProperty('order'))
? Joi.required()
: Joi.optional()
})
)
const input = [
{ Date: 1, Time: 2, Price: 3 },
{ Date: 1, Time: 2, Price: 3, order: true },
]
const schema = schemaFactory(input)
const result = schema.validate(input)
if (result.error) {
console.log(result.error)
}
<script src="https://cdn.jsdelivr.net/npm/joi-browser#13.4.0/dist/joi-browser.min.js"></script>
How can I display multiple values of an array to the console that match the condition (e.g: === "McDonalds")?
I only managed to display one item. But I don't know how i can display all the value of my array.
public products: product[] = [
{ id: 1, name: "McFlurry", price: 2, enseigne:"McDonalds" },
{ id: 2, name: "Potatoes", price: 3, enseigne:"McDonalds" },
{ id: 3, name: "BigMac", price: 4, enseigne:"KFC" },
{ id: 4, name: "Nuggets", price: 3, enseigne:"KFC" }
];
searchEnseigne(){
let server = this.products.find(x => x.enseigne === "McDonalds");
console.log(server);
}
let server = this.products.filter(x => x.enseigne === "McDonalds");
console.log(server);
Use filter instead of find:
The filter() method creates a new array with all elements that pass the test. While The find() method returns the value of the first element
searchEnseigne(){
let server = this.products.filter(x => x.enseigne === "McDonalds");
console.log(server);
}
Using MongoDB, I want to find all documents in one collection who's _id shows up in an array of sub-documents in another collection. Using the $in operator doesn't really work here, because I'm only trying to match against a single value in the sub-document.
Suppose I have the following document from db.foos:
{ _id: 1, foo: [ { bar_id: 1 }, { bar_id: 3 } ] }
and the following collection of db.bars:
{ _id: 1, foo: "bar" }
{ _id: 2, foo: "abr" }
{ _id: 3, foo: "rab" }
I want to find all documents in db.bars who's _id can be found in the foo array (returning db.bars with _id 1 and 3, in this case). Something like this:
var foos = db.foos.findOne( { _id: 1 } )
db.bars.find( _id: { $in: foos.foo.bar_id } )
Of course, that won't work. How would I go about accomplishing this?
You can use the collection.distinct method to get distinct _id values from the foo
db.bars.find({ '_id': { '$in': db.foos.distinct('foo.bar_id', {'_id': 1}) }})
Demo:
> db.foos.distinct('foo.bar_id', {'_id': 1})
[ 1, 3 ]
> db.bars.find({ '_id': { '$in': db.foos.distinct('foo.bar_id', {'_id': 1})}})
{ "_id" : 1, "foo" : "bar" }
{ "_id" : 3, "foo" : "rab" }