Broadcast message only for the owner of the models - javascript

I am building an application where users can create event and other users can "join" and add comments to events, also they can open a chat between them, I have a model named "Notification" where I want to store all the notifications in the system and I want to warn to the owner of the event whenever a user comment on his events, write a new message to him, etc.
This is the part of code for comments that I have wrote:
Notification Model:
/* Notification.js */
module.exports = {
attributes: {
title: {
type: 'string',
required: true
},
text: {
type: 'string'
},
type:{
type: 'string',
enum: ['new_assistant', 'cancel_assistant', 'new_message', 'new_comment'],
required: 'true'
},
read: {
type: 'boolean',
defaultsTo: false
},
user: {
model: 'user'
}
}
};
This is where I subscribe the socket to his notification model:
Notification.find({
user: owner_id
}).then(function(notifications) {
return Notification.watch(req.socket);
});
And whenever a user comment in an event I create a new Notification record:
Notification.create({
title: 'A new user has comment',
text: "Hola",
type: 'new_comment',
read: false,
user: event.owner
}).then(function(comment) {
return Notification.publishCreate({
id: notification.id,
title: 'A new user has comment'
});
});
That code run but this sent a socket message to all users and I just want to warn to the owner of the event (And in the future to the users who going to this event).
Thank you so much.

watch sends the model instance creation message to all of the sockets that are watching the model, the same registration could have been performed without finding the notification as it's not instance dependent, i.e. just call: Notification.watch(req.socket);
To send the notification to a single subscriber use sails.sockets
Create a room for the owner when you want to subscribe:
sails.sockets.join(req.socket, owner_id);
And when you want to publish broadcast to this room:
Notification.create({
title: 'A new user has comment',
text: "Hola",
type: 'new_comment',
read: false,
user: event.owner
}).then(function(comment) {
sails.sockets.broadcast(event.owner, {
id: notification.id,
title: 'A new user has comment'
});
});

Related

How to change the default value of "non-interaction" events in Google Analytics

I'm using Google's Model Viewer in my project, and unfortunately, it is treating certain events as non-interaction: false when they should be non-interaction: true. In my case, these are the events that fire when the model loads, when it detects a user with AR support, and when it detects a user with QR support.
How can I manually set the non-interaction values of these events to true? I've attempted solutions similar to this to no avail:
export type AnalyticsEvent = {
type: string;
category: string;
action: string;
label: string;
value: number;
nonInteraction: boolean;
};
export const USER_WITH_AR_SUPPORT_TEMPLATE: AnalyticsEvent = {
type: 'event',
category: AR_CATEGORY,
action: 'UserWithArSupport',
label: '',
value: '',
nonInteraction: true,
};
"kind": "javascript-module",
"path": "src/globals/ArEvents.ts",
"declarations": [
{
"kind": "variable",
"name": "userWithArSupportTemplate",
"type": {
"text": "AnalyticsEvent"
},
"default": "{\n type: 'event',\n category: ARCategory,\n action: 'UserWithArSupport',\n label: '',\n ,\n nonInteraction: true}"
},
I've also attempted the solution here, as well as several similar ones. Am I using the wrong variable name or index for non-interaction?
Added more code as requested
public sendGaEvent(uaCode: string, eventData: AnalyticsEvent, sku: string, log: boolean) {
...
const instance = this[$analyticsMap].get(uaCode);
const tracker = instance!.tracker;
if (!tracker) {
const queue = instance!.queue;
queue!.enqueue(eventData);
LoggerInstance.log({
sender: this,
message: 'Enqueuing GA event',
force: log
});
} else {
ga(`${tracker}.send`,
eventData.type,
eventData.category,
eventData.action,
eventData.label,
eventData.nonInteraction,
{
hitCallback: () => LoggerInstance.log({
sender: this,
message: 'GA event successfully sent!',
objectToLog: eventData,
force: log
})
}
);
LoggerInstance.log({
sender: this,
message: 'Sending GA event',
force: log
});
}
...
}
EDIT: Using #d-_-b's suggestion, I found the proper form of the solution to be passing in nonInteraction as an object as follows:
ga(
'send',
'event',
'AR_CATEGORY',
'UserWithArSupport',
'label',
{'nonInteraction': true}
);
It is evidently important to keep the quotes around the name 'nonInteraction' when passing it in as an object
For Universal Analytics, the nonInteraction property should be passed as an object (see docs):
ga('send', 'event', 'AR_CATEGORY', 'UserWithArSupport', 'label', {
nonInteraction: true
});
If you're using gtag.js, you need to add non_interaction: true as documented here
gtag('event', '<event-name>', {
'event_label': '',
'event_category': 'AR_CATEGORY',
'event_action': 'UserWithArSupport',
'non_interaction': true
});

Conditional Prompt rendering in Inquirer?

I am building a command line interface in node.js using library: inquirer.
based on my need I want to render prompt, confirmation text etc when user input's. example.
inquirer usage
var _questions = [{
'type': 'list',
'name': 'databasetype',
'message': 'Choose database :',
'choices': ['mongoDB', 'mysql [alpha]', 'firebase [alpha]', 'url [alpha]'],
'default': 'mongoDB'
}, {
'type': 'input',
'name': 'xfactor',
'message': 'X Factor [email, username etc..] :'
}]
// show question's.
Inquirer.prompt(_questions).then(async (__answers) => {
console.log(__answers)
})
what i want
if user chooses mongoDB than it should render another prompt asking
mongodb url
You can use the when question property, its value should be a function that returns a boolean; true for show question, false for don't show question
so using your example:
_questions = [{
type: 'list',
name: 'databasetype',
message: 'Choose database :',
choices: ['mongoDB', 'mysql [alpha]', 'firebase [alpha]', 'url [alpha]'],
default: 'mongoDB'
}, {
type: 'input',
name: 'url',
message: 'Enter the URL',
when: (answers) => answers.databasetype === 'mongoDB'
}]
see more examples here when usage examples

Getting a "method not found [404]" error from dev console while working with meteor collections

I am trying to insert a document into my meteor collection with an autoform made from my mongo schema, yet when I press the submit button it is giving me a "method not found [404]" error in the dev console. I believe it is coming from this code:
GameList.allow({
insert: function(userId, doc){
return !!userId;
}
});
which allows people to add documents to the database if they are logged in as a user. Without this code I will receive a "not authorized [403]" error, because I took out the insecure package from my meteor app. Any idea on what is causing this method not found error?
Autoform code:
{{> quickForm collection="GameList" id="insertGameForm" type="insert" class="newGameForm"}}
Schema for autoform:
GameListSchema = new SimpleSchema({
title: {
type: String,
label: "Title"
},
platform: {
type: String,
label: "Platform"
},
category: {
type: String,
label: "Category"
},
gameRank: {
type: String,
label: "GameRank"
},
auth: {
type: String,
label: "Author",
autoValue: function(){
return this.userId
},
autoform: {
type: "hidden"
}
}
});
GameList.attachSchema(GameListSchema);
I believe this is happening because your allow/deny rules are supposed to run on the server according to the Meteor documentation. Try putting them on server-side code and running this again.

MeanJS - Adding ArticleID to Comment Mongo Collection

I have 2 Collections of article and comment and i would like to add the articleID to the Comment Collection when creating a new comment. The same way in which the UserID automatically goes in.
comment.client.controller.js
// Create new Comment
$scope.create = function() {
// Create new Comment object
var comment = new Comments ({
details: this.details,
status: this.status,
created: this.created,
});
// Redirect after save
comment.$save(function(response) {
$location.path('comments/' + response._id);
// Clear form fields
$scope.status = '';
$scope.details = '';
$scope.created = '';
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
comment.server.model.js
var CommentSchema = new Schema({
userName: {
type: String,
default: 'To Do',
required: 'Please fill Comment name',
trim: true
},
created: {
type: Date,
default: Date.now
},
details: {
type: String,
trim: true
}
,
user: {
type: Schema.ObjectId,
ref: 'User'
},
article: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Article'
}
});
Essentially what i need to know is where does the ObJectID for the User come from without having user : this.user or similar like you need for details, status and created. How can i get the same for Article to just automatically include the Article ObjectID?
The id will come from the route itself or if you intentionally send it inside the POST request body.
Example with article id in route:
If a user posts a comment to an article (with id 123456789) it will make a POST request to /api/articles/123456789/posts then in the backend of the app you will have the endpoint defined as follows:
app.route('/api/articles/:articleId/posts').post(article.postComment);
Note the :articleId in the route, now what you can do is bind that route param to use in your server controllers like so:
app.param('articleId', article.articleById);
articleById is the middleware that will use mongoose to find the article. articleById is defined in the article server controllers file.
Then in your postComment controller you can access the id using req.article.
If you take a look at the server routes for the articles module in meanjs, you will notice that it was already done, so you can probably use the req.article to access the article id.

Mongodb data structure on posts, comments, save and likes

I am just learning how to build websites using MEANJS, and I am structuring my data but unsure on the best practice, I am very new to the NoSql concept.
I need to store:
questions
answers
likes
saved_questions
In my app I enable the user to save questions to be viewed later, as well as they can access any answer they posted. And I provide some stats for each question (i.e. number of likes, number of answers, etc)
Should I create one document for "question" and everything inside of it:
{_id: <ObjectId>,
user_id: <ObjectId>,
question: 'how can we....',
answers: [{user_id: <ObjectId>, answer: ''}],
likes: [{user_id: <ObjectId>}],
saves: [{user_id: <ObjectId>}]
}
Or should I make multiple documents for each? Or should I use both methods?
I would have at least two database models, maybe one for the User and the other for the Question. One of the great things about the MEAN.JS boiler plate is that it already comes with a User module complete with sign-up, login/logout functionality. So you have that out of the way as soon as you deploy your new project.
With that already out of the way, I would use the Yo Generator to create a new CRUD module called Question. You can add the files manually, but Yo helps you do it quickly and accurately by automatically placing the files in the correct place, complete with sample code to help you set it up. To learn how to use the Yo Generator I would look at the Yo Generator Section of the MEAN.JS docs.
From your app's root directory, run yo meanjs:crud-module Question. This will create all of the necessary files you need for the database model, as well as a new module on the front & back ends with samples of how to create/read/update/delete the questions. Now, if you log in, you will see the new module in your menu bar.
Then open app/controllers/models/question.server.model.js. This is the file that you can define your new database model. Depending on how complex/relational you want the data to be, you'd want your Mongoose model to look something like this:
var QuestionSchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true,
required: 'Title cannot be blank'
},
question: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
answers: {
type: Array,
default: []
},
likes: {
type: Array,
default: []
},
saves: {
type: Array,
default: []
}
});
Obviously this is very simplified. You may want to create separate mongoose models for the likes, saves, and reports so you can store more data about each (ie: user_id, date, reason for reporting/saving/liking, etc.) To read more about how to make the perfect mongoose model for your needs, I would definitely check out the docs about Mongoose Schemas at mongoosejs.com.
I hope that helps!
Continued...
To get a list of a given user's actions, I would go ahead and make a new Mongoose Schema for each type of action (comments, likes, saves), and store the details of user's actions there. For instance, in Answers schema you could store the actual comment, who said it, when they said it, what question it was for etc. Then simply query the action tables for a given user ID to retrieve your list of actions.
So..
var QuestionSchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true,
required: 'Title cannot be blank'
},
question: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
var AnswerSchema = new Schema({
created: {
type: Date,
default: Date.now
},
question: {
type: Schema.ObjectId,
ref: 'Question'
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
answer: {
type: String,
default: '',
trim: true
}
});

Categories