Creating Second User on Creating First User in Meteor.JS - javascript

How can we automatically create a second user when the user registers (the first user) from a form generated using the useraccounts:core package?
Running a Accounts.createUser from within Accounts.onCreateUSer causes an error Exception while invoking method 'ATCreateUserServer' TypeError: Cannot read property '_id' of undefined
Accounts.onCreateUser(function(options, user) {
// Create Primary User
if(!user.type) {
// Set user.type as 'user'
user.type = 'user'
// Create Secondary User
Accounts.createUser({
username: options.profile.slaveName,
password: options.profile.slaveName,
type: 'slave',
profile: {
firstName: user.profile.firstName,
lastName: user.profile.lastName
}
})
user.profile = options.profile
return user
}
// Create Secondary User
if(user.type == 'slave') {
user.profile = options.profile
return user
}
});

It looks to me like you're conflating the user argument and the options argument. For instance, the type field comes in through the options argument, not user.
The following code worked for me:
Accounts.onCreateUser(function(options, user) {
// Create Primary User
if(!options.type) {
// Set user.type as 'user'
options.type = 'user'
// Create Secondary User
Accounts.createUser({
username: options.profile.slaveName,
password: options.profile.slaveName,
type: 'slave',
profile: {
firstName: options.profile.firstName,
lastName: options.profile.lastName
}
});
user.profile = options.profile
return user
}
// Create Secondary User
if(options.type == 'slave') {
user.profile = options.profile
return user
}
});
I then tested like so:
// console
Accounts.createUser({username: "guest", password: "guest", profile: {slaveName: 'guestslave', firstName: "Greatest", lastName: "Ever"}})
Meteor.users.find({username: {$regex: 'guest'}}).fetch()
> [returned two user objects]

Related

Friend Request System - Express, MongoDB, EJS

I want to create a social network thus allowing users to send and interact with frind requests. As of now I have created the register, log-in and "search for other users function".
When I find and select another user, I display their user-info and have created a "Add friend" button.
Can anyone help me in a direction of the creation of the "Add friend" option? I have looked around for some time now, and not been able to find the correct solution. Below I have attached my UserSchema and route for finding users:
//User Schema
const UserSchema = new mongoose.Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
password: {
type: String,
required: true
},
},{ collection: 'Users' });
//Get single user based on ID
router.get('/user/get:id', ensureAuthenticated, function (req, res) {
MongoClient.connect(DBUri,{useUnifiedTopology: true }, function (err, db) {
let dbo = db.db(DBName);
const query = {_id: objectId(req.params.id)}
dbo.collection("Users").find(query).toArray(function(err, resultTasks) {
if (err) throw err;
res.render('../View/findFriend', {
resultTasks: resultTasks
});
db.close();
});
});
});
You can add something like this in your user schema:
friends: [{ type : ObjectId, ref: 'User' }],
OR
friends: userSchema
Take the one which suits you.
What that will do is add an array to the user, Then you can store IDs of friends.(Who are other users, hence the ref: 'User')
Then, When you have to fetch users you can do:
User.find(<ID or whatever you have to find Users>).populate('friends')
Also, To push a new friend simply use: user.friends.push(newFriend._id)

Sequelize create model with object type

Is this possible to create model with sequelize to look like:
var User = sequelize.define('User', {
username: DataTypes.STRING,
email: DataTypes.STRING,
password: DataTypes.STRING,
facebook: {
id: DataTypes.STRING,
token: DataTypes.STRING,
email: DataTypes.STRING,
name: DataTypes.STRING
},
})
Idea is: When i will get user data from DB i would like to see
User: {
facebook: {
id,
token,
...
}
}
No.
Either
you make User.facebook a DataType.JSON field (which is supported by postgresql only)
you create an Entity 'facebook', which is 1:1 related to User
Option i) is fine, but you don't get any support from sequelize to check integrity and validity if you make it a json field.
Column dataType - TEXT save as JSON format
after find table - return json patse text
PodPodMaterial.afterFind(async (material) => {
if(material.length) {
for(let mat in material) {
try {
material[mat].ez_kolvo = JSON.parse(material[mat].ez_kolvo)
} catch(e) {console.error(e)}
}
} else {
try {
material.ez_kolvo = JSON.stringify(material.ez_kolvo)
}catch(e) {console.error(e)}
}
return material
})

output to jade the appropriate value from an object sent from express

I'm trying to figure out how you would retrieve the appropriate information on the page when users go to "/users/:name". what I'm trying to do is print out "welcome user2" if user2 logged in and the same for the other users. the way I was thinking of doing it is to pass along the param from "/users/:name" and check if the param is equal to the username value print out that value.(not sure if that is a safe way to do it) how do I cycle through my particular list of objects and compare it to the param?
I get this sent to my jade document
{ list: 'userList', users: [ { password: 'pass1', username: 'user1' }, { username: 'user2', password: 'pass2' }, { username: 'user3', password: 'pass3' } ], address: '14459 70 th st city NY', desc: '3 floors', __v: 0, _id: 56baf181356641f01213295a }
that get's sent because I do this:
app.get("/users/:name", function(req, res){
// console.log(req.params.name)
User.findOne({"users" : { $elemMatch: { username : req.params.name}}}, function(err, doc){
console.log("test ", doc)
res.render("users", {result : doc, name : req.params.name});
})
})
jade:
html
head
body
p= result
p Welcome #{result.users[0].username} #{name} // prints out--> Welcome user1 user2 ||| when user2 signs in
p= result.address
h3= result.desc
a(href="/logout") logout
Then you probably want to go with this, to select appropriate user object for the given param input:
app.get("/users/:name", function(req, res){
// console.log(req.params.name)
User.findOne({"users" : { $elemMatch: { username : req.params.name}}}, function(err, doc){
console.log("test ", doc)
var users = result.users;
var currentUser = {};
for(var i=0;i<users.length;i++)
if(users[i].username === req.params.name)
currentUser = users[i];
res.render("users", {result : doc, user : currentUser });
});
})

Insert data in collection at Meteor's startup

I would like to insert data at Meteor's startup. (And after from a JSON file)
At startup, I create a new account and I would like to insert data and link it to this account once this one created.
This is the code that creates the new account at startup:
if(!Meteor.users.findOne({emails: { $elemMatch: { address: "test#test.com"}}})){
var id = Accounts.createUser({ email: "test#test.com", password: "1234", profile: { name: 'Test' } });
Meteor.users.update({_id: id }, { $set: { admin: false }});
}
And after that, I need to insert data and link it to this account with its ID. (In different collections).
So I tried to do something like that, but obviously It didn't work:
UserData = new Mongo.Collection('user_data');
if(!Meteor.users.findOne({emails: { $elemMatch: { address: "test#test.com"}}})){
var id = Accounts.createUser({ email: "test#test.com", password: "1234", profile: { name: 'Test' } });
Meteor.users.update({_id: id }, { $set: { admin: false }});
UserData.insert({
createdBy: id,
firstname: "test",
/* ... */
});
}
EDIT
Sorry for not have been clear.
The real issue is the :
UserData = new Mongo.Collection('user_data');
declaration is in another file, so I can't do like above.
As it's not in the same file, I tried to get the userId that got "test#test.com" as the email (the account's email created at startup). And once I got it, I want to use it in "createdBy: ID_HERE".
Ok, you'll want to check out Structuring your application. You'll have to make the file with the definition load earlier, or the one with the fixture later.
Normally you have your collections inside lib/ and your fixtures inside server/fixtures.js.
So if you put your insert code into server/fixtures.js it'll work.

mongoose document filtering properties

I have defined a schema like
var UserSchema = new Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true },
location: { type: String, required: true },
picture: { type: String, required: true },
passwordHash: { type: String, required: true },
resetPasswordToken: String,
resetPasswordExpired: Boolean
});
I have a REST Endpoint which return list of all users. In that list I want to hide some properties i.e, passwordHash, resetPasswordToken, resetPasswordExpired
I defined a custom filter function like below
var doFilterUser = function(user) {
_.omit(user, ['passwordHash', 'resetPasswordToken', 'resetPasswordExpired']);
user.id = user._id;
delete user._id;
delete user.__v;
return user;
};
_ is lodash
When I check my API is responding with all user properties
This filter function is defined in common helper module and I am calling it like
User.findOne({_id: id}, function(err, user) {
var filtered = helper.doFilterUser(user);
});
How to resolve this issue?
Try this:
You are allowed to access certain values through mongoose.
User.findOne({_id: id}, 'firstName lastName email location picture', function(err, user){
console.log(user);
});
You just mention the fields needed, after the query.
Hope it helps....
The problem here is that you still have a mongoose document that conforms to s strict schema. If you want to change that document, then you need to make it a "raw" object without all the additional controls:
User.findOne({_id: id}, function(err, user) {
var filtered = helper.doFilterUser(user.toObject());
});
So the .toObject() method here will return an object in it's raw form. That allows you to manipulate the keys how you wish.
You can also explicitly direct it not to serve back certain properties. Useful if you don't want to render a hashed password over the wire. The find method would look like this:
User.find({}, '-id -__v',function(err,users){
})
or
User.findOne({_id: id}, '-id -__v',function(err,user){
})

Categories