how can I run my functions be sequentially - javascript

function Getir() {
var options =
{
host: 'example',
port: 443,
path: '/myUrl'
};
get(options, function (http_res) {
var data = "";
http_res.on("data", function (chunk) {
data += chunk;
});
http_res.on("end", function () {
writeFile('NewHtml.txt', `${data}`, 'utf8', (err) => {
if (err) console.log(err);
});
});
});
}
function DegistirDuzenle() {
if (existsSync("./DatabaseHtml.txt")) {
var DataBaseHtml = readFileSync("./DatabaseHtml.txt", 'utf-8', (err) => { if (err) console.log(err) });
var MyHtml = readFileSync("./NewHtml.txt", 'utf-8', (err) => {if (err) console.log(err) });
if (MyHtml == DataBaseHtml) {
unlink("./NewHtml.txt", (err)=>{ if(err) console.log(err)});
console.log("değişiklik yapılmadı");
} else {
//notification
console.log("değişiklik yapıldı");
//Change
unlink('./DatabaseHtml.txt', (err) => { if(err) console.log(err); });
writeFile('./DatabaseHtml.txt', `${MyHtml}`, 'utf-8', (err) => { if(err) console.log(err); });
unlink('./NewHtml.txt', (err) => { if(err) console.log(err); });
}
}
else {
writeFile('DatabaseHtml.txt', `NewDataBaseHtml`, 'utf8', (err) => {
if (err) console.log(err);
});
}
}
async function Mysystem() {
let mypromis = new Promise((resolve, reject)=>{
resolve(Getir());
});
await mypromis.then(DegistirDuzenle());
}
Mysystem();
I want to create a txt file, read it and delete it later. I have 2 function 1.(Getir()) Create txt, 2.(DegistirDuzenle()) read txt and delete but 2. function starts working first and I getting error. "Error: ENOENT: no such file or directory, open './NewHtml.txt'"

async function Mysystem() {
let mypromis = new Promise((resolve, reject)=>{
resolve(Getir());
});
await mypromis()
await DegistirDuzenle()
}
Mysystem()

You should use
async function Mysystem() {
await Getir();
await DegistirDuzenle();
}
or
function Mysystem() {
return Getir().then(DegistirDuzenle);
}
but not a mix of them. Also notice that when passing the DegistirDuzenle function to .then() as a callback, it shouldn't be invoked (passing the result of a call, not passing the function). Alternatively, you could write .then((getirResult) => DegistirDuzenle()).
Also, for this to work, you'll need to properly promisify the code in Getir and DegistirDuzenle.

Related

Nodejs api structure on calling sql helpers inside another helper all called by a controller

I'm studying to create a simple API with mysql. I've understood and implemented the simple structure in which the app call the router, that call the controller, that call the service. But now i'm developing a multiple tag service module and I've realized that I need to call the same sql queries services declared in it. I show you the code for a better understanding:
tag_service.js:
const mysql = require("../../config/database");
module.exports = {
insertTags: async (data, callBack) => {
const connection = await mysql.connection();
let results = '';
const tagsArray = data.tags.map(tag => [data.id_manager,data.cod_table,data.id_record,tag])
try {
//console.log("at insertCallout...");
await connection.query("START TRANSACTION");
results = await connection.query(
`INSERT INTO s_com_tags (id_manager,cod_table,id_record,tag)
VALUES (?,?,?)`,
[tagsArray]
);
await connection.query("COMMIT");
} catch (err) {
await connection.query("ROLLBACK");
//console.log('ROLLBACK at insertCallout', err);
throw err;
} finally {
await connection.release();
return callBack(null, results);
}
},
deleteTags: async (data, callBack) => {
//console.log(data);
let results = '';
const connection = await mysql.connection();
try {
//console.log("at deleteCallouts...");
await connection.query("START TRANSACTION");
results = await connection.query(
`DELETE FROM s_com_tags
WHERE cod_table = ? AND id_record = ? AND tag IN (?)`,
[data.code_table, data.id_record,data.tags]
);
//console.log(res);
await connection.query("COMMIT");
} catch (err) {
await connection.query("ROLLBACK");
//console.log('ROLLBACK at deleteCallouts', err);
throw err;
} finally {
await connection.release();
return callBack(null, Callouts);
}
},
};
controller's structure that will use the service:
module.exports = {
updateLabDesc: async (req, res, next) => {
try {
const body = req.body;
if(!body.internal_code){
updateLabDesc(body.manager, async (err, results) => {
if (err) {
return next(createError.InternalServerError())
}
});
}
updateTags(body, async (err, results) => {
if (err) {
return next(createError.InternalServerError())
}
return res.json({
success: (results ? 1 : 0 ),
message: (results || 0) + " LabDesc inserted successfully"
});
});
} catch (error) {
next(error)
}
},
};
But the update is something like
updateTag function => {
try {
const current_tags = await getTags(req.body);
let newTags = [];
let oldTags = [];
req.body.tags.forEach(tag => {
if(!current_tags.includes(tag))
newTags.push(tag)
});
await insertTags(newTags);
current_tags.tags.forEach(tag => {
if(!req.body.tags.includes(tag))
oldTags.push(tag)
});
await deleteTags(oldTags);
} catch (error) {
next(error)
}
},
Basically, the tag_service has insertTags and deleteTags but I need the updateTags to call these functions as well. The final controller will call insertTags, deleteTags and updateTags. How can I structure these calls?
It is a controller that could call 2 helpers (insertTag and deleteTags) and another helper (updateTags) that call these 2 helpers. Any ideas?

How to get a variable from a function inside a MongoDB Function?

I have:
var url = "mongodb+srv://exampleuser:53pr1WkCUkkOon0q#cluster0-zfo5z.mongodb.net/test?retryWrites=true&w=majority&useUnifiedTopology=true";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("rw_bewerbung");
var query = { mc_uuid: uuid };
dbo.collection("user_name_history").find(query).toArray(function(err, result) {
if (err) throw(err);
nameHistory = result[0].name_history;
db.close();
});
});
And I want to get the variable nameHistory...how can I do this?
You can do this by converting your code into a promise:
const bewerbung = async (url) => new Promise((resolve, rejected) => {
MongoClient.connect(url, function(err, db) {
if (err) {
rejected(err);
} else {
const dbo = db.db("rw_bewerbung");
const query = {mc_uuid: uuid};
dbo
.collection("user_name_history")
.find(query)
.toArray(function (err, result) {
if (err) {
rejected(err);
} else {
db.close();
resolve(result[0]);
}
});
}
});
}).catch(console.error);
const url = "todo...";
const res = await bewerbung(url);
const nameHistory = res.name_history;
console.info('nameHistory', nameHistory);
.

How to wrap node.js function to access them in organized way

So I come to this, I want to write into a DB and do other operations to work with my program logic, this is the guide that I'm following Node.js Class Creation:
//## This is my mysql_test.js file
function MySQL(){
var mysql = require('mysql');
var con = mysql.createConnection({
//data omitted
});
function AppendRecordset (req, res){
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
con.query(req, function (err, res) {
if (err) throw err;
console.log("1 record inserted");
});
});
}
function UpdateRecordset (req, res) {
con.connect(function(err) {
if (err) throw err;
con.query(req, function (err, res) {
if (err) throw err;
console.log(result.affectedRows + " record(s) updated");
});
});
}
function DeleteRecordset (req, res){
con.connect(function(err) {
if (err) throw err;
con.query(req, function (err, res) {
if (err) throw err;
console.log("Number of records deleted: " + result.affectedRows);
});
});
}
function GetRecordset (req, res) {
con.connect(function(err) {
if (err) throw err;
con.query(req, function (err, res, fields) {
if (err) throw err;
console.log(result);
});
});
}
}
I then have in a separate file(s) my app logic, and want to use what of the above as an object/class so I wrote this accordingly to that guide:
//##this is inside my main app file
//declare the sql processor
require('./mysql_test.js');
var DB = MySQL();
DB.AppendRecordset(sql_string, res); //sql_string contains a valid SQL statement
But when I try to acces it using `` I get this error message: ReferenceError: MySQL is not defined what am I doing wrong?
I think these functions handle your routes, so I didn't change them. Because I don't know how your router is desined.
Create a file dbHangler.js and write this single function:
const mysql = require('mysql');
let con;
exports.execQuery = (query) => {
return new Promise((resolve, reject) => {
if(!con) {
con = mysql.createConnection({
//data omitted
});
}
con.connect(function(err) {
if(err) {
reject(err);
}
else {
console.log("Connected!");
con.query(query, function (err, res) {
if (err) {
reject(err);
}
else {
resolve(res);
}
});
}
});
});
};
In your dedicated.js file, now you can write:
const dbObject = require('path/to/dbHandler');
function AppendRecordset (req, res){
dbObject.execQuery(req)
.then(result => {
console.log(result.affectedRows + " record(s) updated");
})
.catch(error => {
// handle error
});
}
function AppendRecordset (req, res){
dbObject.execQuery(req)
.then(result => {
console.log("Number of records deleted: " + result.affectedRows);
})
.catch(error => {
// handle error
});
}
function AppendRecordset (req, res){
dbObject.execQuery(req)
.then(result => {
console.log(result);
})
.catch(error => {
// handle error
});
}
UPDATE
I hope this one helps you.
DbHandler.js
const mysql = require('mysql');
class DbHandler {
constructor(config) {
let self = this;
self.dbConfig = config;
self.connection = mysql.createConnection({
//data omitted
});
}
queryExecuter(query) {
let self = this;
return new Promise((resolve, reject) => {
self.connection.connect(function (err) {
if (err) {
reject(err);
}
else {
console.log("Connected!");
self.connection.query(query, function (err, res) {
if (err) {
reject(err);
}
else {
resolve(res);
}
});
}
});
});
}
AppendRecordset(query) {
let self = this;
return self.queryExecuter(query)
.then(result => {
console.log("1 record inserted");
return result;
})
.catch(error => {
// handle error
throw error;
});
}
UpdateRecordset(query) {
let self = this;
return self.queryExecuter(query)
.then(result => {
console.log(result.affectedRows + " record(s) updated");
return result;
})
.catch(error => {
// handle error
throw error;
});
}
// and other functions
}
module.exports = DbHandler;
And use it like below:
let DB = require('/path/to/DbHandler');
let myDb = new DB(/* db config */);
db.UpdateRecordset('your query')
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});

append JSON parsing from XML using NodeJS

I have three different sample.xml files which I have to convert into json output. I am trying to append all of their output into one json file. here is my code
const fs = require('fs');
const xml2js = require('xml2js');
parser = new xml2js.Parser({
explicitArray: true
})
fs.readFile('sample.xml', (err, data) => {
parser.parseString(data, (err, result) => {
let output = JSON.stringify(result.planes.plane);
fs.writeFile('output.json', output, 'utf8', (err) => {
if (err) {
throw err;
} else {
console.log('file created..')
}
})
});
});
now I know the function fs.appendfile() but I am not sure how do I do it? I have two more files named: sample2.xml and sample3.xml
this is what I have tried but the problem it is overwriting not appending.
const fs = require('fs');
const xml2js = require('xml2js');
const async = require('async');
parser = new xml2js.Parser({
explicitArray: true
})
let files = ['sample.xml', 'sample2.xml'];
async.map(files, fs.readFile, (err, files) => {
if (err) {
throw err;
} else {
files.forEach((file) => {
parser.parseString(file, (err, result) => {
let output = JSON.stringify(result.planes.plane);
fs.appendFile('output.json', output, 'utf8', (err) => {
if (err) {
throw err;
} else {
console.log('file created..')
}
})
});
})
}
})
You need to read each xml file, get the json-data from it, and then write it to the final file:
async.map(
files,
(file, cb) => {
fs.readFile(file, (err, data) => {
if (err) {
cb(err)
} else {
parser.parseString(data, (err, result) => {
cb(err, result.planes.plane)
})
}
})
},
function (err, results) {
if (err) {
throw err
} else {
let output = JSON.stringify(results)
fs.writeFile('output.json', output, 'utf8', (err) => {
if (err) {
throw err
} else {
console.log('file created...')
}
})
}
}
)

howto Node module.exports

I want to separate the code for executing mysql query in Node, so I am trying to use the Revealing Module pattern here
/* pool -create connection pool mysql*/
var sqlQuery = function (sqlString) {
var _result = pool.getConnection(function (err, connection) {
/* error handling*/
connection.query(sqlString, function (err, rows) {
console.log(this.sql);
if (!err) {
return _result = rows; <============
}
connection.release();
});
return;
});
console.log(_result);
return { recordSet : _result }
};
module.exports = sqlQuery;
How can I return rows to my app.js. the code below for calling sqlQuery is not working
var SqlQuery = require(./path/to/sqlQueryFile);
var rows = SqlQuery('pass sql here').recordSet;
console.log(row);
res.json(rows);
Your code is asynchronous, but you're calling it synchronously.
If you wanted to do it like this, you'll also need to pass a callback to SqlQuery.
/* pool -create connection pool mysql*/
var sqlQuery = function (sqlString, callback) {
var _result = pool.getConnection(function (err, connection) {
/* error handling*/
connection.query(sqlString, function (err, rows) {
console.log(this.sql);
if (!err) {
callback(rows);
}
connection.release();
});
});
};
module.exports = sqlQuery;
And then call it with:
var SqlQuery = require(./path/to/sqlQueryFile);
var rows = SqlQuery('pass sql here', function(recordSet){
console.log(recordSet);
res.json(recordSet);
});
Edit: If you're using newer versions of JavaScript, you have a few more options.
If you have access to Promises, you can do this:
function sqlQuery (sqlString) {
return new Promise((resolve, reject) => {
pool.getConnection(function (err, connection) {
if (err) { return reject(err); } // error handling
connection.query(sqlString, function (err, rows) {
if (err) { return reject(err); }
resolve(rows);
connection.release();
});
});
});
}
module.exports = sqlQuery;
And then you'd use it like:
var SqlQuery = require(./path/to/sqlQueryFile);
SqlQuery('pass sql here')
.then(function(recordSet) {
console.log(recordSet);
res.json(recordSet);
})
.catch(function(err) {
// do your error handling
res.status(500).json({ err: 'Sorry there was an error' });
});
If you're using even newer JavaScript, you can use the async/await syntax (currently available via Babel, and I think in FireFox. Chrome in V55).
var SqlQuery = require(./path/to/sqlQueryFile);
async handleQuery(query) {
try {
var rows = await SqlQuery(query);
res.json(rows);
} catch (e) {
console.log('Error!', e);
}
}
To chain multiple queries together:
async handleQuery(query) {
try {
return await SqlQuery(query);
} catch (e) {
console.log('Error!', e);
}
}
var rows = await handleQuery('select * from tablename');
var rowsToReturn = await handleQuery('select id from another_table where name = "' + rows[0].name + '"');

Categories