MEAN Stack Cannot Update MongoDB Record using PUT method - node.js

Cannot update mongoDB record, using PUT method. Parameters are passing correctly, there must be a problem within a query I guess.
Schema
let Boards = new mongoose.Schema({
title: String,
description: String,
lastUploaded: Number,
owner_id: String
});
Server:
module.exports.updateTime = function (req, res) {
let board = new Board();
let id = new mongoose.Types.ObjectId(req.body._id);
let myquery = { _id: id };
let newvalues = { lastUploaded: req.body.time };
console.log("New time: " + req.body.time); //Number recieved
console.log("Id: " + req.body._id); //String recieved
board.findByIdAndUpdate(myquery, newvalues, function (err, response) {
if (err) {
response = { success: false, message: "Error updating data" };
} else {
response = { success: true, message: "Data updated" };
}
res.json(response);
});
board.close();
};
Client:
public updateTime(updateOptions: UpdateTime): Observable<any> {
let headers = new Headers;
let URI = `${apiUrl}/updateTime`;
headers.append('Content-Type', 'application/json');
return this.http.put(URI, updateOptions, { headers: headers })
.map(this.extractData)
.catch(this.handleError);
}
Router:
router.put('/updateTime', ctrlContent.updateTime);
Finally gave me empty response error through .catch(this.handleError);

There are two bugs that I can see.
First, the first argument to the findByIdAndUpdate method should be an _id itself, not an object with an _id property:
// this will not work
board.findByIdAndUpdate({ _id: id }, newvalues, handler);
// this is how it should be
board.findByIdAndUpdate(_id, newvalues, handler);
Second, you are calling board.close(); outside of the query callback. Closing a connection is propably a mistake, but even if you absolutely need it, you should do it inside the callback function.
Here is a complete server example:
module.exports.updateTime = function (req, res) {
let id = req.body._id;
let newvalues = { lastUploaded: req.body.time };
Board.findByIdAndUpdate(id, newvalues, function (err, response) {
if (err) {
res.json({ success: false, message: "Error updating data" });
} else {
res.json({ success: true, message: "Data updated" });
}
});
};

Related

extract text from image and show it in html page

i have a problem : i made a function to extract text from image with ocr space api in backend when i called it with postTypeRequest(...) in angular it worked
i added a declaration text: string and i gave it the extracted text from backend to call it in html tag and show results in my project but it shows this problem : Type 'Object' is not assignable to type 'string'
the console shows an empty data like this :
[1]: https://i.stack.imgur.com/PmRDn.png
ress is empty and its type is object
so i think ress should return string not object
home.component.ts
onSubmit() {
console.log('image', this.image);
const formData = new FormData();
formData.append('file', this.image ,'file');
return this.api.postTypeRequest('/api/scan/images', formData).subscribe((res) => {
console.log(res) ;
this.text =res //add a variable to call it in html {{text}} and show results
} )
}
scan.controller.js
const uploadImage = (req,res)=> {
let imageDetails = {
name: req.file.originalname,
};
Scan.find({ name: imageDetails.name }, (err, callback) => {
if (err) {
res.json({
err: err,
message: `There was a problem creating the image because: ${err.message}`,
});
} else {
let attempt = {
name: req.file.originalname,
imageUrl: req.file.path,
imageId: "",
};
cloudinary.uploads(attempt.imageUrl).then((result) => {
let imageDetails = {
name: req.file.originalname,
imageUrl: result.url,
imageId: result.id,
};
Scan
.create(imageDetails)
.then((image) => {
imageFilePath =imageDetails.imageUrl
const rlt = ScanService.createScan(imageFilePath).then( ()=>{
res.json({
success: true,
data: image,
ress : rlt
});
})
})
.catch((error) => {
res.json({
success: false,
message: `Error creating image in the database: ${error.message}`,
});
});
});
}
});
}
scan.service.js
const createScan = async (imageFilePath) => {
ocrSpaceApi.parseImageFromUrl(imageFilePath, options)
.then(function (parsedResult) {
console.log('parsedText: \n', parsedResult.parsedText);
console.log('ocrParsedResult: \n', parsedResult.ocrParsedResult);
return parsedResult.parsedText,parsedResult.ocrParsedResult
}).catch(function (err) {
console.log('ERROR:', err);
})}```
The error is ocorring because you have an Object on the JSON response, so you need to check before assign the String value to your text.
In this case i yould recomendo you using a type check to make sure you are receiving your data as you expect.
Something on the lines of
if(typeof res !== "string") {
this.text = "";
return;
}
this.text = res;

Can not get the data in response from Azure httpTriggered Function in NodeJS

I am creating a REST API service using Azure Function in nodeJs. The function is reading some data from Azure SQL and I want it to be returned. I am using tedious package to connect to Azure SQL Database.
const { Connection, Request } = require("tedious");
var data = [];
console.log("0." + data);
const config = {
authentication: {
options: {
userName: "------", // update me
password: "--------" // update me
},
type: "default"
},
server: "----.database.windows.net", // update me
options: {
database: "---", //update me
encrypt: true
}
};
module.exports = async function (context, req, resp) {
const connection = new Connection(config);
context.bindings.response = { status: 201, body: {"time": new Date().getUTCMinutes(), "data": data} };
connection.on("connect", err => {
if (err) {
console.error(err.message);
} else {
queryDatabase(context);
}
});
connection.connect();
//context.bindings.response = { status: 201, body: JSON.stringify(data) };
function queryDatabase(context) {
console.log("Reading rows from the Table...");
// Read all rows from table
const request = new Request(
`SELECT FirstName, LastName FROM Persons`,
(err, rowCount, data) => {
if (err ) {
console.error(err.message);
} else {
console.log(`${rowCount} row(s) returned`);
}
}
);
request.on("row", columns => {
var row = {};
columns.forEach(column => {
row[column.metadata.colName] = column.value;
console.log("%s\t%s", column.metadata.colName, column.value);
data.push(row);
});
});
connection.execSql(request);
}
}
I can read data from Azure SQL Database and the console.log is printing data in the console.
console.log("%s\t%s", column.metadata.colName, column.value);
But while I am trying to bind the data to response, it always shows blank.
{
"time": 52,
"data": []
}
How and where to bind the context.bindings.response?
If I’ve understood you correctly, try this approach ...
// Construct response
const responseJSON = {
"name": "Some name",
"sport": "Some sport",
"message": "Some message",
"success": true
}
context.res = {
// status: 200, /* Defaults to 200 */
body: responseJSON,
contentType: 'application/json'
};

dynamodb deleteItem works, but it's callback returning undefined

I have a deleteItem lambda function I created that deletes an item if it's userId is found. The userId is passed as a pathParameter and it works no problem if the userId is found.
let output = await deleteUser(userId);
console.log("output: " + JSON.stringify(output))
always returns output: undefined
everytime whether it's found and deleted or not. I need a response from the deleteItem operation so that I can return message User not found or User deleted based on that response.
How can I get the dynamodb callback to work properly?
delete.js
const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-1' });
const dynamoDB = new AWS.DynamoDB();
const tableName = process.env.TABLE_NAME;
exports.handler = async (event) => {
let userId = event.pathParameters.userid;
try {
let output = await deleteUser(userId);
console.log("output: " + JSON.stringify(output))
return {
statusCode: 200,
body: JSON.stringify({
message: "User deleted"
})
};
} catch (err) {
console.log("ERROR TIME")
console.log("ERROR:" + err)
return {
statusCode: 500,
body: JSON.stringify({
message: "User failed to be deleted"
})
};
}
async function deleteUser(userId) {
let params = {
TableName: tableName,
"Key": {
"userid": {
"S": userId.toString()
}
}
};
try {
const dbResponse = await dynamoDB.deleteItem(params).promise();
console.log("dbResponse")
console.log(dbResponse)
if (dbResponse.Item) {
console.log(`deleted row with userId of ${userId}`);
return (dbResponse);
}
} catch (err) {
console.log(`user reset failed with ${err}`);
return {
statusCode: 500,
body: JSON.stringify({
errr: err
})
};
}
}
};
This is because dbResponse doesn't have a property named Item, so this condition is never satisfied:
if (dbResponse.Item) {
I suggest reviewing the documentation to see what the expected response format is, or at the very least log dbResponse so you can see what is coming back.

Return not stopping function

I have the following code
insertcontact(root, args) {
var finalresult = '';
var soap = require('soap');
var url = 'http://192.168.100.2/setlead/webservice.asmx?wsdl';
var soapargs = {
contacto: args.contacto, token: args.token, PrimeiroNome: args.PrimeiroNome, Apelidos: args.Apelidos, Email: args.Email, Telefone: args.Telefone, Origem: args.Origem
};
soap.createClient(url, function (err, client) {
if (err) {
console.log(err);
finalresult = err
return { contacto: "error cliente" };
}
else {
client.OperationDetail(args, function (err, result) {
console.log(result);
return { token: result };
});
}
});
return {
contacto: args.contacto,
PrimeiroNome: args.PrimeiroNome,
token: args.token,
Apelidos: args.Apelidos,
Email: args.Email,
Telefone: args.Telefone,
Origem: args.Origem
};
}
}
The operation does not trigger any error and I do receive the result in the console log. But I don't receive the return declared right after that part. The function goes on and I receive the last return declared. Shouldn't it stop at the return result?
This is a classic mistake in Javascript.
The function will return even before starting to create the soap client, because of its async behavior.
That function implementation is not very good as it returns the params whatever the result of the client creation process.
It would be much better to do it like this, with embeded soap args in the return statement if needed, and of course without the last return statement:
// ...
soap.createClient(url, function (err, client) {
if (err) {
console.log(err);
finalresult = err
return { contacto: "error cliente" };
} else {
client.OperationDetail(args, function (err, result) {
console.log(result);
return {
token: result,
soapargs: soapargs
};
});
}
});
wrap your returned object in parenthesis like this
return ({
contacto: args.contacto,
PrimeiroNome: args.PrimeiroNome,
token: args.token,
Apelidos: args.Apelidos,
Email: args.Email,
Telefone: args.Telefone,
Origem: args.Origem
});

Nodejs not returning promise properly

I'm working on a NodeJS + Express + Mongoose + MongoDB project.
This code works fine:
var findRecord = function(id) {
// find record by id
return User.findOne({
_id: id
}).then(function(record) {
// if record not found
if (!record) {
return Promise.reject(constant.NOT_FOUND);
} else {
// return found object
return Promise.resolve({
data: record,
status: constant.READ_SUCCESS
});
}
}, function() {
// if there is error reading record
return Promise.reject(constant.READ_ERROR);
});
};
Don't know what is wrong with this one:
var allRecords = function(skip, limit) {
// find all records
return User.find({}).limit(limit).skip(skip)
.then(function(records) {
console.log('executed');
// if records found
return Promise.resolve({
data: records,
status: constant.READ_SUCCESS,
});
}, function() {
return Promise.reject(constant.READ_ERROR);
});
};
executed never prints on console
Even this one also don't work:
var allRecords = function(skip, limit) {
// find all records
return User.find({}).limit(limit).skip(skip)
.exec(function(records) {
console.log('executed');
// if records found
return Promise.resolve({
data: records,
status: constant.READ_SUCCESS,
});
}, function() {
return Promise.reject(constant.READ_ERROR);
});
};
You need to run exec method:
User.find({}).limit(limit).skip(skip).exec();
Besides of this you shouldn't use Promise.resolve to return result from a promise, just return an object. Also, it's better to use catch callback, instead of second callback of then:
var allRecords = function(skip, limit) {
return User.find({})
.limit(limit)
.skip(skip)
.exec()
.then(records => {
console.log('executed');
// if records found
return {
data: records,
status: constant.READ_SUCCESS,
};
})
.catch(err => Promise.reject(constant.READ_ERROR));
};

Resources