why update doesn't work - node.js

I pass a json variable to a module but I can't do the update of my collection, always I have an error in the updating.
var gestion = function(myJSON) {
var dburl = 'localhost/mongoapp';
var collection = ['clientes'];
var db = require('mongojs').connect(dburl, collection );
function cliente(nombre, estado, nuevo){
this.nombre = nombre;
this.estado = estado;
this.nuevo = nuevo;
}
var cliente1 = new cliente(myJSON.nombre myJSON.estado, myJSON.nuevo);
if (cliente1.estado == "desconectado"){
db.clientes.update(cliente1.nombre, {$set: {estado: "desconectado", nuevo: "no"}}, function(err) {
if (err) console.log("error "+cliente1.nombre);
else console.log("OK");
});
}
}
return 0;
}
I also tried to remove my db and create one more time and I'm sure that my object exist in my db.

The signature you should be using is
update(query, update, callback)
but you're passing a string for query, which doesn't mean anything to Mongo. You may want to look at the docs for an overview, but for this specific instance, it looks like you're trying to find the document where nombre is equal to the string at cliente1.nombre. The query for this is a dictionary { nombre: cliente1.nombre }, so that line should be
db.clientes.update({nombre: cliente1.nombre}, {$set: {estado: "desconectado", nuevo: "no"}}, function(err) {

Related

How to connect my electron app using PouchDB (leveldb) with Cloudant or any other database that support couchDB and sync

I'm creating an electron app using pouchDB and I want the app to be able to diferents customers and sync the data between them. As an example I'm making the tutorial: https://github.com/nolanlawson/pouchdb-getting-started-todo, I adapt the code to electron and I created a noSQL database at cloudant.
At the moment I can save data but I cannot sync with my remote db that is in cloudant. Here is the endpoint I'm using to sync data between both database.
Here is the error that I'm getting.
Here is the code of my script.js
(function() {
'use strict';
var $ = document.querySelector.bind(document);
var ENTER_KEY = 13;
var newTodoDom = document.getElementById('new_todo');
var syncDom = document.getElementById('sync-wrapper');
// EDITING STARTS HERE (you dont need to edit anything above this line)
var NodePouchDB = require('pouchdb');
var db = new NodePouchDB('todos');
var couchdb = require('felix-couchdb')
var remoteCouch = couchdb.createClient(5984, 'https://ac725f4e-29ec-4614-8e96-02ebc74a529b-bluemix.cloudant.com/')
db.info(function(err, info) {
console.log("is working", info)
db.changes({
since: info.update_seq,
live: true
}).on('change', showTodos);
});
// We have to create a new todo document and enter it in the database
function addTodo(text) {
var todo = {
_id: new Date().toISOString(),
title: text,
completed: false
};
db.put(todo).then(function (result) {
console.log("everything is A-OK");
console.log(result);
}).catch(function (err) {
console.log('everything is terrible');
console.log(err);
});
}
// Show the current list of todos by reading them from the database
function showTodos() {
db.allDocs({include_docs: true, descending: true}).then(function(doc) {
redrawTodosUI(doc.rows);
}).catch(function (err) {
console.log(err);
});
}
function checkboxChanged(todo, event) {
todo.completed = event.target.checked;
console.log(todo);
db.put(todo);
}
// User pressed the delete button for a todo, delete it
function deleteButtonPressed(todo) {
db.remove(todo);
}
// The input box when editing a todo has blurred, we should save
// the new title or delete the todo if the title is empty
function todoBlurred(todo, event) {
var trimmedText = event.target.value.trim();
if (!trimmedText) {
db.remove(todo);
} else {
todo.title = trimmedText;
db.put(todo);
}
}
// Initialise a sync with the remote server
function sync() {
syncDom.setAttribute('data-sync-state', 'syncing');
var opts = {live: true};
db.sync(remoteCouch, opts, syncError);
}
// EDITING STARTS HERE (you dont need to edit anything below this line)
// There was some form or error syncing
function syncError() {
syncDom.setAttribute('data-sync-state', 'error');
}
// User has double clicked a todo, display an input so they can edit the title
function todoDblClicked(todo) {
var div = document.getElementById('li_' + todo._id);
var inputEditTodo = document.getElementById('input_' + todo._id);
div.className = 'editing';
inputEditTodo.focus();
}
// If they press enter while editing an entry, blur it to trigger save
// (or delete)
function todoKeyPressed(todo, event) {
if (event.keyCode === ENTER_KEY) {
var inputEditTodo = document.getElementById('input_' + todo._id);
inputEditTodo.blur();
}
}
// Given an object representing a todo, this will create a list item
// to display it.
function createTodoListItem(todo) {
var checkbox = document.createElement('input');
checkbox.className = 'toggle';
checkbox.type = 'checkbox';
checkbox.addEventListener('change', checkboxChanged.bind(this, todo));
var label = document.createElement('label');
label.appendChild( document.createTextNode(todo.title));
label.addEventListener('dblclick', todoDblClicked.bind(this, todo));
var deleteLink = document.createElement('button');
deleteLink.className = 'destroy';
deleteLink.addEventListener( 'click', deleteButtonPressed.bind(this, todo));
var divDisplay = document.createElement('div');
divDisplay.className = 'view';
divDisplay.appendChild(checkbox);
divDisplay.appendChild(label);
divDisplay.appendChild(deleteLink);
var inputEditTodo = document.createElement('input');
inputEditTodo.id = 'input_' + todo._id;
inputEditTodo.className = 'edit';
inputEditTodo.value = todo.title;
inputEditTodo.addEventListener('keypress', todoKeyPressed.bind(this, todo));
inputEditTodo.addEventListener('blur', todoBlurred.bind(this, todo));
var li = document.createElement('li');
li.id = 'li_' + todo._id;
li.appendChild(divDisplay);
li.appendChild(inputEditTodo);
if (todo.completed) {
li.className += 'complete';
checkbox.checked = true;
}
return li;
}
function redrawTodosUI(todos) {
var ul = document.getElementById('todo-list');
ul.innerHTML = '';
todos.forEach(function(todo) {
ul.appendChild(createTodoListItem(todo.doc));
});
}
function newTodoKeyPressHandler( event ) {
if (event.keyCode === ENTER_KEY) {
addTodo(newTodoDom.value);
newTodoDom.value = '';
}
}
function addEventListeners() {
newTodoDom.addEventListener('keypress', newTodoKeyPressHandler, false);
}
addEventListeners();
showTodos();
if (remoteCouch) {
sync();
}
})();
To get to where the problem sits, can you verify that you can speak to the Cloudant database normally, that is using curl from the command-line? Using curl, fetch a document by its _id, perhaps a document you created manually using the Cloudant dashboard. That should shake out any problems with authentication: I note you're using IAM, which isn't always straight-forward -- and to my knowledge, not supported by PouchDB (or wasn't, last time I looked).
If that is the problem, create a new Cloudant instance with IAM+Legacy credentials.

get name from id inside loop in node js

hello all I am new to node js and mongo db so I am facing a problem which is written above want to match an id from an array and get all the record of matching id , but thats not working i have already tried for loop but that is taking too much time so i am looking for some kind of query by which I pass id and get the matching results i have below function also where i can pass id and get the matching result but i don't know how to call that .
exports.getDistrictFromId = function(req, res, next) {
var distId = req.params.id;
districtslib.getDistricts({_id: utils.toObjectId(distId)}, function(err, district) {
if (err) {
return next(err);
}
req.store.district = district;
next();
});
};
Here is my code
exports.getCompleteTeachersList = function(req, res, next) {
var query = req.store.get('query');
var teacherQuery = {enabled: true};
var searchQuery = '';
if (!_.isUndefined(query)) {
// schoolQuery = {'name':new RegExp(query.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"),'i')};
//{ $text: { $search: "amit hinduja"} }
//teacherQuery = {enabled: true,$or:[{firstName:new RegExp(query.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"),'i')},{lastName:new RegExp(query.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"),'i')}]};
if(query.trim() != '') {
teacherQuery = {enabled: true,$text: { $search: query} };
searchQuery = query;
}
}
teacherslib.getTeachers(teacherQuery, function(err, teachers) {
if (err) {
return next(err);
}
var schools = req.store.get('schools');
for(var i = 0; i < teachers.length; i++) {
teachers[i].schoolName = "";
for(var j = 0; j < schools.length; j++) {
if (teachers[i].schoolId.toString() === schools[j]._id.toString()) {
teachers[i].schoolName = schools[j].name;
teachers[i].distId = "";
var districts = req.store.get('districts');
console.log(schools[j].distId);
// i want to get the array of matching district id `schools[j].distId` from the district array from `var districts = req.store.get('districts');` this line
break;
}
}
}
req.store.set('searchQuery', searchQuery);
req.store.set('teachers', teachers);
//req.store.set('districts', districts);
next();
});
};
Collection structure is like this
1) distid is coming in schools collection
using distid get all the matching record from district
2)district array has countyid and from that county id has to get data from the county collection
Instead of looping inside a loop, i would suggest you look into the $lookup operator of the aggregation framework. Here you can perform the lookup server side.

nodejs mongodb $in [array] not working if array is a variable

This is very strange to me. If put the array onlyIds in the aggregation query of my db I get no results. If I however put the content of onlyIds that I get printed from line 5 which looks like:
["52e953942a13df5be22cf792","52e953942a13df5be22cf793","52e953942a13df5be22cf797"...]
Then it works. But not if I use the variable.
This function:
var onlyIds = [];
for (var i = 0; i < users.length; i++) {
onlyIds.push(users[i]._id);
}
console.log("ids: " + JSON.stringify(onlyIds)); <---------- not empty
db.collection('posts', function(err, collection) {
collection.aggregate([
{$match: {user_id: {$in: onlyIds}}}, <------- not working
{$match: {created:{$gte: 0}}},
{$sort:{"created": -1}},
{$skip: req.body.skip},
{$limit: req.body.limit}
],
function(err, posts) {
var errorNo, content, message;
if (err) {
errorNo = resSend.errorDB;
message = JSON.stringify(err);
} else {
errorNo = resSend.errorNo;
content = posts;
message = "";
--> console.log(JSON.stringify(posts));
}
resSend.sendResponse(res, resSend.errorNo, content, message);
});
});
So in short, why does this work:
{$match: {user_id: {$in: ["52e953942a13df5be22cf792","52e953942a13df5be22cf793","52e953942a13df5be22cf797"...]}}}
and this doesn't:
{$match: {user_id: {$in: onlyIds}}}
And the line that does not work, works perfectly in another function. Any ideas or enlightenments?
EDIT:
Switching to find and using the below answer like this:
collection.find({'user_id': {$in: onlyIdsX}}).toArray(function(err, posts)
does not work either.
ANSWER:
As the selected answer indicates below is when the variable you search for is an ObjectId or a string. For anyone else, make sure that the variable in the db is the same type as the one you try to match it with. In my case both were supposed to be strings, but one's in "onlyIds" were ObjectIds.
Try following code to modify your loop:
var ids = ["52e953942a13df5be22cf792","52e953942a13df5be22cf793","52e953942a13df5be22cf797"];
var obj_ids = [];
for (var i = 0; i < users.length; i++) {
obj_ids.push(new ObjectID(users[i]._id.toString()));
var obj_ids.push(users[i]._id); // <== This will not work if your DB has _id : ObjectID("xyz") [i.e. you are not overiding defaults]
}
And you should include var ObjectID = require('mongodb').ObjectID; into your code.
You should use .toArray(function(err,.. (Not in your case since you used aggregation framework).This will also cause issue if you are not using findOne() (For more info on this here is the link)
Following is the example which spots the issue (in comments) & working Code:
var mongo = require('mongodb'),
Server = mongo.Server,
Db = mongo.Db,
ObjectID = require('mongodb').ObjectID;
var BSON = require('mongodb').BSONPure;
var server = new Server('localhost', 27017, {
auto_reconnect: true
});
var MongoClient = require('mongodb').MongoClient
//let id = your _id, smth like '6dg27sh2sdhsdhs72hsdfs2sfs'...
var users = ["52e953942a13df5be22cf792","52cbd028e9f43a090ca0c1af","52e953942a13df5be22cf797"];
var obj_ids = [];
for (var i = 0; i < users.length; i++) {
obj_ids.push(new ObjectID(users[i].toString()));
//obj_ids.push(users[i]._id); // <== This will not work if your DB has _id : ObjectID("xyz") [i.e. you are not overiding defaults]
}
MongoClient.connect('mongodb://127.0.0.1:27017/YourDBName', function(err, db) {
console.log('err' + err);
db.collection('posts', function(error, collection) {
//collection.find({_id:{$in: users}}),function(err, docs) { //This will not work
collection.find({_id:{$in: obj_ids}}).toArray(function(err, docs) {
console.log("Printing docs from Array. count " + docs.length);
docs.forEach(function(doc) {
console.log("Doc from Array ");
console.dir(doc);
});
});
});
});

Is there a way to define a virtual field in Geddy model?

Is it possible to define a temp field / virtual field in geddy model?
Like in the form I've use the input fields tmpFirstName and tmpLastName but when submitted I want to store the information in a single column name.
Thanks
This can be trivially achieved with the new lifecycle methods (thanks to you!).
In your controller:
this.create = function (req, resp, params) {
var self = this
, person = geddy.model.Person.create(params);
person.firstname = params.firstname;
person.lastname = params.lastname;
if (!person.isValid()) {
this.respondWith(person);
}
else {
person.save(function(err, data) {
if (err) {
throw err;
}
self.respondWith(person, {status: err});
});
}
};
In your model:
this.defineProperties({
name: {type: 'string'}
});
this.beforeSave = function () {
this.name = this.firstname + ' ' + this.lastname;
}
Note that you don't declare the "virtual" properties, otherwise geddy will store them in the database.

How to query two collection in mongoose on nodeJs?

hi am new to nodeJs i have to query a table from the result of the query, i have to query another table. i tried the code as follows but it returns only null.
action(function getpositions(req){
var namearray = [];
NHLPlayerStatsDaily.find ({"created_at": {$gt: new Date(y+"-"+m+"-"+d)}}, function(err,position){
if(!err)
{
for (i=0;i< position.length; i++)
{
var obj = JSON.stringify(position[i]);
var pos = JSON.parse(obj);
var p = pos["player_stats_daily"]["content"]["team_sport_content"]["league_content"]["season_content"]["team_content"]["team"]["id"]
NHLTeam.find({"sdi_team_id": p}, "first_name nick_name short_name sport_id", function(err, team){
if (!err){
var obj = JSON.stringify(team);
var pos = JSON.parse(obj);
namearray.push(team)
}
})
}
return send(namearray);
}
})
})
if i just push "p" it shows the result and when am query "NHLTeam" in separate function it also shows the result. when querying a collection with in collection it return null. how to query a collection within a collection in mongoose. thanks in advance.
This is not a query problem, it is callback issue. The send(namearray) is called before any of the NHLTeam queries in the loop are completed (remember the result of these queries is passed to callback asynchronously).
What you can do is this (basically tracking when all callbacks are completed):
NHLPlayerStatsDaily.find ({"created_at": {$gt: new Date(y+"-"+m+"-"+d)}}, function(err,position){
if(!err)
{
var total = position.length;
for (i=0;i< position.length; i++)
{
var obj = JSON.stringify(position[i]);
var pos = JSON.parse(obj);
var p = pos["player_stats_daily"]["content"]["team_sport_content"]["league_content"]["season_content"]["team_content"]["team"]["id"]
NHLTeam.find({"sdi_team_id": p}, "first_name nick_name short_name sport_id", function(err, team){
total--;
if (!err){
var obj = JSON.stringify(team);
var pos = JSON.parse(obj);
namearray.push(team);
}
if(total == 0)
send(namearray);
})
}
}
})

Resources