Mongodb query doesn't work - arrays

In my image sharing application you can upload images and create albums. When you delete an image from the site it shall also be deleted in the albums (the ones that has got the image in it).
Below is the route for deleting an image, and what I really need help with is why the code for deleting the images (imageName and imageId) in the albums below doesn't work.
Thanks in advance!
The models:
var AlbumSchema = new Schema({
title : String,
imageName : [String],
imageId : [String]
});
modelObject.AlbumSchema = AlbumSchema;
modelObject.Album = mongoose.model('Album', AlbumSchema);
-
var BlogPostSchema = new Schema({
name : String,
size : Number,
type : String,
author : ObjectId,
title : String
});
modelObject.Comment = mongoose.model('Comment', CommentSchema);
modelObject.BlogPost = mongoose.model('BlogPost', BlogPostSchema);
The part that doesn't work in the code below is the following:
albums[i].imageName.remove(j);
albums[i].imageId.remove(j);
albums[i].save(function (err){
if (err) {
console.log(err);
// do something
}
});
Full code:
app.get('/blog/delete/:id', function(req, res){
model.BlogPost.findById(req.params.id, function (err, blog){
var theImage = blog.name;
var query = albumModel.Album.find( { imageName:theImage } )
query.exec(function (err, albums) {
if (!albums) {
blog.remove(function(err) {
console.log(err);
// do something
});
res.redirect('/blogs');
}
else {
for (var i = 0; i < albums.length; i++) {
for (var j = 0; j< albums[i].imageName.length; j++){
if (theImage == albums[i].imageName[j]){
albums[i].imageName.remove(j);
albums[i].imageId.remove(j);
albums[i].save(function (err){
if (err) {
console.log(err);
// do something
}
});
}
}
}
}
blog.remove(function(err) {
console.log(err);
// do something
});
res.redirect('/blogs');
});
});
});

JavaScript arrays don't have a remove method so I would expect your code may be crashing. You should be using code like albums[i].imageName.splice(j, 1); instead.

Related

In NodeJS, convert database query output to Json format

This is my code:
oracledb.getConnection(
{
user : "user",
password : "password",
connectString : "gtmachine:1521/sde1"
},
function(err, connection)
{
if (err) { console.error(err); return; }
connection.execute(
"SELECT filetype, filetypeid from filetype where filetypeid < 6",
function(err, result)
{
if (err) { console.error(err); return; }
response = result.rows;
console.log(response);
res.end(JSON.stringify(response));
});
This is the output
[["Ascii Text",1],["Binary",2],["Graphics - GIF",3],["Graphics - JPEG",4],["HTML",5]]
But my front end angularjs is expecting something in this format:
[{"filetype":"Ascii Text","filetypeid":1},{"filetype":"Binary","filetypeid":2}]
Does any one know what is the standard way to convert this?
These will convert your array of arrays into an array of objects:
var results = [["Ascii Text",1],["Binary",2],["Graphics - GIF",3],["Graphics - JPEG",4],["HTML",5]];
results = results.map(
function(item) {
return {
filetype: item[0],
filetypeid: item[1]
}
}
);
console.log(results);
And in ES6:
var results = [["Ascii Text",1],["Binary",2],["Graphics - GIF",3],["Graphics - JPEG",4],["HTML",5]];
results = results.map(item => ({filetype: item[0], filetypeid: item[1]}));
console.log(results);

Nodejs S3 Delete Multiple Objects Error

I am trying to bulk delete my s3 objects that are associated with one specific blog record in my database, but I'm getting hung up on how to pass the array to my params object to be used in the s3.deleteObjects method, but I'm held up on this error: Check with error message InvalidParameterType: Expected params.Delete.Objects[0].Key to be a string. I feel like it could be related to not having a loop at some point in the process or maybe the format of the values being passed to my s3File array.
Here is the my routing:
.delete(function(req, res){
models.File.findAll({
where: {
blogId: blog.blogId
}
}).then(function(file){
var s3Files = [];
function s3Key(link){
var parsedUrl = url.parse(link);
var fileName = parsedUrl.path.substring(1);
return fileName;
}
for(var k in file){
console.log('Here are each files ' + file[k].fileName);
s3Files.push(s3Key(file[k].fileName));
}
console.log('Here are the s3Files ' + s3Files);
//GOTTEN TO THIS POINT WITHOUT AN ERROR
aws.config.update({accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_KEY, region: process.env.AWS_REGION});
//var awsKeyPath = s3Key(file.fileName);
var s3 = new aws.S3();
var options = {
Bucket: process.env.AWS_BUCKET,
Delete: {
Objects: [{
Key: s3Files
}],
},
};
s3.deleteObjects(options, function(err, data){
if(data){
console.log("File successfully deleted");
} else {
console.log("Check with error message " + err);
}
});
});
Here is the output from console.log('Here are each files ' + file[k].fileName);:
Here are each files https://local-bucket.s3.amazonaws.com/1/2017-02-12/screen_shot_2017-02-01_at_8_25_03_pm.png
Here are each files https://local-bucket.s3.amazonaws.com/1/2017-02-13/test.xlsx
Here are each files https://local-bucket.s3.amazonaws.com/1/2017-02-13/screen-shot-2017-02-08-at-8.23.37-pm.png
Here is the output from console.log('Here are the s3Files ' + s3Files);:
Here are the s3Files 1/2017-02-12/screen_shot_2017-02-01_at_8_25_03_pm.png,1/2017-02-13/test.xlsx,1/2017-02-13/screen-shot-2017-02-08-at-8.23.37-pm.png
Here is the error message:
Check with error message InvalidParameterType: Expected params.Delete.Objects[0].Key to be a string
Key should be a string. You should use array of Object to Objects.
Use this code :
var objects = [];
for(var k in file){
objects.push({Key : file[k].fileName});
}
var options = {
Bucket: process.env.AWS_BUCKET,
Delete: {
Objects: objects
}
};
Change your array as an object
const objects = [
{Key: 'image1.jpg'},
{Key: 'image2.jpg'}
]
Add a new item to the list
for(var k in file){
objects.push({Key : file[k].fileName});
}
Set the array as Objects value in parameters
const options = {
Bucket: process.env.BUCKET,
Delete: {
Objects: objects,
Quiet: false
}
};
Now delete objects
s3.deleteObjects(options, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
Learn more from official docs

CloudantDB & NodeJS: Query data with specific id

I just created a NodeJS cloudantDB web starter on bluemix. Then, I have a API get data from cloudantDB and get successfull but it returns all data. Please see js file:
js file:
app.get('/api/provider', function(request, response) {
console.log("Get method invoked.. ")
db = cloudant.use(dbCredentials.dbProvider);
var docList = [];
var i = 0;
db.list(function(err, body) {
if (!err) {
var len = body.rows.length;
console.log('total # of docs -> '+len);
if(len == 0) {
// error
} else {
body.rows.forEach(function(document) {
db.get(document.id, { revs_info: true }, function(err, doc) {
if (!err) {
if(doc['_attachments']) {
// todo
} else {
var responseData = createResponseDataProvider(
doc._id,
doc.provider_type,
doc.name,
doc.phone,
doc.mobile,
doc.email,
doc.logo,
doc.address
);
}
docList.push(responseData);
i++;
if(i >= len) {
response.write(JSON.stringify(docList));
console.log('ending response...');
response.end();
}
} else {
console.log(err);
}
});
});
}
} else {
console.log(err);
}
});
If I want to add parameter to API to get specific data from DB , Do we need create search index or query on cloudant, afer that call API the same : app.get('/api/provider/:id'). Please help me review and sharing. Thanks
you could get the document by id/name:
db.get(docID, function(err, data) {
// do something
});
references:
https://github.com/apache/couchdb-nano#document-functions
https://github.com/cloudant/nodejs-cloudant#api-reference
You can use a search function of Cloudant.
You need to create search index. In search index you can manage what data you want to get.
Example: https://cloudant.com/for-developers/search/
Following this code after create search index.
...
var query = {q: "id:doc.id"};
db.search('design document name', 'index name', query, function(er, result) {
if (er) {
throw er;
}
console.log(result);
});

$in is not working in loopback

I have an array of string as follows:
['57b69c9d4ae615ef0e312af6','57b69bf477b8e5cd0eb38c88'];
I am converting this into ObjectId as follows:
var objectIds = [];
for(var i=0; i<expenseIds.length; i++){
var _id = new ObjectId(expenseIds[i]);
objectIds.push(_id);
}
objectIds:
[ 57b69c9d4ae615ef0e312af6, 57b69bf477b8e5cd0eb38c88 ]
Now i am using $in query in mongoDb to fetch all the details as follows:
app.models.xxxxx.find({"_id" : {"$in" : objectIds}}, function(err, res){
if(err){
} else {
console.log(res);
}
});
But its not filtering. All the documents in the collection xxxxx is returning.. Please share your ideas. Thanks in advance.
EDIT:
when i am running the command in mongo shell:
db.xxx.find({ _id: { '$in': [ 57b69c9d4ae615ef0e312af6, 57b69bf477b8e5cd0eb38c88 ] }});
It throws error:
SyntaxError: identifier starts immediately after numeric literal #(shell):1:35
You need to enable allowExtendedOperators for your model.
//model.json
...
"options": {
"validateUpsert": true,
"mongodb": {
...
"allowExtendedOperators": true
}
},
...
UPDATE
Also there is a problem with your filter.
app.models.xxxxx.find({where: {"_id" : {"$in" : objectIds}}}, function(err, res){
if(err){
} else {
console.log(res);
}
});
Also you use built-in operators :
app.models.xxxxx.find({where: {id : {inq : objectIds}}}, function(err, res){
if(err){
} else {
console.log(res);
}
});
if you are using mongoose then try this
var objectIds = [];
for(var i=0; i<expenseIds.length; i++){
var _id = mongoose.Types.ObjectId(expenseIds[i]);
objectIds.push(_id);
}
or simply you can do this using MongoDb
var ObjectId = require('mongodb').ObjectID;
var objectIds = [];
for(var i=0; i<expenseIds.length; i++){
var _id = ObjectId(expenseIds[i]);
objectIds.push(_id);
}
please do let me know if this solves your problem

using tedious connection,need to get the total data

hai I am new to tedious and Es-6,It may be a silly question but I am struggling,
I want the total data in a array, using tedious connections here is my code:
getZipData() {
var Connection = require('tedious').Connection;
Request = require('tedious').Request;
var config = {
userName: 'xx',
password: 'xxxx',
server: 'xxx', // You can use 'localhost\\instance' to connect to named instance
options: {
database: 'xxxxx',
rowCollectionOnDone:'true'
}
}
var connection = new Connection(config);
var jsonArray = [];
connection.on('connect', function (err) {
if (err) {
console.log(err)
}
var sql = "SELECT * FROM xxxxx";
return new Promise(function(resolve,reject){
var request = new Request(sql,
(err, rowCount, rows)=>{
if (err) {
reject(err);
}
else {
alert("rows");
console.log(rowCount + 'rows');
}
});
request.on('row', (columns)=>{
var rowObject = {};
columns.forEach((column)=> {
rowObject[column.metadata.colName] = column.value;
});
jsonArray.push(rowObject);
});
connection.execSql(request);
request.on('done', function(rowCount, more) {
console.log(rowCount + ' rows returned');
alert("jsonArray2:"+jsonArray);
resolve(jsonArray)
});
});
})
}
componentWillMount() {
this.getZipData().then(function(resolved){
console.log(resolved);
alert("data:"+resolved);
}).catch(function(rejected){
console.log(rejected);
})
}
when i add the request.on('done', function(rowCount, more) also i didn't get any data can any one give the solution for it,
I want the total data to be displayed
It looks like you're calling resolve before your query has been executed:
var jsonArray = [];
// Register callback for row event
request.on('row', (columns)=>{
var rowObject = {};
columns.forEach((column)=> {
rowObject[column.metadata.colName] = column.value;
});
jsonArray.push(rowObject);
});
// Call resolve before executing request
resolve(jsonArray);
connection.execSql(request);
The docs mention a done event that indicates a request has completed:
request.on('done', function (rowCount, more, rows) {
// Call resolve here instead?
resolve(jsonArray);
});
Disclaimer: I've haven't actually used Tedious, but from the docs linked this looks like what you're looking for.

Resources