Mongoose: (CastError) Cast to [ObjectId] failed for value - arrays

I'm having a lil problem I've been trying to solve for a while and despite looking online pretty much everywhere I can't find the solution to my problem.
I have 2 mongoose schemas. One "Post" schema and one "Tag" schema.
const postSchema = new Schema({
creator:{type:mongoose.Types.ObjectId, required:true, ref:'User'},
type:{type:String, required:true},
title:{type:String, maxlength:14},
description:{type:String, maxlength:1140},
content:{type:String},
tags:[{type:mongoose.Types.ObjectId, ref:'Tag'}],
date:{type:Date},
});
const tagSchema = new Schema({
name:{type:String, required:true, unique:true},
bgImages:[{type:String}],
posts:[{type:mongoose.Types.ObjectId, ref:'Post'}],
});
When I create a new post, I want to be able to add multiple tags to the tags array in the Post, so what I tried doing is find the ID's of the tags selected by the user and send the array of id's in the POST request.
This is the exact error I get:
'tags.0': CastError: Cast to [ObjectId] failed for value "["60d193ab04caf9336cc9169b,60d193b504caf9336cc9169c"]" (type string) at path "tags.0"
Both the ID's exist in the Tag collection. If I send only one Id in the request it works, but if I send an array of Id's it doesn't.
Something I have in mind is that it sends an array of a single string from what looks like, instead of an array of strings (where each string is the ID).
Can someone help me figure out what's the issue? Thanks a lot.

Found the problem. As I thought it's because I was sending an array containing one single string instead of an array of atomic strings.
Had to split the array with "," to solve the problem.

Related

de-duping items in a mongoose list of populate IDs

I have a mongoose object which contains an array of ObjectIds, being used for population from another table. I want to be able to dedupe these. eg I have
[ '61e34f3293d9361bbb5883c7' ,'61e34f3293d9361bbb5883c7', '61e34f3293d9361bbb5883c7' ]
When i print and iterate through these they look like strings.
But they also have an _id property, so I think they're somehow "populated" or at least contain references to the child table.
What's the best way to do this? I tried:
const uniqueTokens = _.uniqBy(tokens, '_id') which doesn't seem to work as _id is some kind of Object.
converting to a string will allow me to dedupe:
const tokens = this.tokens || []
let newTokens: string[] = []
for (let t of tokens) {
const text = t.toString()
// clog.info('t', t, t._id, typeof t._id)
if (!newTokens.includes(text)) {
newTokens.push(text)
}
}
but then these aren't real Objects I can assign back to the original parent object.
// this.tokens = newTokens
await this.save()
I could maybe go through and re-find the objects, but that seems to be digging deeper into the hole!
Seems there must be a better way to handle these type of types...
related searches
How to compare mongoDB ObjectIds & remove duplicates in an array of documents using node.js?
I also tried using lean() on the tokens array to try and convert it back to a simple list of references, in case somehow the 'population' could be undone to help.
I'm down to creating a unique signature field for the referenced items and de-duping based on that.

mongoose $literal in find method projection

I have a mongoose find method like this,
photo.find({},{
name:1,
src:1,
likes:{$literal:[]},
dislikes:{$literal:[]},
}).then(photos => ....)
what I want is, when I run the code likes and dislikes field must be an empty array for every record.
I try this way but not working.
Unsupported projection option: likes: { $literal: 1 }
Any idea to add default value for any field in find method ?
As per mongoose, document schema is constructed during its creation. So you can also edit the schema with a default value, so for every record, when it is created it will create likes, and dislikes with empty values.
You can also do this way, if you feel the schema control is not in your hands.
https://mongoosejs.com/docs/2.7.x/docs/defaults.html
photo.find({ 'name' : '1', 'likes': {$ne: []}})

RestFB: Getting list of users who liked a post

I need to get the name of each like on each post on a group page. Since I first have to get some data from the original post, I'm trying to make a connection then iterate through the likes and get a list of the users who liked each post. Here's what I have:
Connection<Likes> feedLikes = postFeed.fetchConnection(id+"/likes", Likes.class, Parameter.with("fields","from,actions,type"));
// Get the iterator
Iterator<List<Likes>> likeIt = feedLikes.iterator();
while(likeIt.hasNext()) {
List<Likes> likeFeed = likeIt.next();
for (Likes currLike: likeFeed) {
String ObjectId = id;
String LikeUserId = currLike.getId();
String LikeUserName = currLike.getName();
like_data.add(new String[] {ObjectId, LikeUserId, LikeUserName});
}
}
This doesn't work and I'm a little stuck on why. I know the username is stored in Likes.LikeItem but I can't even get to that step so far. Does anyone have any idea what I'm missing?
According to the Facebook reference this is not possible (https://developers.facebook.com/docs/graph-api/reference/v3.2/object/likes):
A User or Page can only query their own likes. Other Users'or Pages' likes are unavailable due to privacy concerns.
Only aggregated counts using total_count with the summary parameter are available for Post likes.

How to create complex query parameters in Restangular

I need to create a fairly complex query string in Restangular.
http://vdmta.rd.mycompany.net//people?anr=Smith&attrs=givenName,displayName,name,cn
How do I do this?
So far I am OK getting as far as ?anr=Smith using this:
return Restangular.all('/people').getList({anr:searchTerm});
The last part attrs=x,y,x lets me control which attributes I want back in the search and could change per request I make.
Any advice appreciated.
Regards
i
You should be able to simply add another query parameter where the value is your comma separated list of attributes.
var attributes = ['givenName' , 'displayName']; // attributes you require for the request
var attributesAsString = attributes.join();
return Restangular.all('/people').getList({
anr : searchTerm,
attrs: attributesAsString
});

Bind dynamic file contents in array format to jtable

I'm working with ASP.NET MVC 3, and wondering how to return the contents of a file, as an array to a jtable in a view. Each line of the array contains a comma separated list. (The contents of the file came from either a .csv file or excel spreadsheet)
The first column contains the field headers, and the number of field headers in the file can vary, so I guess you could say the contents of the jtable would be dynamic?
I've written jtables with explicitly named fields, but that's when I know how many fields to expect. In this case, it could be anywhere from 1 to 11 fields, and since the field names are in the first line of the array, i'm not quite sure how to setup the jtable to recognize them as column headers for the jtable.
For starters, here's a couple of examples of an array I would expect to bind to the table.
array[0] = "phone,first,last";
array[1] = "1111111111,firstname,lastname";
OR
array[0] = "first,last,email";
array[1] = "firstname,lastname,emailaddress#email.com";
For the first example, I would not need to display the 'email' field, and for the second I don't need the phone field. The actual contents would probably contain many lines, which is why I want to bind it to jtable with paging enabled.
In my controller method, I have the contents of the file as a string array, one line with comma separated fields per array item. Where do I go from there is the question.
Thanks for any help,
Carrie
Actually, I've solved my first problem by using the Expando object, to create a list of dynamic objects . . . problem now is that jtable seems to need to bind to the results returned from a post. The json object i now have has already been returned, so I don't need to do a post to get it. So, the question now is, is it possible to bind a json result to a jtable without making jtable do the post?
Again, thanks.
Working on a similar question; I am returning json and need to bind to jtable. Here is the code from within my ajax call. The only jtable method I found is the addRecord.
Hope this helps and I will edit as I improve and get this fully functional. Yeh, I know that I should only include well formed answers but since you have had no help, we can start with this and let it be a work in progress.
if (data.Result == "OK") {
for (var i = 0; i < data.Records.length; i++) {
$("#SearchResultsAddContact").jtable('addRecord', {
record: {
FirstName: data.Records[i].FirstName,
LastName: data.Records[i].LastName,
NumGroups: data.Records[i].NumGroups,
NumPhones: data.Records[i].NumPhones,
NumTexts: data.Records[i].NumTexts,
NumTags: data.Records[i].NumTags,
NumTDDs: data.Records[i].NumTDDs,
NumEmails: data.Records[i].NumEmails
}
});
}
$("#SearchResultsAddContact").jtable('load');
Make sure that you edit your jquery.jtable.js file as follows: (lines 1297-1308)
addRecord: function (options) {
var self = this;
options = $.extend({
**clientOnly: true,**
animationsEnabled: self.options.animationsEnabled,
url: self.options.actions.createAction,
success: function () { },
error: function () { }
}, options);
Change the clientOnly: to true

Resources