<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Victor Chan</title>
    <description>The latest articles on DEV Community by Victor Chan (@__victorchan).</description>
    <link>https://dev.to/__victorchan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F342472%2Fdb944932-7ffc-4ffe-9a3e-45eec435130f.png</url>
      <title>DEV Community: Victor Chan</title>
      <link>https://dev.to/__victorchan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/__victorchan"/>
    <language>en</language>
    <item>
      <title>3 Javascript features you probably didn't know</title>
      <dc:creator>Victor Chan</dc:creator>
      <pubDate>Mon, 27 Jun 2022 14:30:35 +0000</pubDate>
      <link>https://dev.to/__victorchan/3-javascript-features-you-probably-didnt-know-2936</link>
      <guid>https://dev.to/__victorchan/3-javascript-features-you-probably-didnt-know-2936</guid>
      <description>&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deep object destructuring&lt;/strong&gt;
You probably know you can destructure objects, but did you know you can destructure a destructured object?
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;legs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eyes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;breed&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pets&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Destructuring an array&lt;/strong&gt;
You can also destructure an array by its index
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sixth&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Feb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Apr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;May&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jun&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// expected output: "Jan"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sixth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// expected output: "Jun"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The comma operator&lt;/strong&gt; (,) 
Evaluates each of its operands (from left to right) and returns the value of the last operand.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// expected output: 2&lt;/span&gt;

&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// expected output: 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is used when you need multiple variables for &lt;code&gt;for&lt;/code&gt; loops&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;][&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;] = &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>7 Useful Javascript Tips</title>
      <dc:creator>Victor Chan</dc:creator>
      <pubDate>Thu, 18 Jun 2020 09:31:56 +0000</pubDate>
      <link>https://dev.to/__victorchan/7-useful-javascript-tips-3km8</link>
      <guid>https://dev.to/__victorchan/7-useful-javascript-tips-3km8</guid>
      <description>&lt;h3&gt;
  
  
  7 Useful Javascript Tips
&lt;/h3&gt;

&lt;p&gt;Without further ado, lets dive into it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Filtering falsy values:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have an array of values, you can filter out falsy values(&lt;code&gt;null&lt;/code&gt; &lt;code&gt;undefined&lt;/code&gt; &lt;code&gt;0&lt;/code&gt; &lt;code&gt;""&lt;/code&gt; &lt;code&gt;NaN&lt;/code&gt; &lt;code&gt;false&lt;/code&gt; ) with &lt;code&gt;Boolean()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Example 1
const x = ["a","",3,false,"hello",undefined]
const y = x.filter(Boolean);

console.log(y) // ["a",3,"hello"]

//Use it like this
myArray.filter(Boolean);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Floor a decimal number instead of &lt;code&gt;Math.floor()&lt;/code&gt;&lt;/strong&gt; &lt;br&gt;
Useful for when you want to show whole numbers&lt;br&gt;
(Edit: This removes decimal numbers so it actually acts like &lt;code&gt;Math.ceil()&lt;/code&gt; for negative numbers, credits to @&lt;a href="https://dev.to/veljko94pesic"&gt;veljko94pesic&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Example 1 
const x = 1.5 
const y = ~~x   
console.log(y) // Equals 1  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Example 2
const a = -1.5
const b = ~~a
console.log(b) // Equals -1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Example 3 
const z = ~~2.73123 
console.log(z) // Equals 2   

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Implicit boolean coercion&lt;/strong&gt;&lt;br&gt;
Change a value into a boolean (Instead of &lt;code&gt;Boolean(value)&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const x = {} 
const y = !!x //Equals true 
console.log(y) // true

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Last items in an array&lt;/strong&gt;&lt;br&gt;
You can use Array.slice() with negative indicies to count backwards.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let array = [0, 1, 2, 3, 4, 5, 6, 7, 8]  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(array.slice(-1)); // Equals [8]

console.log(array.slice(-2)); // Equals [7, 8]

console.log(array.slice(-3)); // Equals [6, 7, 8]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Implicit number coercion using &lt;code&gt;+&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Putting a &lt;code&gt;+&lt;/code&gt; in front of any value will attempt to change it to a number, similar to &lt;code&gt;Number(value)&lt;/code&gt;. This can also be used for Date objects as an alternative to &lt;code&gt;Date.getTime()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Example 1 
const x = new Date() 
const y = +x 
console.log(y) //Equals 1591887393586 (gives back time in ms)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful for doing this (get time 10 seconds later)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const z = new Date(+new Date() + 10 *1000)
console.log(z) //Equals 1591887403586

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6.Method parameter validation&lt;/strong&gt; &lt;br&gt;
Lets you throw an error if input not given&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const isRequired = () =&amp;gt; { throw new Error('param is required'); };

const print = (value = isRequired()) =&amp;gt; {   
    console.log(`${value}`)  
};  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(2);// Equals  2  
print()// Throws error  
print(null)// Equals null

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7.Swallow errors for promise all&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Normally, &lt;code&gt;Promise.all()&lt;/code&gt; will throw if any promises inside its array rejects. We can ignore errors by using map and catch for each promise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const promiseArray = [
    Promise.reject(null),
    Promise.resolve(100),
    Promise.resolve("More data"),
    Promise.reject(new Error('Throw an error here'))
];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Map and catch for promises 
//And just console.log them 
const all = await Promise.all(
    promiseArray.map(p =&amp;gt; p.catch(console.log))
)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thats all!&lt;br&gt;
Do you have any Javascript tips?&lt;br&gt;
Feel free to leave them as a comment below 🙂&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>NodeJS: Quick and dirty logging 📈</title>
      <dc:creator>Victor Chan</dc:creator>
      <pubDate>Thu, 11 Jun 2020 11:21:47 +0000</pubDate>
      <link>https://dev.to/__victorchan/nodejs-quick-and-dirty-logging-20m7</link>
      <guid>https://dev.to/__victorchan/nodejs-quick-and-dirty-logging-20m7</guid>
      <description>&lt;p&gt;Here is a quick and dirty guide on how to add logging to your ExpressJS app. I’ll assume that you already know about Javascript, NodeJS and ExpressJS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why logging 📈?&lt;/strong&gt;&lt;br&gt;
Logging is one of the three main pillars of a systems &lt;em&gt;&lt;a href="https://logz.io/blog/what-is-observability/"&gt;Observability&lt;/a&gt;&lt;/em&gt;. Adding logging allows your express app to be monitored, for debugging errors as well as infer usage of the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Im sold 🙋🏻‍♂️, how do I add logging?&lt;/strong&gt;&lt;br&gt;
Just follow the four examples below to get an understanding of it.&lt;br&gt;
Or just skip to Step 4 👇 if you want the answer to just add to your Express app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Have an ExpressJS app prepared&lt;/strong&gt;&lt;br&gt;
For this tutorial we will go through the hello world example found &lt;a href="https://expressjs.com/en/starter/hello-world.html"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also make sure you have NodeJS, npm and express dependencies &lt;a href="https://expressjs.com/en/starter/installing.html"&gt;installed&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//index.js
const express = require("express");
const app = express();
const port = 3000;

app.get("/", (req, res) =&amp;gt; res.send("Hello World!\n"));

app.get("/forbidden", (req, res) =&amp;gt; res.status(403).send("Forbidden!\n"));

app.listen(port, () =&amp;gt; console.log(`Example app listening at http://localhost:${port}`));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run the server on your terminal$ node index.js and you should be able to access it through your browser at &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sxe7Ic2f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2400/1%2AY9_e7NPpCAyqta-lBYhBzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sxe7Ic2f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2400/1%2AY9_e7NPpCAyqta-lBYhBzw.png" alt="It looks simple but it works"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Lets add some simple logging to the console&lt;/strong&gt;&lt;br&gt;
Lets modify the code and add a library called &lt;a href="https://github.com/expressjs/morgan"&gt;Morgan&lt;/a&gt;. &lt;code&gt;npm install morgan&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//index.js
const express = require("express");
const morgan = require("morgan"); //Import it here
const app = express();
const port = 3000;

app.use(morgan("tiny")); //Use it here
app.get("/", (req, res) =&amp;gt; res.send("Hello World!\n"));

app.get("/forbidden", (req, res) =&amp;gt; res.status(403).send("Forbidden!"));

app.listen(port, () =&amp;gt; console.log(`Example app listening at http://localhost:${port}`));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run the server again on your terminal $ node index.js and on your browser test it with the following links:&lt;br&gt;
&lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt;&lt;br&gt;
&lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt;&lt;br&gt;
&lt;a href="http://localhost:3000/forbidden"&gt;http://localhost:3000/forbidden&lt;/a&gt;&lt;br&gt;
&lt;a href="http://localhost:3000/sdfasdfasdf"&gt;http://localhost:3000/sdfasdfasdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👏 Great, you now have logging! 👏&lt;br&gt;
Your terminal should look something like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GWZXCTNi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AmUrr-DrTVzyaPp4ppx7T4Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GWZXCTNi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AmUrr-DrTVzyaPp4ppx7T4Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Store the logs on the machine&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express");
const fs = require("fs");
const app = express();
const port = 3000;

app.use(morgan("tiny")); //We will keep this for demo purposes
app.use(morgan("tiny", { stream: fs.createWriteStream("./access.log", { flags: "a" }),})); //Write to a file here

app.get("/", (req, res) =&amp;gt; res.send("Hello World!\n"));

app.get("/forbidden", (req, res) =&amp;gt; res.status(403).send("Forbidden!"));

app.listen(port, () =&amp;gt; console.log(`Example app listening at http://localhost:${port}`));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once again run the server in your terminal $ node index.js and access the links, the server will now store them into a file called access.log&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AgwTnfRK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AXCPLE7UtgtY_I-JAg6aQnQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AgwTnfRK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AXCPLE7UtgtY_I-JAg6aQnQ.png" alt="Your precious logs, now stored in a file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But what if the server keeps running, and keeps generating logs? Over time the file size could become way too large. This can be solved by rotating the log files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Rotate the logs daily, and remove older logs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lets add another library called file-stream-rotator &lt;code&gt;$ npm install file-stream-rotator&lt;/code&gt; which will allow us to clean up logs past a certain amount of time. Lets also change the type of logging from tiny to combined , this will show more details in the logs.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express");
const morgan = require("morgan");
const fs = require("fs");
const fileStreamRotator = require("file-stream-rotator");
const app = express();
const port = 3000;

//This will ensure log directory exists for acccess logs
const logsFolder = __dirname + "/accessLog";
fs.existsSync(logsFolder) || fs.mkdirSync(logsFolder);
//Create a log stream here
const rotatingLogStream = fileStreamRotator.getStream({
    filename: `${logsFolder}/access-%DATE%.log`,
    frequency: "daily",
    verbose: false,
    date_format: "YYYY-MM-DD",
    max_logs: 45, //Keep for 45 days
});

app.use(morgan("tiny")); //We will keep this for demo purposes
app.use(morgan("combined", {stream: rotatingLogStream}));

app.get("/", (req, res) =&amp;gt; res.send("Hello World!\n"));

app.get("/forbidden", (req, res) =&amp;gt; res.status(403).send("Forbidden!"));

app.listen(port, () =&amp;gt; console.log(`Example app listening at http://localhost:${port}`));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Again run the server in your terminal $ node index.js and access the links, the server will now store them into a folder with log files sorted daily, and cleaning them up after 45 days.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gKfF4CyB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3628/1%2ANSxHNj56Rf4LFmmlWK279A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gKfF4CyB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3628/1%2ANSxHNj56Rf4LFmmlWK279A.png" alt="Now kept daily and rotated, nice and neat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎉 Congratulations! 🎊 You now have a rotating log setup for your Express app with just a few lines of code.&lt;/p&gt;

&lt;p&gt;For a production setup you can easily use &lt;a href="https://www.elastic.co/beats/filebeat"&gt;Filebeats&lt;/a&gt;, &lt;a href="https://www.elastic.co/"&gt;Elasticsearch&lt;/a&gt; and &lt;a href="https://www.elastic.co/kibana"&gt;Kibana&lt;/a&gt; to collect and display these logs onto a dashboard (Out of this posts scope, but maybe I’ll cover it in a future writeup).&lt;/p&gt;

</description>
      <category>node</category>
      <category>express</category>
      <category>logging</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Short snippets: SSH Port Forwarding</title>
      <dc:creator>Victor Chan</dc:creator>
      <pubDate>Thu, 11 Jun 2020 09:21:45 +0000</pubDate>
      <link>https://dev.to/__victorchan/short-snippets-ssh-port-forwarding-1oa6</link>
      <guid>https://dev.to/__victorchan/short-snippets-ssh-port-forwarding-1oa6</guid>
      <description>&lt;h2&gt;
  
  
  How to access a database behind a firewall
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt;  Say you have a remote linux server somewhere remote (AWS EC2 or something) and you want to access a database whose port is blocked by a firewall, you can use the SSH (Secure Shell) local port forwarding command (-L) to gain access on your localhost to that port.&lt;/p&gt;

&lt;p&gt;This is very useful when you’re developing and don’t want to expose your database in the cloud to the outside world.&lt;/p&gt;

&lt;p&gt;Open a terminal and use this command below:&lt;br&gt;&lt;br&gt;
(You may be prompted to enter the user’s password for the remote server)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#This would connect you to port 5432 on your remote server
#And allow you to access it locally on port 5432 also, like magic!

$ ssh -L localhost:5432:localhost:5432 &amp;lt;user&amp;gt;@&amp;lt;server_ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can even specify another port if you wish, like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#This would connect you to port 5432 on your remote server
#And allow you to access it locally on port 8000

$ ssh -L localhost:8000:localhost:5432 &amp;lt;user&amp;gt;@&amp;lt;server_ip&amp;gt;

#You will notice that this creates a new shell
#(You will be logged in to your remote server)
#If you don't want this to happen then you can use the -N flag

$ ssh -NL localhost:8000:localhost:5432 &amp;lt;user&amp;gt;@&amp;lt;server_ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Further Reading:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If you want to find out more about SSH and tunnels, I recommend the two links below, there are much more things you can achieve with SSH tunneling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.ssh.com/ssh/tunneling/example"&gt;SSH Tunneling&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.tunnelsup.com/how-to-create-ssh-tunnels/"&gt;How to create SSH Tunnels&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ssh</category>
      <category>portforwarding</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
