Like any kind of apps, there are difficult issues to solve when we write Node apps.
In this article, we’ll look at some solutions to common problems when writing Node apps.
Creating Rooms in Socket.io
To create rooms in socket.io, we just have to join a room by name.
It doesn’t have to be created.
For instance, we can write:
socket.on('create', (room) => {
socket.join(room);
});
We listen to the create
event with the room name.
We get the room
parameter with the room we want to join.
Then we can emit the event so join
is run:
socket.emit('create', 'room');
'create'
is the event name.
'room'
is the room name.
Use populate with Multiple Schemas in Mongoose
We can chain the populate
calls to select multiple related documents.
For instance, we can write:
Person.find()
.populate('address')
.populate('phone')
.exec((err, results) => {
//...
});
to get the Person
with the address
and phone
models.
Then we get all the related documents in the results
.
Also, we can call populate
with a space-delimited string to specify multiple schemas without call populate
multiple times.
For instance, we can write:
Person.find()
.populate('address phone')
.exec((err, results) => {
//...
});
This is available since version 3.6 of Mongoose.
Download and Unzip a Zip File in Memory in a Node App
We can download and unzip a zip file in memory with the adm-zip
package.
To install it, we run:
npm install adm-zip
Then we can download and unzip a file as follows:
const fileUrl = 'https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v7.8.6/npp.7.8.6.bin.zip'
const AdmZip = require('adm-zip');
const http = require('http');
http.get(fileUrl, (res) => {
let data = [];
let dataLen = 0;
res.on('data', (chunk) => {
data.push(chunk);
dataLen += chunk.length;
})
.on('end', () => {
const buf = Buffer.alloc(dataLen);
for (let i = 0, pos = 0; i < data.length,; i++) {
data[i].copy(buf, pos);
pos += data[i].length;
}
const zip = new AdmZip(buf);
const zipEntries = zip.getEntries();
for (const zipEntry of zipEntries) {
if (zipEntry.entryName.match(/readme/))
console.log(zip.readAsText(zipEntry));
}
};
});
We use the http
module’s get
method to make a GET request to get the zip file.
Then we put the response data chunks into the data
array.
Once we did that, we create a new buffer with Buffer.alloc
.
Then we put the chunks in data
into the buffer according to the position.
Once we copied everything into the buffer, we create a new AdmZip
instance with the buffer.
Then we can get the entries from it.
We looped through the entries in the for-of loop.
Use a DOM Parser with Node.js
There are several DOM parser libraries made for Node apps.
One is the jsdom
library.
We can use it by writing:
const jsdom = require("jsdom");
const dom = new jsdom.JSDOM(`<p>Hello world</p>`);
dom.window.document.querySelector("p").textContent;
We pass in an HTML string into the JSDOM
constructor.
Then we can use the dom.window.document.querySelector
method to get an element from the parsed DOM tree.
There’s also the htmlparser2
library.
It’s faster and more flexible than jsdom
but the API is more complex.
To use it, we can write:
const htmlparser = require("htmlparser2");
const parser = new htmlparser.Parser({
onopentag(name, attrib){
console.log(name, attrib);
}
}, { decodeEntities: true });
parser.write(`<p>Hello world</p>`);
parser.end();
We use the htmlparser.Parser
constructor, which takes an object with the onopentag
handler that’s run when the HTML string is parsed.
name
has the tag name and attrib
has the attributes.
decodeEntities
means that we decode the entities within the document.
cheerio
is another DOM parser library. It has an API similar to jQuery, so it should be familiar to many people.
We can use it by writing:
const cheerio = require('cheerio');
const $ = cheerio.load(`<p>Hello world</p>`);
$('p').text('bye');
$.html();
cheerio.load
loads the HTML string into a DOM tree.
Then we can use the returned $
function to select elements and manipulate it.
Conclusion
We don’t have to create a room explicitly to join it.
We can zip files with a library.
There are many libraries to let us parse HTML strings into a DOM tree.
We can use Mongoose’spopulate
to get related documents.