I have a form on a users page that calls a method, 'newDiscussion' to create a new discussion object between the logged in user (hereafter: user1) and the user whose page they're on (hereafter: user2). It also created a message object with a discussionId matching the newly created discussion object.
In the discussion object, I store user1._id and user2._id.
I want check whether an existing discussion object contains these two users Id's. If false, proceed as above, else just insert the message and make the discussionId match the existing discussion object Id.
Assuming you already have the discussion published to your client, you can use collection.findOne method in your client code like this
var dicussion = Discussions.findOne({'user1._id': Meteor.userId(), 'user2._id': 'another user id'});
if (discussion) {
// do some updates, if necessary
}
else {
// else create a new discussion
}
Related
I am currently coding a discord bot and have just created a JSON file. This file is to record each members points in a system. I wanted to check within the client.on("ready") function whether a member's points is undefined if so, set it to 0
if (client.points[/*problem*/guild.member.id].points == undefined) {
client.points [/*problem*/guild.member.id] = {
points: 0;
}
fs.writeFile("./points.json", JSON.stringify (client.points, null, 4), err => {
if (err) throw.err;
});
I improvised with "guild.member.id", however, I don't think that is the right way to do it.
EDIT: Due to the impossibility and inefficiency of retrieving the User's ID within the ready function, I have created an if statement every time a player speaks, which then assigns them to my JSON. This has a benefit of recording whether the user is active or not.
You typically don't want to do this every time the bot comes online. Instead, before you do anything related to points, first check if they are saved, if they aren't initialized them with your default values and save them.
https://anidiots.guide/coding-guides/json-based-points-system
I wrote a script that allows you to delete a property in the caches of the application, however I need to run this script only once when I install the application.
someone has an idea, thanks
var executed = 0;
if(executed === 0){
Ti.App.Properties.removeProperty("My_Property");
executed++;
}
The only ways you can hold some value across app sessions are Ti.App.Properties or sql database. So you can do it in two ways as below:
Solution 1: Use another property to know that you have deleted the desired property.
// for first time installation, the default value (or 2nd parameter) will be false as you have not deleted the property yet
var isDeleted = Ti.App.Properties.getBool('My_Property_Deleted', false);
if (isDeleted) {
Ti.App.Properties.removeProperty("My_Property");
// since you have deleted it, now set it to true so this 'if' block doesn't runs on any next app session
Ti.App.Properties.setBool('My_Property_Deleted', true);
} else {
// you have already deleted the property, 'if' block won't run now
}
Solution 2: Create a new database or pre-load a shipped db with your app.
// Titanium will create it if it doesn't exists, or return a reference to it if it exists (after first call & after app install)
var db = Ti.Database.open('your_db');
// create a new table to store properties states
db.execute('CREATE TABLE IF NOT EXISTS deletedProperties(id INTEGER PRIMARY KEY, property_name TEXT);');
// query the database to know if it contains any row with the desired property name
var result = db.execute('select * from deletedProperties where name=?', "My_Property");
if (result.rowCount == 0) { // means no property exists with such name
// first delete the desired property
Ti.App.Properties.removeProperty("My_Property");
// insert this property name in table so it can be available to let you know you have deleted the desired property
db.execute('insert into deletedProperties(name) values(?)', "My_Property");
} else {
// you have already deleted the property, 'if' block won't run now
}
// never forget to close the database after no use of it
db.close();
There can be other ways as well, but these 2 will work for what you want. Read more about Ti.Database here
I'm using Mongoose for MongoDB operations in my project. I'm trying to:
find every document matching query
create a new object (let's call it objects)
for every document found create a new object inside objects
save fields from found document to created object
And this works just fine. But I also want to:
for every object saved inside my objects find one document matching query in another collection
if document is found, save fields from it to previously created object objects (as new keys)
My code for the second part looks like this:
for(var i in objects) {
if(objects.hasOwnProperty(i)) {
Model.findOne({name: objects[i].name, id: objects[i].id}, function(e, document) {
if(e) console.error(e);
if(document) {
console.log("Found matchind document"); //This is showed for each object, as expected.
objects[i].newField = document.someData;
objects[i].evenNewerField = document.someMoreData;
}
});
}
}
console.log(objects); //This shows old data from previous operations, no new data from the for loop
Your problem is not your mongoose usage, you should take a deep look to Javascript scope and asynchronous. In your code when console.log is called, objects is not yet updated.
I've made a working chat with meteor and mongodb, but I want to play a sound or something when there is a new message. However, I don't know how to check if data is updated. I could check if there is a new message by counting the messages before and after the update, but I just don't know how to check for an update.
So my question here is: How do I check for an update in the data?
I have a website that needs to pop up a toastr alert whenever a new message arrives. My collection is called "Alerts". This is what I do:
Alerts.find({notified: false}).observeChanges({
added: function(id, doc) {
Alerts.update(id, {
$set: {
notified: true
}
});
toastr.info(foo, bar);
}
});
Whenever a new alert is created whose field "notified" is false, a toastr alert will be created and that alert will be marked as "notified: true".
Alternatively you could do the same thing but create a separate collection of "notifications" that when observed, are removed from the collection as well that are a distinct collection from your chat messages collection.
You could create a tailing cursor on the oplog collection, so you get a new document whenever something (anything!) in the database changes. But that's not really an elegant solution, because that handler would need to process a lot of junk.
It might be better to have the routine which writes the message to the database also inform any currently online users. There is really no good reason to go the detour over the database.
I am using CRM 2013 on-premise with UR1 installed
I have a custom entity with a subgrid on it looking at related "tasks" which looks like this:
Whenever I create a task from the subgrid using the "+" button in the top right hand corner of the subgrid; the "Regarding" field of the newly created task remains blank. When it should be populated by a lookup to the record it was created from.
I have javascript on the task entity which checks the "Regarding" field to check what kind of entity it was created from (if it was created from one) and gets certain field values from the calling entity to populate fields on the task.
Since the "Regarding" field is never filled the Javascript never fires - and the fields do not populate.
When the record is saved, if the regarding field is blank (I have not manually filled it in) - it will eventually be populated by the correct record about 10 - 15 seconds later if you refresh the page. Then the correct fields will be populated and the user is able to edit the option set values and save again. This is not ideal for the user as they would like it to be one fluid action.
Is there any way around this problem?
EDIT for future browsers of this question:
Found a partial work around. If you use an "Activity" subgrid rather than a "Task" subgrid the field will populate. This has a drawback though as you cannot edit the "Activity" subgrid's view to show "Task" specific fields.
Ran into this same issue. The way I got around it was to add a look-up to the custom entity on the form (we put this on a hidden tab). When the Task gets created from the custom entity the look-up will be populated. You can then use that look-up to grab the values that you need to populate, including the regarding field. Not the most elegant, but it works.
I also ran into this problem and went with a pure JS approach to resolving. On load of the task form, call populateRegarding().
This works because even though the regarding lookup doesn't populate by default, the query string parameters include _CreateFromType and _CreateFromId values.
This works in 2015, didn't test on earlier versions. Note that it is unsupported.
function populateRegarding() {
var regarding = Xrm.Page.getAttribute("regardingobjectid"),
createFromType = Xrm.Page.context.getQueryStringParameters()._CreateFromType,
createFromId = Xrm.Page.context.getQueryStringParameters()._CreateFromId;
if (!createFromId || !createFromType ||
!regarding || regarding.getValue() !== null) {
return;
}
var entityLogicalName = getEntityLogicalNameFromObjectTypeCode(createFromType);
regarding.setValue([{
id: createFromId,
entityType: entityLogicalName,
name: "Hardcoded Name" // TODO: retrieve name dynamically
}]);
}
// This method uses an undocumented object and is therefore unsupported.
// You could implement a supported version of this function by querying for
// metadata, but that would be very expensive.
function getEntityLogicalNameFromObjectTypeCode(otc) {
var map = Mscrm.EntityPropUtil.EntityTypeName2CodeMap,
logicalName;
otc = Number(otc); // convert string to number
for (logicalName in map) {
if (!map.hasOwnProperty(logicalName)) { continue; }
if (map[logicalName] === otc) {
return logicalName;
}
}
}