Cannot read property 'metadata' of null Nodejs - node.js

This is my error:
TypeError: Cannot read property 'metadata' of null
at gfs.files.findOne (M:\FinalProject\Commerce\routes\index.js:187:13)
at result (M:\FinalProject\Commerce\node_modules\mongodb\lib\utils.js:414:17)
This is my code :
router.get('/:filename', (req,res) => {
const img = req.params.filename; // Filename
gfs.files.findOne({filename: img}, (req,file) =>{
if(file.metadata.brand=="Mango"){
const brand = "Mango";
displayOne(brand);
}
else if(file.metadata.brand=="Cocotail")
{
const brand = "Cocotail";
displayOne(brand);
}
else if(file.metadata.brand==null)
{
console.log("Null");
}
function displayOne(brand)
{
gfs.files.find({'metadata.brand': brand }).toArray((err,files)=>{
if(!file || file.length ===0)
{
return res.status(404).json({
err: 'No files exist'
});
}
if(file.contentType === 'image/jpeg' || file.contentType === 'image/png')
{
file.isImage = true;
}
else
{
res.status(404).json({
err: 'Not an image'
});
file.isImage = false;
}
res.render('singleproduct',{
file:file,
relatedProduct:files, // Related Products
isSearch:0
});
});
}
});
});
Please give me any ideas about this error. i couldn't find out what is the major reason for this error. I searched on google but there are no appropriate solutions for that.____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Thank you

Did you console what you get just above
(file.metadata.brand=="Mango")
in file? seems you don't get any data from
gfs.files.findOne({filename: img}
try this:
if(file && file.metadata.brand=="Mango"){
const brand = "Mango";
displayOne(brand);
}
else if(file && file.metadata.brand=="Cocotail")
{
const brand = "Cocotail";
displayOne(brand);
}
else if(file && file.metadata.brand==null)
{
console.log("Null");
}
else{
console.log("didinot find value")
}

Related

Formidable package treat some fields as Files

I'm using to parse form/data with the formidable package, it works great but some inputs are treated as files not as fields.
Example : I send the data from the front-end with the http package in flutter like this.
var request = http.MultipartRequest('POST', postUri)
..fields['username'] = _username!
..fields['password'] = _password!
..fields['address'] = _address!
..files.add(await http.MultipartFile.fromPath(
'coverPic',
_coverImage!.path,
contentType: MediaType('image', coverPicType),
));
All fields parsed successfully instead of the address, treated as file, I don't know why ! The text inside the address was :
it's near, don't be late
The function inside Node js:
function formDataParser() {
return (req, res, next) => {
const form = formidable({});
form.parse(req, (err, fields, files) => {
console.log(fields);
console.log(files);
if (err)
return next(err);
if (!fields || !Object.keys(fields).length)
return next(err);
if (!files || !Object.keys(files).length)
return next(err);
for (var file in files) {
const image = files[file];
if (!image.originalFilename || !image.size || !image.mimetype)
return next(new Error('File specification not found');
const imageName = image.originalFilename;
const imageExt = imageName.slice(
((imageName.lastIndexOf('.') - 1) >>> 0) + 2
);
if (image.size > 10000000) {
const error = new Error('File is too large! ' + imageName);
error.originalError = 'Throwing Custom Error';
error.statusCode = 403;
return next(error);
}
if (image.mimetype !== 'image/jpeg' && image.mimetype !== 'image/png' && image.mimetype !== 'image/jpg') {
const error = new Error('File type is not allowed! ' + imageName);
error.originalError = 'Throwing Custom Error';
error.statusCode = 403;
return next(error);
}
if (imageExt !== 'jpg' && imageExt !== 'jpeg' && imageExt !== 'png') {
const error = new Error('File extension is not allowed! ' + imageName);
error.originalError = 'Throwing Custom Error';
error.statusCode = 403;
return next(error);
}
}
if (!req.body)
req.body = {};
for (field in fields) {
req.body[field] = fields[field];
}
for (file in files) {
req.body[file] = files[file];
}
return next();
});
}
}

Need Deep Understanding async/await on NodeJS

I've been trying to understand async/await and Task in NodeJS. I have implemented I need to update db when all process executed.
Below is code samples
const download = require('image-downloader');
const imageDownload = (imgurl) =>{
console.log("inside imageDownload ", new Date())
return new Promise(async(resolve) => {
let imgpath = '/mount/imageDownload/';
if (!fs.existsSync(imgpath)) {
fs.mkdirSync(imgpath, {
recursive: true
});
}
const options = {
url: imgurl,
dest: imgpath
};
console.log("before download image " + assetId + " ", new Date())
download.image(options)
.then(({ filename }) => {
resolve({"error":false, "url":filename});
})
.catch((err) => {
console.log(err);
resolve({"error":true,"message":err});
});
});
}
(async () => {
let downloadUrl1 = "";
let downloadUrl2 = "";
let downloadUrlFirst = await imageDownload("https://dummyimage.com/300.png/09f/fff");
if (typeof downloadUrlFirst.url != 'undefined' && downloadUrlFirst.url != null) {
downloadUrl1 = downloadUrlFirst.url;
}
let downloadUrlSecond = await imageDownload("https://dummyimage.com/300.png/09f/fff");
if (typeof downloadUrlSecond.url != 'undefined' && downloadUrlSecond.url != null) {
downloadUrl2 = downloadUrlSecond.url;
}
if (downloadUrl1 != '' || downloadUrl2 !='' ) {
let updateImagePayload = {}
if (portrait_mounturl != '') {
updateImagePayload.downloadUrl1 = downloadUrl1;
}
if (landscape_mounturl != '') {
updateImagePayload.downloadUrl2 = downloadUrl2;
}
updateImagePayload.modified_date_time = new Date().toISOString();
db.collection("images").findOneAndUpdate({_id:ObjectId(assetId)}, { $set: updateImagePayload }, (err, update) => {
if (err) {
resolve({"error":true,"message": err});
} else {
let resolveStatus = false;
let resolveMessage = "Successfully updated image";
resolve({"error":resolveStatus,"message":resolveMessage});
}
});
}
})();
I need to update if both has async proccess completed.
Note: Image will be optional. Means either 1 image or both
Getting High Memory and CPU utilization
Any help understanding this would be much appreciated.

Neo4jError: Message 'COMMIT' cannot be handled by a session in the READY state

Im new to neo4j (playing with neo4j-Desktop 1.2.4 on a 4.0.0 neo4j-DB the last week) and I started today with the neo4j-javascript-driver (version 4.0.1) in node.js. I've gone through the neo4j-driver doc for javascript and the official neo4j Documentation for Drivers and found no clue on the state of the session.
The minimum code file 'Neo4jDB.js' is:
var Promise = require("bluebird");
const cfg = require('../config/config_all');
var neo4j = require('neo4j-driver');
var driver = neo4j.driver(
cfg.neo4j.uri,
neo4j.auth.basic(cfg.neo4j.user,cfg.neo4j.password),
{ maxTransactionRetryTime: 30000}
);
function Neo4jDB() { // NJDBxx
this.cleanUp = function() {
var session = driver.session();
session.close();
driver.close();
}
function error2msg(msgid,error,msgclass) {
if (typeof error.msgid === 'string' || typeof msgid === 'undefined' ) {
return error;
}
if (typeof msgclass === 'undefined') {
msgclass = 'DatabaseError';
}
return {
msgid : msgid,
msg : error,
msgclass : msgclass,
}
}
function pt_createAuthor(txc,author) {
return new Promise(function(resolve,reject){
if (typeof author !== 'object' || typeof author.name !== 'string') {
reject(error2msg('NJAT01','ParameterError in Author creation',"ParameterError"));
return;
}
txc.run("MERGE (a:Author { name:$nameParam }) "
+"RETURN a.name AS name",
{nameParam: author.name})
.then(authors => {
resolve(authors);
}).catch(error => {
console.log("p_createAuthor-error:",error);
txc.rollback();
reject(error2msg('NJAT02',error));
});
});
}
function pt_createBook(txc,book) {
return new Promise(function(resolve,reject){
if (typeof book !== 'object' || typeof book.title !== 'string' || typeof book.isbn !== 'string') {
reject(error2msg('NJBO01','ParameterError in Book creation',"ParameterError"));
return;
}
txc.run("MERGE (b:Book { title: $titleParam,isbn:$isbnParam }) "
+"RETURN b.title AS title,b.isbn AS isbn",
{titleParam: book.title,isbnParam : book.isbn})
.then(books => {
resolve(books);
}).catch(error => {
console.log("pt_createBook-error:",error);
reject(error2msg('NJBO02',error));
})
});
}
function pt_relateBookAndAuthor(txc,authorname,isbn) {
return new Promise(function(resolve,reject){
if (typeof authorname !== 'string' || typeof isbn !== 'string') {
reject(error2msg('NJBO03','ParameterError in Book relation to Author', "ParameterError"));
return;
}
txc.run("MATCH (a:Author),(b:Book) WHERE a.name = $authorParam AND b.isbn = $isbnParam "
+"CREATE (b)-[r:isAuthor]->(a) RETURN type(r) ",
{authorParam: authorname,isbnParam : isbn})
.then(rel => {
resolve(rel);
}).catch(error => {
console.log("pt_relateBookAndAuthor-error:",error);
reject(error2msg('NJBO02',error));
})
});
}
this.createBookAndAuthor = function(book,author) {
var session,txc;
return new Promise(function(resolve,reject){
if (typeof book !== 'object' || typeof book.title !== 'string' || typeof book.isbn !== 'string') {
reject(error2msg('NJBO03','ParameterError in Book creation',"ParameterError"));
return;
}
if (typeof author !== 'object' || typeof author.name !== 'string') {
reject(error2msg('NJAT03','ParameterError in Author creation',"ParameterError"));
return;
}
session = driver.session({database:'',defaultAccessMode: neo4j.session.WRITE});
txc = session.beginTransaction();
pt_createBook(txc,book)
.then(function(result){
console.log('result-1');
return pt_createAuthor(txc,author);
},function(error){
txc.rollback();
session.close();
reject(error2msg(undefined,error));
}).then(function(result){
if (typeof result === 'undefined') {
return;
}
console.log('result-2');
return pt_relateBookAndAuthor(txc,author.name,book.isbn);
},function(error){
txc.rollback();
session.close();
reject(error2msg(undefined,error));
})
.then(function(result){
if (typeof result === 'undefined') {
return;
}
console.log('result-3');
txc.commit()
.then( () => console.log("commit success"))
.catch( (error) => console.log("commit failed: ",error));
session.close();
resolve(book);
},function(error){
txc.rollback();
session.close();
reject(error2msg(undefined,error));
});
});
}
};
module.exports = new Neo4jDB();
I'm using three discrete routines pt_createAuthor, pt_createAuthor, pt_relateBookAndAuthor. Despite of using one cypher-Statement for the whole task, I've splitted the transaction into these 3 and other basic functions, so that I can combine them in a similar pattern as used in the createBookAndAuthor-Routine also in other comfort routines (one session and one transaction, multiple basic functions).
Currently I'm using some concrete sample data in a spec file:
const pdb = require('./Neo4jDB');
const assert = require('assert');
describe('Neo4jDB',function(){
describe('First Book',function(){
var author1 = {
name:'Boris Grundl'
};
var author2 = {
name:'Bodo Schäfer'
}
var book1 = {
title: 'Leading simple',
subtitle: 'Führen kann so einfach sein',
isbn: '978-3-89749-708-5',
}
it('create pook with 1st author',function(done) {
pdb.createBookAndAuthor(book1,author1)
.then(function(result){
// console.log(result);
done();
},function(error){
console.log(error);
done(error);
})
})
it('merge book with 2nd author',function(done) {
pdb.createBookAndAuthor(book1,author2)
.then(function(result){
// console.log(result);
done();
},function(error){
console.log(error);
done(error);
})
})
it('cleans up',function(done){
pdb.cleanUp();
done();
})
}) // Connection tests.
}); // Neo4jDB

Nodejs REST API function throws error "Callback is not a function"

I am writing a node app's REST API using Sqlite3. The app will have accounts, and the user should be able to create and update one. My code for creating and fetching accounts works as intended, but my update function throws the error: "TypeError: callback is not a function"
The backend is split in two files; db.js – where I set up the database and create the base function for get/post/put/delete, and app.js – where I call the function from db and perform validation checks.
when i run the function in postman, i get error code 500. in vscode, the terminal reads:
Project/rbrneck/rbrneck-backend/db.js:124
callback([], updatedAccount)
^
TypeError: callback is not a function
at Statement.db.run
code:
//in db.js
exports.updateAccountById = (id, updatedAccount, callback) => {
const query = 'UPDATE accounts SET username = ?, password = ? WHERE id = ?'
const values = [
id,
updatedAccount.username,
updatedAccount.password
]
db.run(query, values, (error) => {
if(error) {
if(error.message == "SQLITE_CONSTRAINT: UNIQUE constraint failed: accounts.username") { //username taken
callback(['usernameTaken'])
} else {
callback(['databaseError'])
}
} else {
//const accountUpdated = (this.changes == 1)
callback([], updatedAccount) //HERE IS THE CALLBACK THE ERROR IS REFERRING TO
}
})
}
// in app.js:
app.put('/accounts/:id', (req, res, next) => {
const id = req.params.id
const updatedAccount = req.body
//errors and validation
//type of input
if(typeof(updatedAccount.username) !== 'string' && typeof(updatedAccount.password) !== 'string') {
res.status(422).json({
message: 'Unprocessable Entry'
}).end()
return
}
//does the account exist?
db.getAccountById(id, (errors, oldAccount) => {
if(errors.length > 0) {
res.status(500).json({
message: 'Internal Server Error'
}).end()
return
} else if (!oldAccount) {
res.status(404).end()
return
}
})
//validation:
const validationErrors = []
if(updatedAccount.username.length < USERNAME_MIN_LENGTH) {
validationErrors.push('Username too short')
} else if (updatedAccount.username.length > USERNAME_MAX_LENGTH) {
validationErrors.push('Username too long')
}
if(updatedAccount.password.length < PASSWORD_MIN_LENGTH) {
validationErrors.push('Password too short')
} else if (updatedAccount.password.length > PASSWORD_MAX_LENGTH) {
validationErrors.push('Password too long')
}
if(validationErrors.length > 0) {
res.status(400).json(validationErrors).end()
return
}
db.updateAccountById(updatedAccount, (errors, userId) => {
if(errors.length == 0) {
res.setHeader('Location', '/accounts/' + userId)
res.status(201).end()
} else if (errors.includes('usernameTaken')) {
res.status(400).json(errors).end()
} else {
res.status(500).end()
}
})
})

Delete and EDIT API's using expressJS

I created DELETE API and in the callback function I have written .remove function to delete a product if the id I have given is present. But when I am giving incorrect input, the result is receiving some object which shouldn't be the case. As there is no data with the Id i have given it should be null or undefined.
Can someone help on this?
Route URL-
http://localhost:3000/api/v1/products/:productId/delete
Code -
let deleteProduct = (req, res) => {
if (check.isEmpty(req.params.productId)) {
console.log('productId should be passed')
let apiResponse = response.generate(true, 'productId is missing', 403, null)
res.send(apiResponse)
} else {
productModel.remove({ 'productId': req.params.productId }, (err, result) => {
if (err) {
console.log('Error Occured.')
logger.error(`Error Occured : ${err}`, 'Database', 10)
let apiResponse = response.generate(true, 'Error Occured.', 500, null)
res.send(apiResponse)
} else if (check.isEmpty(result)) {
console.log('Product Not Found.')
let apiResponse = response.generate(true, 'Product Not Found.', 404, null)
res.send(apiResponse)
} else {
console.log('Product Deletion Success')
let apiResponse = response.generate(false, 'Product Deleted Successfully', 200, result)
res.send(apiResponse)
}
})
}
}
let isEmpty = (value) => {
if (value === null || value === undefined || trim(value) === '' || value.length === 0) {
return true;
} else {
return false;
}
}
When I give incorrect productId, Ideally it should give 'Product Not found' but the output is coming as Product Deleted Successfully.
The result will contain an object no matter if it was successful or not, it will never be empty in this case. Please read the documentation here.
check.isEmpty(result) will always be false.

Resources