I have a mongo collection that is created outside of Meteor that holds user info of people who want access to my app. It looks like this in MongoVue-
**tmpUsers**
/* 5 */
{
"_id" : ObjectId("54c7ae456587e23335915948"),
"email" : "trial#domain.com",
"first" : "Trial User",
"type" : "trial",
"active" : "Yes"
}
When I try to read this I get basically an empty collection structured like this -
collection:
d_docs: d._IdMap_..........
Here's my code -
**client**
var type = "";
var tmpCursor = tmpUsers.find({"email": Meteor.user().emails[0].address});
tmpCursor.forEach(function(rec) {
type = rec.type
});
Meteor.call("updateProfile", Meteor.userId(), type);
**server**
Meteor.methods({
"updateProfile": function(id, value){
Meteor.users.update({"_id": id}, {$set: {"profile.acctType": value}});
}
})
How would I update the client side code to read the type from tmpUsers?
Update:
Here is where I insert the record from outside of Meteor -
try {
$mongoDb = $mongoConn->abcdefg;
$collection = $mongoDb->tmpUsers;
$userInfo = array("email" => $_POST['email'], 'first' => $first,"type" => $_POST['type'], 'active' => $activation);
$collection->insert($userInfo);
} catch (MongoException $e) {
die('Error: ' . $e->getMessage());
}
Try with this.
Tracker.autorun(function(){
Meteor.subscribe('tmpUsers',function(){
var finde = tmpUsers.find({email:Meteor.user().emails[0].address}).count();
if (finde === 1){
console.log("found email");
} else{
console.log("not email found")
}
});
});
Related
I would like to add new field into json already have in mongoDB Cosmos like this
{
"_id" : "6396cde306fd2d1088d584e4",
"userName" : "user-20526"
}
Now I would like to add a others field like this bellow userName field:
{
"_id" : "6396cde306fd2d1088d584e4",
"userName" : "user-20526",
"others": [
{
"address" : "city",
"phone" : "12345676543"
}
]
}
I user this function to do that thing, with updateDocument but it's not works for me:
const updateDocuments = async (value, condition, collectionName) => {
const DATABASE_COLLECTION_NAME = collectionName;
if (!db)
throw Error('findDocuments::missing required params');
const collection = await db.collection(DATABASE_COLLECTION_NAME);
const filter = { condition };
const filterJSON = JSON.parse("{" + filter.condition + "}");
const options = { upsert: true };
// get value (condition) and convert it to correct JSON format before call it in update variable
const getValue = { value }
const valueJSON = JSON.parse("{" + getValue.value + "}");
const updateDoc = {
$set: valueJSON
};
return await collection.updateOne(filterJSON, updateDoc, options);
}
The above function only works when we update one field that already have in data, the example I would like to update userName data, then that function is work, If I use that function to add new one then it's not, not add new one, how can I create more to add new field as what I expected before
anyone please help me
I'm having difficulty creating the routes to send to MongoDB.
When I return user, it returns the full database. This goes for using User or 'user'.
User is a model
let User = require('../models/user.model');
User.findById(req.params.id)
.then(user => {
if (!user)
res.status(404).send("data is not found");
else
for(var key in req.body.proposal) {
//res.send(user.proposal)
//res.send(user)
//res.send(User.username)
user.proposal.insertOne(
{
"uid" : req.body.proposal[key].uid,
"clientEmail" : req.body.proposal[key].clientEmail,
"summary" :req.body.proposal[key].summary,
"terms" :req.body.proposal[key].terms,
"form" :req.body.proposal[key].form
} //update
)
}
user.save()
.then(user => res.json(user))
.catch(err => res.status(400).json('Error: ' + err));
})
.catch(err => res.status(400).json('Error: ' + err));
});
Thank you in advanced!
It should be something like this :
let proposalArr = [];
for (const key in req.body.proposal) {
proposalArr.push({
uid: req.body.proposal[key].uid,
clientEmail: req.body.proposal[key].clientEmail,
summary: req.body.proposal[key].summary,
terms: req.body.proposal[key].terms,
form: req.body.proposal[key].form
});
}
user.proposal = proposalArr;
user.save().............
You can't use .insertOne on result of database query, it's a function of mongoose model to insert new document to collection but not to insert new fields to objects. You need to do just like adding new fields to json object using .js code, but mongoose will keep track of object's changes & when you use .save() it can update the document in collection with all those changes.
Instead of two DB calls, you can do that in one call, Check : .findByIdAndUpdate() & try below sample code :
let proposalArr = [];
for (const key in req.body.proposal) {
proposalArr.push({
uid: req.body.proposal[key].uid,
clientEmail: req.body.proposal[key].clientEmail,
summary: req.body.proposal[key].summary,
terms: req.body.proposal[key].terms,
form: req.body.proposal[key].form
});
}
User.findByIdAndUpdate(
req.params.id,
{
proposal: proposalArr
},
{ new: true }
)
.then(user => {
if (!user) res.status(404).send("data is not found");
res.json(user);
})
.catch(err => res.status(400).json("Error: " + err));
I copied documents from a local database to my production database and when I try to get the document by Id by running model.findOne({_id : id}) and mongoose returns nothing. I am copying the documents over with the same Id, but I also tried with a new Id. I can find the document in the database and confirm that the JSON is correct, the Id is correct, etc and it won't find it. The documents I did not copy and where generated via my app still query fine with the findOne command. So, I have no idea what's going on
any help is greatly appreciated, thanks
groups.crud
getGroupById(id: string) {
logger.debug(".getGroupById id: " + id);
return new Promise(function(resolve, reject) {
GroupsModel.findById(id)
.populate('createdBy')
.then(function (group) {
logger.debug(".getGroupById");
if(group.createdBy.privacySettings.useUserName) {
group.createdBy.firstName = '';
group.createdBy.lastName = '';
}
resolve(group);
})
.catch(function(error) {
reject(error);
});
});
}
groups.routes
getGroupById(req, res, next) {
logger.debug('.getGroupById: BEG');
let id = req.params.id;
return groupsCrud.getGroupById(id)
.then(function(group) {
if(group) {
logger.debug('.getGroupById: get by id success');
let response = {
data : group
}
logger.debug('.getGroupById: response: ' + response);
res.json(response);
}
else {
logger.debug('.getGroupById: get by id failed 1');
res.status(404).json({ status : 404, message : "Group not found."});
}
})
.catch(function(error) {
logger.debug('.getGroupById: get by id failed 2 err = ' + JSON.stringify(error, null, 2));
res.sendStatus(404);
});
}
I am trying to use the Waterline .native() method to query an item by id in the database. This is what my code looks like:
// Consutruct the query based on type
var query = {};
if (req.param('type') === 'id') {
query = { _id: req.param('number') };
} else {
query = { 'data.confirmationNumber': req.param('number') };
}
Confirmations.native(function(error, collection) {
if (error) {
ResponseService.send(res, 'error', 500, 'Database error.');
} else {
collection.find(query).toArray(function(queryError, queryRecord) {
if (queryError) {
ResponseService.send(res, 'error', 500, 'Database error.');
} else {
if (queryRecord.length > 0) {
ResponseService.send(res, 'success', 200, queryRecord[0]);
} else {
ResponseService.send(res, 'error', 404, 'Your confirmation details could not be found.');
}
}
});
}
});
When the query is 'data.confirmationNumber' it works but if it is '_id' it dows not work. How do I fix this?
if your Id is a ObjectId see this
var ObjectId = require('mongodb').ObjectID;
{_id: new ObjectId(req.param('number') )}
Iniside Model and in attribute define the id field like this
id : {type : 'objectid',primaryKey:true}
When you are querying the code
Here my model name is - QuizModel and the id is coming in the params quizId so here quizId is equal to the _id in the mongodb database
QuizModel.find({_id: QuizModel.mongo.objectId(quizId)})
.then(function(response){
})
.catch(function(error){
});
Is it possible to create new Meteor collections on-the-fly? I'd like to create foo_bar or bar_bar depending on some pathname which should be a global variable I suppose (so I can access it throughout my whole application).
Something like:
var prefix = window.location.pathname.replace(/^\/([^\/]*).*$/, '$1');
var Bar = new Meteor.Collection(prefix+'_bar');
The thing here is that I should get my prefix variable from URL, so if i declare it outside of if (Meteor.isClient) I get an error: ReferenceError: window is not defined. Is it possible to do something like that at all?
Edit : Using the first iteration of Akshats answer my project js : http://pastie.org/6411287
I'm not entirely certain this will work:
You need it in two pieces, the first to load collections you've set up before (on both the client and server)
var collections = {};
var mysettings = new Meteor.Collection('settings') //use your settings
//Startup
Collectionlist = mysettings.find({type:'collection'});
Collectionlist.forEach(function(doc) {
collections[doc.name] = new Meteor.Collection(doc.name);
})'
And you need a bit to add the collections on the server:
Meteor.methods({
'create_server_col' : function(collectionname) {
mysettings.insert({type:'collection', name: collectionname});
newcollections[collectionname] = new Collection(collectionname);
return true;
}
});
And you need to create them on the client:
//Create the collection:
Meteor.call('create_server_col', 'My New Collection Name', function(err,result) {
if(result) {
alert("Collection made");
}
else
{
console.log(err);
}
}
Again, this is all untested so I'm just giving it a shot hopefully it works.
EDIT
Perhaps the below should work, I've added a couple of checks to see if the collection exists first. Please could you run meteor reset before you use it to sort bugs from the code above:
var collections = {};
var mysettings = new Meteor.Collection('settings')
if (Meteor.isClient) {
Meteor.startup(function() {
Collectionlist = mysettings.find({type:'collection'});
Collectionlist.forEach(function(doc) {
eval("var "+doc.name+" = new Meteor.Collection("+doc.name+"));
});
});
Template.hello.greeting = function () {
return "Welcome to testColl.";
};
var collectionname=prompt("Enter a collection name to create:","collection name")
create_collection(collectionname);
function create_collection(name) {
Meteor.call('create_server_col', 'tempcoll', function(err,result) {
if(!err) {
if(result) {
//make sure name is safe
eval("var "+name+" = new Meteor.Collection('"+name+"'));
alert("Collection made");
console.log(result);
console.log(collections);
} else {
alert("This collection already exists");
}
}
else
{
alert("Error see console");
console.log(err);
}
});
}
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
Collectionlist = mysettings.find({type:'collection'});
Collectionlist.forEach(function(doc) {
collections[doc.name] = new Meteor.Collection(doc.name);
});
});
Meteor.methods({
'create_server_col' : function(collectionname) {
if(!mysettings.findOne({type:'collection', name: collectionname})) {
mysettings.insert({type:'collection', name: collectionname});
collections[collectionname] = new Meteor.Collection(collectionname);
return true;
}
else
{
return false; //Collection already exists
}
}
});
}
Also make sure your names are javascript escaped.
Things got much easier:
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
db.createCollection("COLLECTION_NAME", (err, res) => {
console.log(res);
});
Run this in your server method.