NodeJS | Mongoose not updating value in DB - node.js

In array I'm updating a value. I am setting member approved value to true then I console.log all object and it shows the array with users updated approved status to true. But value is not saved to MongoDB after save I still see that approved value is false. This is the code:
userIndex = isInMembersArray.members.findIndex(user => user.username === requestedMember);
isInMembersArray.members[userIndex].approved = true;
console.log(isInMembersArray) // shows data with updated user in members array
isInMembersArray.save();

Use isInMembersArray.markModified("user.approved "); before isInMembersArray.save();
You need to explicitly call markModified() when you update a subpath of a mixed path.
Per Docs
Since Mixed is a schema-less type, you can change the value to anything else you like, but Mongoose loses the ability to auto detect and save those changes. To tell Mongoose that the value of a Mixed type has changed, you need to call doc.markModified(path), passing the path to the Mixed type you just changed.

Related

Use a variable in the name of a variable [duplicate]

This question already has an answer here:
using a variable in mongodb update
(1 answer)
Closed 2 years ago.
When I was using quick.db, I used to do this :
const table = new require('quick.db').table('table') // quick.db table
let guildID = msg.guild.id // snowflake generated by Discord; let's say it's equal to '1234567890'
table.set(`${guildID}.name`, `Cool Name`) // here, the variable name changes in function of guildID : so, to get 'Cool Name', I would have to look for '1234567890.name'.
And I am trying to do the same thing on mongoDB. In my view, it's a lot better and more complete than quick.db, but I still can't find how to do the same thing on mongo.
I guess that this is probably not possible, but I'd like to know if you have an idea about how I could replace this to easily get infos about a guild with its corresponding guildID.
I found a solution thanks to a comment that sent me to this page.
Even through with this method I can't create a value whose name is dependent of a variable directly as a field of the document, I can create one inside an object (the objects are selected with their names as strings, that's why I can insert a variable in that string)
collection.updateOne({id: "123"}, {$set: { ["object."+guildID+".name"]: "Cool Name" }}
Then, "Cool Name" can be found with:
collection.find({id: "123"}, {"object.1234567890.name": 1}) // note: I don't remember how to get a specific field of a document, please correct me or delete this note if you know what's correct

Firebase Invalid document reference. Document references must have an even number of segments

What is wrong with this query?
const db = firebase.firestore()
const query = db.doc(this.props.user.uid).collection('statements').orderBy('uploadedOn', 'desc').limit(50)
I get the following error:
Uncaught Error: Invalid document reference. Document references must have an even number of segments, but FrMd6Wqch8XJm32HihF14tl6Wui2 has 1
at new FirestoreError (index.cjs.js:346)
at Function.DocumentReference.forPath (index.cjs.js:15563)
at Firestore.doc (index.cjs.js:15368)
at UploadStatementPresentation.componentWillMount (UploadStatementPage.jsx:61)
at UploadStatementPresentation.componentWillMount (createPrototypeProxy.js:44)
at callComponentWillMount (react-dom.development.js:6872)
at mountClassInstance (react-dom.development.js:6968)
at updateClassComponent (react-dom.development.js:8337)
at beginWork (react-dom.development.js:8982)
at performUnitOfWork (react-dom.development.js:11814)
Since you haven't described what exactly you're trying to query, I'll just point out that all documents must be in a collection, without exception. So, if you say this:
db.doc(this.props.user.uid)
Firestore assumes that the string you're passing to doc() contains both the collection and document id separated by a slash. But this seems to be highly unlikely in your case. You need to determine which collection the uid is in, and use that first when you build the reference to the collection you want to query. Assuming that you do have a statements subcollection in the uid document, and that some other collection contains the uid document, you'll have to specify the full path like this:
db.collection('that-other-collection').doc(this.props.user.uid).collection('statements')
Of course, only you know the actual structure of your data.
If you want to get a collection of documents with querying, you don’t have to specify a document id. Below code should work in this case.
const query = db.collection('statements').orderBy('uploadedOn', 'desc').limit(50)
Or if you want to get the document, you can pass the document id to doc() method. In that case, the code should be.
const query = db.collection('statements').doc(this.props.user.uid)
For more details about querying firestorm data: https://firebase.google.com/docs/firestore/query-data/get-data?authuser=0
For others having this issue, make sure that no document reference has an empty string.
I had this issue when using a get method with uid input as below and forgot to check if uid is empty
private fun getFullRef(uid: String): CollectionReference {
return ref.document(uid).collection(FireContact.SUB_PATH)
}

Can't modify/remove a field from an ActivityNode using sbt

I created an ActivityNode (an Entry) and I can add custom fields with the
setFields(List<Field> newListField)
fonction.
BUT
I am unable to modify these fields. (In this case I try to modify the value of the field named LIBENTITE)
FieldList list = myEntry.getTextFields();
List<Field> updatedList = new ArrayList<Field>();
//I add each old field in the new list, but I modify the field LIBENTITE
for(Field myField : list){
if(myField.getName().equals("LIBENTITE")){
((TextField)myField).setTextSummary("New value");
}
updatedList.add(myField);
}
myEntry.setFields(updatedList);
activityService.updateActivityNode(myEntry);
This code should replace the old list of fields with the new one, but I can't see any change in the custom field LIBENTITE of myEntry in IBM connections.
So I tried to create a new list of fields, not modifying my field but adding a new one :
for(Field myField:list){
if(!myField.getName().equals("LIBENTITE")){
updatedList.add(myField);
}
}
Field newTextField = new TextField("New Value");
newTextField .setFieldName("LIBENTITE");
updatedList.add(newTextField );
And this code is just adding the new field in myEntry. What I see is that the other custom fields did not change and I have now two custom fields named LIBENTITE, one with the old value and the second with the new value, in myEntry.
So I though that maybe if I clear the old list of Fields, and then I add the new one, it would work.
I tried the two fonctions
myEntry.clearFieldsMap();
and
myEntry.remove("LIBENTITE");
but none of them seems to work, I still can't remove a custom field from myEntry using SBT.
Any suggestions ?
I have two suggestions, as I had (or have) similar problems:
If you want to update an existing text field in an activity node, you have to call node.setField(fld) to update the field in the node object.
Code snippet from my working application, where I'm updating a text field containing a (computed) start time:
ActivityNode node = activityService.getActivityNode(id);
node.setTitle(formatTitle()); // add/update start and end time in title
boolean startFound = false;
// ...
FieldList textfields =node.getTextFields();
Iterator<Field> iterFields = textfields.iterator();
while (iterFields.hasNext()) {
TextField fld = (TextField) iterFields.next();
if (fld.getName().equals(Constants.FIELDNAME_STARTTIME)) {
fld.setTextSummary(this.getStartTimeString()); // NOTE: .setFieldValue does *not* work
node.setField(fld); // write updated field back. This seems to be the only way updating fields works
startFound=true;
}
}
If there is no field with that name, I create a new one (that's the reason I'm using the startFound boolean variable).
I think that the node.setField(fld) should do the trick. If not, there might be a way to sidestep the problem:
You have access to the underlying DOM object which was parsed in. You can use this to tweak the DOM object, which finally will be written back to Connections.
I had to use this as there seems to be another nasty bug in the SBT SDK: If you read in a text field which has no value, and write it back, an error will be thrown. Looks like the DOM object misses some required nodes, so you have to create them yourself to avoid the error.
Some code to demonstrate this:
// ....
} else if (null == fld.getTextSummary()) { // a text field without any contents. Which is BAD!
// there is a bug in the SBT API: if we read a field which has no value
// and try to write the node back (even without touching the field) a NullPointerException
// will be thrown. It seems that there is no value node set for the field. We
// can't set a value with fld.setTextSummary(), the error will still be thrown.
// therefore we have to remove the field, and - optionally - we set a defined "empty" value
// to avoid the problem.
// node.remove(fld.getName()); // remove the field -- this does *not* work! At least not for empty fields
// so we have to do it the hard way: we delete the node of the field in the cached dom structure
String fieldName = fld.getName();
DeferredElementNSImpl fldData = (DeferredElementNSImpl) fld.getDataHandler().getData();
fldData.getParentNode().removeChild(fldData); // remove the field from the cached dom structure, therefore delete it
// and create it again, but with a substitute value
Field newEmptyField = new TextField (Constants.FIELD_TEXTFIELD_EMPTY_VALUE); // create a field with a placeholder value
newEmptyField.setFieldName(fieldName);
node.setField(newEmptyField);
}
Hope that helps.
Just so that post does not stay unanswered I write the answer that was in a comment of the initial question :
"currently, there is no solution to this issue, the TextFields are read-only map. we have the issue recorded on github.com/OpenNTF/SocialSDK/issues/1657"

fieldChanged function in netsuite

Field Changed Function
If the value in a text field is changed to the same value (example: old value = "ABC", new value = "ABC"), will the script
Field Changed Function fire or not?
nlapiSetFieldValue
Some additional information:
FieldName:
String - the name of the field being set
value: String - the value the field is being set to
firefieldchanged: Boolen - if true then the fieldchange script for
that field is executed. (Only available in Client SuiteScript)
Sets the value of the given field.
This API can be used during beforeLoad scripts to initialize field scripts on new records or non-stored fields.
nlapiSetFieldValue is available only in Client and User Event SuiteScripts.
Whenever you are changing the value of an textfield, you will call the fieldChanged event even if you are staying with the same name as you had before.
If you are asking about the Client Side script event Field Change, if I recall correctly this will only trigger when the user has changed the value of the field in the UI. But this event can also be triggered by the nlapiSetFieldValue and nlapiSetCurrentLineItemValue if the fireFieldChange parameter is set to True.

Can't set Orchard field values unless item already created

I seem to be having a problem with assigning values to fields of a content item with a custom content part and the values not persisting.
I have to create the content item (OrchardServices.ContentManager.Create) first before calling the following code which modifies a field value:
var fields = contentItem.As<MyPart>().Fields;
var imageField = fields.FirstOrDefault(o => o.Name.Equals("Image"));
if (imageField != null)
{
((MediaLibraryPickerField)imageField).Ids = new int[] { imageId };
}
The above code works perfectly when against an item that already exists, but the imageId value is lost if this is done before creating it.
Please note, this is not exclusive to MediaLibraryPickerFields.
I noticed that other people have reported this aswell:
https://orchard.codeplex.com/workitem/18412
Is it simply the case that an item must be created prior to amending it's value field?
This would be a shame, as I'm assigning this fields as part of a large import process and would inhibit performance to create it and then modify the item only to update it again.
As the comments on this issue explain, you do need to call Create. I'm not sure I understand why you think that is an issue however.

Resources