Javascript includes method does not work with MongoDB IDs - javascript

I was trying to use includes method to check existing MongoDB Id in an array but it is always returning false.
Is it a some kind of bug in the includes method or am I doing something wrong below is my code
let user = req.user._id;
let keyword= req.query.q;
let userSearchHistory = await UserSearchHistory.findOne({searchKeywords: keyword}).exec();
if (!userSearchHistory.users.includes(user))
{
}
where users in my database is an array with ObjectId refering to user collection
I also tried converting user object
let user= mongoose.Types.ObjectId(req.user._id);
But still the same result.
Converting ObjectIds to String working for me but then I have to remove the references in my model what is the proper way to handle this ?

This is probably happening because userSearchHistory.users returns an array of objectIds.
You can try replacing userSearchHistory.users.includes(user) with userSearchHistory.users.map(user=>user.toString()).includes(user).
This way you will be able to convert the array of objectIds to array of strings before applying 'includes' function.
Edit : Did you try trimming spaces in 'req.user._id' by using req.user._id.trim() and then casting it to objectId?

Related

Validate if object has string

I have this array
switched = {"Restaurant":1,"Hotel":2,"Beauty shop":3,"Physiotherapist":4,"Dentist":5,"Bar":6,"Coffee shop":7}
and this object
result = [{"Google Place URL":"http://www.restaurant.com","Business Type":"Restaurant"},{"Google Place URL":"http://www.hotel.com","Business Type":"Hotel"}]
I want to validate if every item of the result contains words of switched
also, I'm already working with a for that returns each item separately
item[csvBusinessType] = Restaurant
how can I validate if item[csvBusinessType] is included in switched?
I have tried with
let n = switched.includes(item[csvBusinessType]);
but I get Uncaught TypeError: switched.includes is not a function
There is not good native method for this. Better to use lodash library https://www.npmjs.com/package/lodash
Here is an example
const _ = require('lodash');
console.log( _.includes(switched, item[csvBusinessType]));
I converted the object to string and used includes, I don't know if it will be the best way, but I think it is the most supported by browsers
let businessListArray = JSON.stringify(switched);
let checkBusiness = businessListArray.includes(item[csvBusinessType]);
I want to validate if every item of the result contains words of switched
If you want to validate that every item of the result object array contains words of the switched array, you should look into JS Array methods and working with Objects, just as #Andreas suggested.
In this specific case, your switched object has keys that appear to match the csvBusinessType of your item objects. This is helpful as we can use Object.keys() to grab all the keys of your switched object as an array of strings.
const businessTypes = Object.keys(switched) // = ["Restaurant","Hotel","Beauty shop","Physiotherapist","Dentist","Bar","Coffee shop"]
Now that we have grabbed the keys that you want to check against, we can use the JS Array method every() to perform a test against every object in your result object array. In this case, we will be testing that the obect's Business Type is included in our newly created businessTypes array.
const resultsValid = result.every((resultObject) => businessTypes.includes(resultObject["Business Type"]));
resultsValid is a boolean that is true if all objects in result had a Business type that matched one of the keys of your switched object.
NOTE: You may want to check Letter Casing before some of these comparisons unless you want to explicitly match only exact matches ("Beauty shop" will NOT match "Beauty Shop" for example).

How would you convert an ObjectID of mongodb to an object in order to store inside an array?

How would you convert an objectID of a MongoDB entry into an object so that you can store it in an array?
Having searched all over the internet, I resorted here as my one last option.
What I want to achieve is, storing IDs into an array. Those IDs are strings. They needed to be converted into objects, if they are to be stored.
How would you do that?
Following is a small snippet of the code for your review:
var user_id_object = JSON.parse(JSON.stringify(user_id));
console.log((user_id_object));
console.log(typeof (user_id_object));
Here' s what I get in the console:
Your server is running on the port number 8080
Connected to the MongoDB
5ee9ce5ded28da51fc4072c8
string
Parameter "obj" to Document() must be an object, got 5ee9ce5ded28da51fc4072c8
What do you think?
Thanks a TON!!
EDIT 1: Got the below error after implementing the Arjun's code:
const mongoose = require('mongoose');
const ID_OF_24_CHARACTERS = '5c6bf11473e216001afa5608' // example
const arrayOfObjectIds = []
if (mongoose.Types.ObjectId.isValid(ID_OF_24_CHARACTERS)) { // validate ObjectId
const id = mongoose.Type.ObjectId(ID_OF_24_CHARACTERS) // converting string to an ObjectId
arrayOfObjectIds.push(id)
}

Javascript object with arrays to search param style query string

Looking for clean way to convert a javascript object containing arrays as values to a search param compatible query string. Serializing an element from each array before moving to the next index.
Using libraries such as querystring or qs, converts the object just fine, but handles each array independently. Passing the resulting string to the server (which I cannot change) causes an error in handling of the items as each previous value is overwritten by the next. Using any kind of array notation in the query string is not supported. The only option I have not tried is a custom sort function, but seems like it would be worse than writing a custom function to parse the object. Any revision to the object that would generate the expected result is welcome as well.
var qs = require("qs")
var jsobj = {
origString:['abc','123'],
newString:['abcd','1234'],
action:'compare'
}
qs.stringify(jsobj,{encode:false})
qs.stringify(jsobj,{encode:false,indices:false})
qs.stringify(jsobj,{encode:false,indices:false,arrayFormat:'repeat'})
Result returned is
"origString=abc&origString=123&newString=abcd&newString=1234&action=compare"
Result desired would be
"origString=abc&newString=abcd&origString=123&newString=1234&action=compare"
I tried reorder your json:
> var jsobj = [{origString: 'abc', newString: 'abcd' }, {origString: '123',
newString: '1234' }, {action:'compare'}]
> qs.stringify(jsobj,{encode:false})
'0[origString]=abc&0[newString]=abcd&1[origString]=123&1[newString]=1234&2[action]=compare'
But I don't know if this is a good alternative for your problem.
Chalk this up to misunderstanding of the application. After spending some more time with the API I realized my mistake, and as posted above by others, order does no matter. Not sure why my first several attempts failed but the question is 'answered'

Why am I not seeing the added property in the object?

I have to add a property for an object returned from my db before pushing it to an array. Changing properties work, but adding new ones doesn't. Can anyone can explain the logic behind this behavior?
ids.forEach(async (id, index) => {
//get object without highlight property
let real_a = await database.getA(id)
real_a.highlight = "shoud add highlight property to real_a object"
realItems.push(real_a)
// the correct string is printed
console.log(real_a.highlight)
//object still doesn't have that property
console.log(real_a)
}
It was the intended behavior.Sorry for bothering.
I was using a mongodb query for the database.getA(id) function and it turns out you have to specify a parameter in the mongodb query to get an actual changeable JSON object.
Here is the complete answer:
Why can't you modify the data returned by a Mongoose Query (ex: findById)

Comparing arrays from Mongoose using ShouldJS

Taking an array such as ['hello', 'there'] and storing that in a Mongoose document with a schema such as
tags: { type: Array }
using something such as:
Something.create({ tags: ['hello', 'there']}, cb);
Then using ShouldJS to check that the document matches my supplied array I would expect this:
doc.tags.should.eql(['hello', 'there']);
But it does not. If I console.log doc tags I get:
[hello, there]
Notice that the quotes are gone. The doc.tags is indeed an array (I can check instanceof Array) and I can also use shouldjs with
doc.tags.should.have.keys('hello');
doc.tags.should.have.keys('there');
Anyone have an idea as to why my array doesn't match anymore?
Your array is not a real json Array: it's a MongooseArray, with additional methods.
To make should.eql work with mongoose array, first use toObject():
doc.tags.toObject().should.eql(['hello', 'there']);

Categories

Resources