Recent Entries 10
- pattern minor 112d agoNodeJS/Express/socket.io backendI have the backend of a socket.io script running in NodeJS for a web application. A user can login to the site and join a project collaboration (group of users linked to a project). Each project has a list containing multiple questions; each question contains multiple responses. I've been writing the site such that each user associated to a project can see responses from other users in real time and without the need to refresh the page. This is mainly done to teach myself realtime development. The script I have takes user input from their browser and depending on the action, queries a MySQL database - then sends an appropriate response. The code is clearly messy and I want to refactor it and make it more readable. I've been reading Clean Code by Robert C Martin as was recommended to me. Where is the best place to start? I'm wondering if each socket.on response should be placed into a separate file? I am familiar with design patterns and algorithms but wonder how to apply these. ``` var express = require('express'), http = require('http'); //make sure you keep this order var app = express(); var server = http.createServer(app); var io = require('socket.io').listen(server); var mysql = require("mysql"); server.listen(3000, function() { console.log('listening...'); }); var con = mysql.createConnection({ host: "localhost", user: "david", password: "access", database: "AppTester" }); var roomName; io.on('connection', function(socket) { console.log('connection...'); //var handshakeData = socket.request; //console.log(handshakeData._query); // var userID = handshakeData._query['userID']; //var projectID = handshakeData._query['projectID']; socket.on('userInfo', function(data) { var query = 'SELECT ' + ' uc.ucIdCollaboration AS `idCollaboration` ' + ' FROM ' + ' UserCollaboration uc ' + ' INNER JOIN ' + ' Collaboration c ' + ' ON ' + ' c.idCollaboration = uc.ucIdCol
- pattern minor 112d agoRSVP.hash replacement using ES6 PromiseWe have a pretty big code base that made use of RSVP which we are moving to node 4.3.2+. The only RSVP feature we use frequently that's not in the native js Promise api is the hash() function. I expected to either use the RSVP source or find something on stack overflow. Most people appear to be be solving the problem with different constraints & requirements which makes existing solutions I found somewhat complex so I whipped up my own: ``` function hash (hashOfPromises) { var keys = Object.keys(hashOfPromises); return Promise.all(keys.map(function (key) { return hashOfPromises[key]; })).then(function (list) { return list.reduce(function (hashOfResolved, value, i) { hashOfResolved[keys[i]] = value; return hashOfResolved; }, {}); }); } ```
- pattern minor 112d agoList all the git branchesI have written a toy script to list all the git branches in `cwd`. I am interested in knowing how can I make this code more modular and flexible. For example I would like to have features like: - List only local branches. - List only remote branches. - Etc. ``` const os = require('os'); const cp = require('child_process'); const REGEX_STAR = /^\*\s*/g; const promiseExec = (cmd) => new Promise((resolve, reject) => { cp.exec(cmd, (err, stdout, stderr) => { if (err) { return reject(err); } resolve(lines(`${stdout}`)); }); }); const lines = (str) => str.trim().split(os.EOL).map((line) => line.trim().replace(REGEX_STAR, '') ); const branches = () => promiseExec('git branch -a') .then((res) => { console.log(res); }); branches(); ```
- pattern minor 112d agoExpress routing with a login action using SQLiteI'm new to Express and SQL, so I don't know the conventional ways of combining the two. Right now I have done it the following way: ``` app.get('/login', function (req, res) { res.render('login'); }); app.get('/home', function (req, res) { res.render('home'); }); app.post('/login', function (req, res) { db = new sqlite3.Database(file); db.serialize(function () { [...] db.all(query, function (err, rows) { if(rows.length == 1) { [...] res.render('home', { username: rows[0].username }); } else { res.render('login', { message: "Login not successful!" }); } }); }); db.close(); }); ``` However, I feel like the routing should be separated from the database stuff. What should I do different? Or is this normal?
- pattern minor 112d agoMongoose: find() and count() queryBackground I have a query in Mongoose that finds a set of objects, and then returns these said objects together with the total number of them: ``` var itemsPerPage = 4, pageNum = 1; Survey.find({}) .limit(itemsPerPage) .skip(itemsPerPage * pageNum) .then(docs => { if (docs.length === 0) console.log("There are no results matching your query."); else DocModel.count({}) .then(number => { console.log(JSON.stringify({number, docs})); }); }) .catch(console.log); ``` To achieve this I do: - `find` query with params - use `limit` and `skip` to obtain results from correct page - if `docs` is not empty, start a `count` query - return information Problem The problem here, since I need pagination in the query, is that I have to make 2 separate requests to the DB (`find` and `count`) which can potential be very heavy. To optimize this, I would like to avoid the `count` query, but I don't know how. Another issue is the nested promises anti pattern, but that is not the issue I would like to focus on right now. Question I am open to any suggestions on improving this code you may have!
- pattern minor 112d agoES6 cron moduleI just created my first ES6 module in Node, and first time using promises and I was hoping to get some feedback on it. I am the only developer at my current company, so I cannot get feedback here. I just want to make sure whoever comes behind me in the future can have a clean code base to work in. ``` 'use strict'; var fs = require('fs'); var nodeSchedule = require('node-schedule'); class CronJob { constructor(filePath, time, rule) { this.filePath = filePath; this.maxPdfAge = time || 86400000; this.currentDate = Date.parse(new Date()); this.scheduleRule = rule || this.getDefaultRule(); } schedule(callback) { nodeSchedule.scheduleJob(this.scheduleRule, err => { if (err) return callback(err); this.scanFolder((err, info) => { if (err) return callback(err, null); return callback(null, info); }); }); } scanFolder(callback) { scanDirectory(this.filePath) .then(files => { this.findOldPdfs(this.filePath, files, (err, info) => { if (err) return callback(err, null); return callback(null, info); }); }).catch(err => { callback(err, null); }); } findOldPdfs(filePath, pdfs, callback) { var pdfDates = getPdfCreateDates(filePath, pdfs); Promise.all(pdfDates) .then(pdfs => { this.deletePdfs(pdfs, (err, info) => { if (err) return callback(err, null); return callback(null, info); }); }) .catch(err => { callback(err, null); }); } deletePdfs(pdfObjects, callback) { var pdfsToDelete = getPdfsToDelete(pdfObjects, this.currentDate, this.maxPdfAge); Promise.all(pdfsToDelete) .then(successMsgs => { callback(null, suc
- gotcha minor 112d agoDifference between API time and server timeI'm using the openweathermap API to get weather forecast data. I want to make sure that the forecast values are at minimum 2 hours in the future. The API is providing the forecast in 3 hour steps, so I need to make sure that the weather data are in the future. Here is an example response provided by openweathermap API: {"city":{"id":1851632,"name":"Shuzenji", "coord":{"lon":138.933334,"lat":34.966671}, "country":"JP", "cod":"200", "message":0.0045, "cnt":38, "list":[{ "dt":1406106000, "main":{ "temp":298.77, "temp_min":298.77, "temp_max":298.774, "pressure":1005.93, "sea_level":1018.18, "grnd_level":1005.93, "humidity":87 "temp_kf":0.26}, "weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}], "clouds":{"all":88}, "wind":{"speed":5.71,"deg":229.501}, "sys":{"pod":"d"}, "dt_txt":"2014-07-23 09:00:00"} ]} I'm using JSON. The `list` property has the value `dt_txt` in this format: `year-month-day 09:00:00`. Now I need to check if this DateTime is minimum 2 hours in the future and if not I simply take the item at index `1` of the list. I wrote following code: ``` // look for next prediction var weatherList = parsed.list; // Check which time is relevant // Get only time without description or/and date // 2017-03-17 21:00:00 // ~~~~~~~~~~~~~^ var columnIndex = weatherList[0]["dt_txt"].indexOf(":") - 2; // 2017-03-17 21:00:00 // ~~~~~~~~~~~^ var apiHoursString = weatherList[0]["dt_txt"].substring(columnIndex, columnIndex + 2); // server time: var hours = String((new Date()).getHours()); if(hours.length < 2){ hours = "0" + hours; } var apiHoursInt = parseInt(apiHoursString); var hoursInt = parseInt(hours); if((apiHoursInt - hoursInt) < 2){ indexToUse = 1 } ``` I know this code is bad - what is the proper way to do that on Node.js?
- snippet moderate 112d agoGenerate a nested structure based on a list of file pathsI'm currently working on a small application, as a learning exercise for a Javascript novice. I need to generate an object based on a folder structure. Here is an example of the folder structure: RootFolder/FolderA/FolderB/FileA RootFolder/FolderA/FolderB/FileB RootFolder/FolderA/FolderB/FolderC/FileA RootFolder/FolderA/FolderB/FolderC/FileB The desired resulting object should have the following structure: ``` { RootFolder: { FolderA: { FolderB: { FileA: {}, FileB: {}, FolderC: { FileA: {}, FileB: {} } } } } }; ``` So far I came up with the following code and it seems to be doing the job, but I'm concerned with 'eval' use and generally believe there is a more elegant way of doing it. `module.exports = { structure: function(structureArray) { var generatedObject = {}; for (var i = 0; i `structureArray` contains full path strings as in the folder structure example above (e.g. `'RootFolder/FolderA/FolderB/FileA'`)
- pattern minor 112d agoJS/Node.JS Poem Generator (Followup)Original question: Node.JS Automatic Poem Generator This is a followup to the question from above. I am only reposting, as my new code was written from the ground up, and is only slightly similar. This code generates (sentences of) random poems. ``` // Node.JS/JavaScript Poem Generator // This only generates simple sentences, not full poems. // First of all, we need some words. I don't include every part of speech; just the useful ones. // In addition, I mostly chose words that were abstract, pertaining to emotions, or artistic. // a = noun singular // b = noun plural // c = pronoun singular // d = pronoun plural // e = verb action // f = verb linking singular // g = verb linking plural // h = adjective // i = adjective possessive // j = interjection // k = preposition // l = adjverb var a = "darkness,morning,light,feeling,beauty,love,hatred,expression,message,happiness,sadness,anger,frustration".split(","), b = "mornings,lights,feelings,beauties,messages".split(","), c = "he,she,it,I".split(","), d = "them".split(","), e = "ran,went,vanished,died,lived,appeared,disappeared,increased,decreased,augmented,changed".split(","), f = "is,was,had been,will be,could be,might be,should have been,would have been,could have been,should be,would be".split(","), g = "are,were,had been,will be,could be,might be,should have been,would have been,could have been,should be,would be".split(","), h = "abstract,mysterious,permanent,unfortunate,intricate,confusing,true,false,fake,a lie,a stranger,a friend,serene,confusing,an enemy,terrible,enchanting,mine,yours,his,hers,theirs,ours,fortunate,understood,mine,interesting,mutual,artistic,musical".split(","), i = "the,my,your,his,her,their,our,everybody's".split(","), j = "ha,ah,aah,eh,er,hmm,yah,oh".split(","), k = "with,from,during,included,among,by,about,between,after,along with".split(","), l = "quickly,fleetingly,continuously".split(","); // A short helper function to generate a random word based on the type given to it. functio
- pattern minor 112d agoSieve of Eratosthenes performance; Scala very slow compared to Node.jsI am new to Scala so it might show. I am learning it for one of my classes and have to write a performance benchmark. I have written the Sieve of Eratosthenes in both Node.js and Scala, and my Node.js version runs much much quicker for n larger than 100,000. At n = 100,000 the Scala version runs in around a minute where as the Node.js one runs in milliseconds. As far as I know the Scala version is implemented correctly as it finds the first few primes correctly. The big disparity in time leads me to believe it's an algorithmic issue and the two pieces of code likely have different time complexities, but looking at the two pieces of code I don't see any stark differences other than iterating the list a couple extra times in the scala version (with the zipIndex and mapping). Any help would be appreciated. This is my Scala method `// Sieve of Eratosthenes // pseudo code from https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes def sieve (n: Integer) = { // Let A be an array of Boolean values, indexed by integers 2 to n, // initially all set to true. var A = new ListBuffer[Boolean]() var i = 2 for (i b }.map{ case (b, i) => i + 2 }; } ` This is my Node.js code: `let _ = require('lodash'); // Sieve of Eratosthenes // https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes function int (str, base=10) { return parseInt(str, base); } // Input: an integer n > 1. let n = int(process.argv[2]); // Let A be an array of Boolean values, indexed by integers 2 to n, // initially all set to true. let A = _.range(n+1) A[0] = false A[1] = false // for i = 2, 3, 4, ..., not exceeding √n: // if A[i] is true: // for j = i2, i2+i, i2+2i, i2+3i, ..., not exceeding n: // A[j] := false. for(let i = 2; i el); `