Jekyll2023-01-17T23:11:59+00:00http://amandafalke.com/feed.xmlAmanda Falke, Software Engineer | BlogHi, I'm Amanda, a software engineer currently located in Portland
Oregon. I am a Software Engineer at Igalia working on the WebKit team. I have a passion for low level code and embedded systems. Previously, before my tech career, I was a professional musician and I still play often and record albums with friends.
Tutorial: Building WPE WebKit for Raspberry Pi 32023-01-17T08:03:00+00:002023-01-17T08:03:00+00:00http://amandafalke.com/igalia/2023/01/17/building-wpe-webkit-for-raspberry-pi-3-tutorial<blockquote>
<p>A lightning guide for building WPE WebKit with buildroot</p>
</blockquote>
<p>This tutorial will be for getting “up and running” with WPE WebKit using a Raspberry Pi 3 using a laptop/desktop with Linux Fedora installed. WPE WebKit has many benefits; you may <a href="https://wpewebkit.org/about/a-good-choice.html">read here about why WPE WebKit is a great choice for embedded devices</a>. WPE WebKit has minimal dependencies and it displays high-quality animations, WebGL and videos on embedded devices.</p>
<p><a href="https://github.com/WebPlatformForEmbedded">WebPlatformForEmbedded</a> is our focus; for this tutorial, we’ll be building WPE WebKit with buildroot to build our image, so, make sure to <a href="https://github.com/WebPlatformForEmbedded/buildroot">clone the buildroot repository</a>.</p>
<h2 id="you-will-need">You will need:</h2>
<blockquote>
<p>Raspberry pi 3 items:</p>
</blockquote>
<ul>
<li>A raspberry pi 3.</li>
<li>A microSD card for the pi. (I usually choose 32GB microSD cards).</li>
<li>An external monitor, extra mouse, and extra keyboard for our rpi3, separately from the laptop.</li>
<li>An HDMI cable to connect the rpi3 to its own external monitor.</li>
</ul>
<blockquote>
<p>Laptop items:</p>
</blockquote>
<ul>
<li>Linux laptop/desktop.
<ul>
<li>This tutorial will be based on Fedora, but you can use Debian or any distro of your choice.</li>
</ul>
</li>
<li>You also need a way to interface the microSD card with your laptop. You can get an SD Adapter for laptops that have an SD Card adapter slot, or you can use an external SD Card adapter interface for your computer.
<ul>
<li>This tutorial will be based on having a laptop with an SD card slot, and hence an SD Card Adapter will work just fine.</li>
</ul>
</li>
</ul>
<blockquote>
<p>Items for laptop to communicate with rpi3:</p>
</blockquote>
<ul>
<li>An ethernet cable to connect the rpi3 to your laptop.</li>
<li>You need some way to get ethernet into your laptop. This is either in the form of an ethernet port on your laptop (not likely), or an adapter of some sort (likely a USB adapter).</li>
</ul>
<h2 id="steps-high-level-overview">Steps: High level overview</h2>
<blockquote>
<p>This is a high level overview of the steps we will be taking.</p>
</blockquote>
<ol>
<li>Partition the blank SD card.</li>
<li>In the <code class="language-plaintext highlighter-rouge">buildroot</code> repository, <code class="language-plaintext highlighter-rouge">make <desired_config></code>.</li>
<li>Run the <code class="language-plaintext highlighter-rouge">buildroot</code> <code class="language-plaintext highlighter-rouge">menuconfig</code> with <code class="language-plaintext highlighter-rouge">make menuconfig</code> to set up <code class="language-plaintext highlighter-rouge">.config</code> file.</li>
<li>Run <code class="language-plaintext highlighter-rouge">make</code> to build <code class="language-plaintext highlighter-rouge">sdcard.img</code> in <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir; change <code class="language-plaintext highlighter-rouge">.config</code> settings as needed.</li>
<li>Write <code class="language-plaintext highlighter-rouge">sdcard.img file</code> to the SD card.</li>
<li>Connect the rpi3 to its own external monitor, and its own mouse and keyboard.</li>
<li>Connect the rpi3 to the laptop using ethernet cable.</li>
<li>Put the SD card into the rpi3.</li>
<li>Setup a shared ethernet connection between the laptop and rpi to get the IP address of rpi.</li>
<li>ssh into the rpi and start WPE WebKit.</li>
</ol>
<h2 id="steps-detailed-overviewsequence">Steps: Detailed overview/sequence</h2>
<h3 id="1-partition-the-blank-sd-card-using-fdisk-create-a-boot-partition-and-a-root-partition">1. Partition the blank SD card using <code class="language-plaintext highlighter-rouge">fdisk</code>. Create a boot partition and a root partition.</h3>
<ul>
<li>Note: this is only needed in case the output image format is root.tar. If it’s sdcard.img, then that is dumped directly to the sdcard, that image is already partitioned internally.</li>
<li>If you’re unfamiliar with fdisk, <a href="https://www.nayab.xyz/linux-tools/partitioning-using-fdisk">this is a good tutorial</a>.</li>
</ul>
<h3 id="2-in-the-buildroot-repository-root-directory-make-the-desired-config">2. In the <code class="language-plaintext highlighter-rouge">buildroot</code> repository root directory, <code class="language-plaintext highlighter-rouge">make</code> the desired config.</h3>
<ul>
<li>Make sure to <a href="https://github.com/WebPlatformForEmbedded/buildroot">clone the buildroot repository</a>.</li>
<li>Since things change a lot over time, it’s important to note the specific <a href="https://github.com/WebPlatformForEmbedded/buildroot/commit/ce9dd9a89a90a50920ca34e2af4a185947123390">buildroot commit</a> this tutorial was built on, and that this tutorial was built on January 12th, 2023. It is recommended to build from that commit for consistency to ensure that the tutorial works for you.</li>
<li>We are building the <code class="language-plaintext highlighter-rouge">cog</code> <code class="language-plaintext highlighter-rouge">2.28</code> wpe with buildroot. See the build options from the <a href="https://github.com/WebPlatformForEmbedded/buildroot">buildroot repository</a>.</li>
<li>Run <code class="language-plaintext highlighter-rouge">make list-defconfigs</code> to get a list of configurations.</li>
<li>Copy <code class="language-plaintext highlighter-rouge">raspberrypi3_wpe_2_28_cog_defconfig</code> and run it: <code class="language-plaintext highlighter-rouge">make raspberrypi3_wpe_2_28_cog_defconfig</code>.</li>
<li>You will quickly get output which indicates that a <code class="language-plaintext highlighter-rouge">.config</code> file has been written in the root directory of the buildroot repository.</li>
</ul>
<h3 id="3-run-the-buildroot-menuconfig-with-make-menuconfig-to-set-up-config-file">3. Run the <code class="language-plaintext highlighter-rouge">buildroot</code> <code class="language-plaintext highlighter-rouge">menuconfig</code> with <code class="language-plaintext highlighter-rouge">make menuconfig</code> to set up <code class="language-plaintext highlighter-rouge">.config</code> file.</h3>
<ul>
<li>Run <code class="language-plaintext highlighter-rouge">make menuconfig</code>. You’ll see options here for configuration. Go slowly and be careful.</li>
<li>Change these settings. Help menus are available for <code class="language-plaintext highlighter-rouge">menuconfig</code>, you’ll see them displayed on the screen.</li>
</ul>
<table>
<thead>
<tr>
<th>Operation in menuconfig</th>
<th>Location</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>ENABLE</td>
<td>Target packages -> Filesystem and flash utilities</td>
<td>dosfstools</td>
</tr>
<tr>
<td>ENABLE</td>
<td>Target packages -> Filesystem and flash utilities</td>
<td>mtools</td>
</tr>
<tr>
<td>ENABLE</td>
<td>Filesystem images</td>
<td>ext2/3/4 root filesystem</td>
</tr>
<tr>
<td>SET VALUE</td>
<td>Filesystem images -> ext2/3/4 root filesystem -> ext2/3/4 variant</td>
<td>ext4</td>
</tr>
<tr>
<td>DISABLE</td>
<td>Filesystem images</td>
<td>initial RAM filesystem linked into linux kernel</td>
</tr>
</tbody>
</table>
<h3 id="4-run-make-to-build-sdcardimg-in-buildrootoutput-dir-change-config-settings-as-needed">4. Run <code class="language-plaintext highlighter-rouge">make</code> to build <code class="language-plaintext highlighter-rouge">sdcard.img</code> in <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir; change <code class="language-plaintext highlighter-rouge">.config</code> settings as needed.</h3>
<ul>
<li>
<p>Run <code class="language-plaintext highlighter-rouge">make</code>. Then get a coffee as the build and cross-compilation will take awhile.</p>
</li>
<li>In reality, you may encounter some errors along the way, as cross-compilation can be an intricate matter.
This tutorial will guide you through those potential errors.</li>
<li>When you encounter errors, you’ll follow a “loop” of sorts:
<blockquote>
<blockquote>
<p>Run <code class="language-plaintext highlighter-rouge">make</code> -> encounter errors -> manually edit <code class="language-plaintext highlighter-rouge">.config</code> file -> -> remove <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir -> run <code class="language-plaintext highlighter-rouge">make</code> again until <code class="language-plaintext highlighter-rouge">sdcard.img</code> is built successfully.</p>
</blockquote>
</blockquote>
</li>
<li>If you encounter CMake errors, such as <code class="language-plaintext highlighter-rouge">fatal error: stdlib.h: No such file or directory, compilation terminated</code>, and you have a relatively new version of CMake on your system, the reason for the error may be that buildroot is using your local CMake instead of the one specified in the buildroot configuration.
<ul>
<li>We will fix this error by setting in <code class="language-plaintext highlighter-rouge">.config</code> file: <code class="language-plaintext highlighter-rouge">BR2_FORCE_HOST_BUILD=y</code>. Then remove <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir, and run <code class="language-plaintext highlighter-rouge">make</code> again.</li>
</ul>
</li>
<li>If you encounter error such as <code class="language-plaintext highlighter-rouge">path/to/buildroot/output/host/lib/gcc/arm-buildroot-linux-gnueabihf/9.2.0/plugin/include/builtins.h:23:10: fatal error: mpc.h: No such file or directory</code>:</li>
<li>then we can fix this error by changing Makefile in <code class="language-plaintext highlighter-rouge">./output/build/linux-rpi-5.10.y/scripts/gcc-plugins/Makefile</code>, by adding <code class="language-plaintext highlighter-rouge">-I path/to/buildroot/output/host/include</code> in <code class="language-plaintext highlighter-rouge">plugin_cxxflags</code> stanza. Then, as usual, remove <code class="language-plaintext highlighter-rouge">buildroot/output</code> dir, and run <code class="language-plaintext highlighter-rouge">make</code> again.</li>
</ul>
<h3 id="5-write-sdcardimg-file-to-the-sd-card">5. Write <code class="language-plaintext highlighter-rouge">sdcard.img file</code> to the SD card.</h3>
<ul>
<li>At this point after the <code class="language-plaintext highlighter-rouge">make</code> process, we should have <code class="language-plaintext highlighter-rouge">sdcard.img</code> file in <code class="language-plaintext highlighter-rouge">buildroot/output/images</code> directory.</li>
<li>Write this file to the SD card.</li>
<li>Consider using Etcher to do so.</li>
</ul>
<h3 id="6-connect-the-rpi3-to-its-own-external-monitor-and-its-own-mouse-and-keyboard">6. Connect the rpi3 to its own external monitor, and its own mouse and keyboard.</h3>
<ul>
<li>We’ll have separate monitor, mouse and keyboard all connected to the raspberry pi so that we can use it independently from the laptop.</li>
</ul>
<h3 id="7-connect-the-rpi3-to-the-laptop-using-ethernet-cable">7. Connect the rpi3 to the laptop using ethernet cable.</h3>
<h3 id="8-put-the-sd-card-into-the-rpi3">8. Put the SD card into the rpi3.</h3>
<h3 id="9-setup-a-shared-ethernet-connection-between-the-laptop-and-rpi-to-get-the-ip-address-of-rpi">9. Setup a shared ethernet connection between the laptop and rpi to get the IP address of rpi.</h3>
<p>In general, one of the main problems for connecting via ssh to the Raspberry Pi is to know the IP address of the device.
This is very simple with Raspbian OS; simply turn on the raspberry pi and edit configurations to enable ssh, often over wifi.</p>
<p>This is where the ethernet capabilities of the raspberry pi come in.</p>
<blockquote>
<p>Goal: To find syslog message <code class="language-plaintext highlighter-rouge">DHCPACK</code> acknowledgement and assignment of the IP address after setting up shared connection between raspberry pi and the laptop.</p>
</blockquote>
<blockquote>
<blockquote>
<p>Throughout this process, continually look at logs. Eventually we will see a message DHCPACK which will likely be preceded by several DHCP handshake related messages such as DHCP DISCOVER, REQUEST etc. The DHCPACK message will contain the IP address of the ethernet device, and we will then be able to ssh into it.</p>
</blockquote>
</blockquote>
<ul>
<li>
<ol>
<li>Tail the syslogs of the laptop. On Debian distributions, this is often <code class="language-plaintext highlighter-rouge">/var/log/syslog</code>. Since we are using Fedora, we’ll be using <code class="language-plaintext highlighter-rouge">systemd's</code> <code class="language-plaintext highlighter-rouge">journald</code> with the <code class="language-plaintext highlighter-rouge">journactl</code> command:
<ul>
<li><code class="language-plaintext highlighter-rouge">sudo journalctl -f</code></li>
<li>Keep this open in a terminal window.</li>
<li>You can also come up with a better solution like grepping logs, if you like, or piping output of stdout elsewhere.</li>
</ul>
</li>
</ol>
</li>
<li>
<ol>
<li>In a second terminal window, open up the NetworkManager.
<ul>
<li>Become familiar with existing devices prior to powering on the raspberry pi, by running <code class="language-plaintext highlighter-rouge">nmcli</code>.</li>
</ul>
</li>
</ol>
</li>
<li>
<ol>
<li>Power on the raspberry pi. Watch your system logs.
<ul>
<li>Syslogs will detail the raspberry pi’s <code class="language-plaintext highlighter-rouge">name</code>.</li>
</ul>
</li>
</ol>
</li>
<li>
<ol>
<li>Look for that <code class="language-plaintext highlighter-rouge">name</code> in NetworkManager <code class="language-plaintext highlighter-rouge">nmcli device</code>.
<ul>
<li>Using NetworkManager <code class="language-plaintext highlighter-rouge">nmcli</code>, set up shared connection for the ethernet device.</li>
<li>Setting up a shared connection is as simple as <code class="language-plaintext highlighter-rouge">nmcli connection add type ethernet ifname $ETHERNET_DEVICE_NAME ipv4.method shared con-name local</code></li>
<li><a href="https://fedoramagazine.org/internet-connection-sharing-networkmanager/">This is a good tutorial</a> for setting up a shared connection with NetworkManager.</li>
</ul>
</li>
</ol>
</li>
<li>
<ol>
<li>Once the connection is shared, syslogs will show a <code class="language-plaintext highlighter-rouge">DHCPACK</code> message acknowledging the ethernet device and its IP address. (You may need to power cycle the rpi to see this message, but it will happen).</li>
</ol>
</li>
</ul>
<h3 id="10-ssh-into-the-rpi-and-start-wpe-webkit">10. ssh into the rpi and start WPE WebKit.</h3>
<ul>
<li>Now that we have the IP address of the raspberry pi, we can ssh into it from the laptop: <code class="language-plaintext highlighter-rouge">ssh root@<RPI3_IP_ADDRESS></code>. (The default password is ‘root’. You can also add your user public key to /root/.ssh/authorized_keys on the pi. You can simplify this process by creating an overlay/root/.ssh/authorized_keys on your computer and by specifying the path to the overlay directory in the BR2_ROOTFS_OVERLAY config variable. That will copy everything in the overlay dir to the image.)</li>
<li>After that, export these env variables <code class="language-plaintext highlighter-rouge">WPE_BCMRPI_TOUCH=1</code> and <code class="language-plaintext highlighter-rouge">WPE_BCMRPI_CURSOR=1</code> to enable keyboard and mouse control.
<ul>
<li><em>Why:</em> Recall that generally WPE WebKit is for embedded devices, such as kioks, or set top boxes requiring control with a remote control or similar device or touch interaction. We are exporting these environment variables so that we can “test” WPE WebKit with our separate mouse and keyboard for our raspberry pi without the need for a touch screen or special hardware targets, or a Wayland compositor such as <code class="language-plaintext highlighter-rouge">weston</code>. If this piques your curiosity, please see the <a href="https://wpewebkit.org/about/faq.html#is-wayland-required-to-run-wpe%3F">WPE WebKit FAQ on Wayland</a>.</li>
</ul>
</li>
<li>Start WPE WebKit with <code class="language-plaintext highlighter-rouge">cog</code>: <code class="language-plaintext highlighter-rouge">cog "http://www.igalia.com/"</code></li>
<li>A browser will launch in the external monitor connected to the raspberry pi 3, and we can control the browser with the raspberry pi’s mouse and keyboard!</li>
</ul>
<p>That’s all for now. Feel free to reach out in the support channels for WPE <a href="https://matrix.to/#/#wpe:matrix.org">on Matrix</a>.</p>
<h1 id="wpes-frequently-asked-questions">WPE’s Frequently Asked Questions</h1>
<ul>
<li><a href="https://wpewebkit.org/about/faq.html">https://wpewebkit.org/about/faq.html</a></li>
</ul>A lightning guide for building WPE WebKit with buildrootGetting started with Raspberry Pi 3: choosing an OS2023-01-06T08:03:00+00:002023-01-06T08:03:00+00:00http://amandafalke.com/raspberrypi/2023/01/06/raspberry-pi-3-tutorial<h2 id="motivation">Motivation</h2>
<p>This is a tutorial to get the Raspberry Pi (<code class="language-plaintext highlighter-rouge">rpi</code>) beginner up and running with the device using Linux.</p>
<p>We will cover installing an operating system on the rpi; the operating systems we’ll cover will include <code class="language-plaintext highlighter-rouge">Ubuntu Server</code> and <code class="language-plaintext highlighter-rouge">Raspbian OS</code>.</p>
<p>For the Ubuntu portion, a lot of this tutorial is similar to (and taken from) this tutorial <a href="https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi#4-boot-ubuntu-server">https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi</a>, but I’ve added more details where rpi beginners may get stuck.</p>
<h2 id="tutorial-overview">Tutorial Overview</h2>
<blockquote>
<p>This tutorial focuses on a Raspberry Pi 3. We will install Raspian, Ubuntu. We will do so interfacing with a laptop with Fedora installed, so we’ll be using the <code class="language-plaintext highlighter-rouge">dnf</code> package manager.</p>
</blockquote>
<h2 id="hardware--requirements">Hardware / Requirements</h2>
<blockquote>
<p>Things you’ll need:</p>
</blockquote>
<ul>
<li>WiFi:
<ul>
<li><code class="language-plaintext highlighter-rouge">rpi</code> (Raspberry Pi) hardware version <code class="language-plaintext highlighter-rouge">>=3</code>, e.g. 3 or greater, has built in wifi.</li>
<li>Any older versions will require a dongle.</li>
<li>A WiFi connection</li>
</ul>
</li>
<li>HDMI cable</li>
<li>Extra mouse and keyboard for the rpi device</li>
<li>SDCard slot on your laptop, or an SDCard adapter for your laptop.
<ul>
<li>If you have a Mac, you’ll probably need this adapter.</li>
<li>This tutorial is generally for Linux developers.</li>
</ul>
</li>
<li>SDCard and adapter that is compatible with your rpi.</li>
</ul>
<h2 id="operating-systems-for-the-rpi">Operating Systems for the rpi</h2>
<p>The rpi3 is 64-bit, but the benefits of using 64-bit on the rpi3 are limited due to hardware restrictions.</p>
<h3 id="ubuntu-rpi-compatibility">Ubuntu rpi compatibility</h3>
<p>Ubuntu keeps a downloads page <a href="https://ubuntu.com/download/raspberry-pi">here</a>; this page has compatibility information.</p>
<blockquote>
<p>Some relevant notes about Ubuntu and the rpi3:</p>
</blockquote>
<ul>
<li>Ubuntu Desktop, as of now, only works on rpi 4+ due to requirements.</li>
<li>Ubuntu Server will require a desktop.
<ul>
<li>See <a href="https://www.makeuseof.com/install-desktop-environment-gui-ubuntu-server/">https://www.makeuseof.com/install-desktop-environment-gui-ubuntu-server/</a> to choose and install a desktop.</li>
<li>Installation instructions here: <a href="https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi#3-using-advanced-options">https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi#3-using-advanced-options</a></li>
</ul>
</li>
<li>Ubuntu Core will require <a href="https://ubuntu.com/download/raspberry-pi-core">registration with Ubuntu</a>.
<ul>
<li>Ubuntu Core is a great OS of choice for embedded systems development.</li>
<li>See information about Ubuntu Core here: https://www.youtube.com/watch?v=aekZhezFCHM</li>
</ul>
</li>
</ul>
<blockquote>
<blockquote>
<p>For the rpi 3, Ubuntu Server 22.10 is compatible.</p>
</blockquote>
</blockquote>
<h2 id="installing-with-ubuntu-server-os">Installing with Ubuntu Server OS</h2>
<p>To start the process of installing Ubuntu Server on your rpi, insert an SDCard through its adapter into the SDCard slot on your laptop.</p>
<ol>
<li>Use the <code class="language-plaintext highlighter-rouge">dnf</code> package manager to get the Raspberry Pi Imager.
<code class="language-plaintext highlighter-rouge">sudo dnf install rpi-imager</code></li>
<li>Use root permissions to launch it.
<code class="language-plaintext highlighter-rouge">sudo rpi-imager</code></li>
<li><code class="language-plaintext highlighter-rouge">Operating System</code>: Choose Ubuntu Server 22.10. <a href="https://ubuntu.com/download/raspberry-pi">This is why.</a>.</li>
<li><code class="language-plaintext highlighter-rouge">Storage</code>: Choose your sdcard.</li>
<li>Configure advanced options by clicking the widget.
<ul>
<li>Setup wifi SSID and password, so that rpi can connect to your wifi network.</li>
<li>Enable ssh.</li>
</ul>
</li>
<li>Write. This will take a few minutes.</li>
<li>Insert the SDCard into your RPI.</li>
<li>Power it on.
<ul>
<li>Time to get a couple of coffees. This will take awhile.</li>
</ul>
</li>
<li>You’ll see a login screen, but do <strong>NOT</strong> login yet. Instead, wait, and you’ll see some stuff print out regarding <code class="language-plaintext highlighter-rouge">cloud-init</code>.</li>
<li><em>Wait</em> until the <code class="language-plaintext highlighter-rouge">cloud-init</code> install “stops”, and press enter.</li>
<li>You’ll see a prompt:
<ul>
<li><code class="language-plaintext highlighter-rouge">raspberry pi login:</code></li>
<li>Enter the username you used during step 5 when you configured advanced options. (Usually this is <code class="language-plaintext highlighter-rouge">pi</code> on Raspbian installs and <code class="language-plaintext highlighter-rouge">ubuntu</code> on Ubuntu installs, but these are defaults, and we shouldn’t be using the defaults, hence step 5). Hit enter.</li>
<li>Enter the password (you’ll be prompted to do so).</li>
<li>Now we are at a CLI prompt <code class="language-plaintext highlighter-rouge">pi@raspberrypi:~$</code></li>
</ul>
</li>
</ol>
<p>… We have now installed and logged into Ubuntu Server on RPI!</p>
<ol>
<li>ssh into the raspberry pi from your laptop to establish a connection.
<ul>
<li><em>On the rpi:</em>
<ul>
<li>We don’t have <code class="language-plaintext highlighter-rouge">net-tools</code> installed (<code class="language-plaintext highlighter-rouge">sudo apt install net-tools</code> if we want it), so we’ll use <code class="language-plaintext highlighter-rouge">hostname -I</code> to retrieve the hostname and the IP address.</li>
<li>Note the IP address.</li>
</ul>
</li>
<li><em>Then, on your laptop:</em>
<ul>
<li><code class="language-plaintext highlighter-rouge">ssh pi@<rpi_ip_address></code></li>
<li>Enter password, you’ll be prompted to.</li>
</ul>
</li>
<li>Once we ssh into the rpi successfully, we’ll see an Ubuntu welcome message.</li>
</ul>
</li>
</ol>
<p>That’s all for now.</p>
<blockquote>
<p>Some followups:</p>
</blockquote>
<ul>
<li>The rpi 3 is not compatible with Ubuntu Desktop. That’s why we installed Ubuntu Server. Here are some articles that talk about that: <a href="https://www.makeuseof.com/install-desktop-environment-gui-ubuntu-server/">[1]</a>, <a href="https://www.makeuseof.com/tag/best-linux-desktop-environments/">[2]</a>, <a href="https://www.makeuseof.com/tag/gnome-explained-look-one-linuxs-popular-desktops/">[3]</a>, <a href="https://www.tomshardware.com/how-to/install-ubuntu-raspberry-pi">[4]</a>.</li>
</ul>
<h2 id="installing-with-raspbian">Installing with Raspbian</h2>
<p><em>Mostly</em> the same instructions as above, only you want to install Raspberry Pi <em>legacy</em> OS, with a desktop,
as you’ll see that’s the OS that’s compatible with rpi 3.</p>
<blockquote>
<p>The way we ssh in to an rpi with Raspbian installed will be different from Ubuntu server:</p>
</blockquote>
<ul>
<li>ssh into the raspberry pi from your laptop to establish a connection.
<ul>
<li><em>On the rpi:</em>
<ul>
<li>Run <code class="language-plaintext highlighter-rouge">ifconfig</code> on the raspberry pi terminal.</li>
<li>Note the IP address belonging to <code class="language-plaintext highlighter-rouge">wlan0</code>.</li>
</ul>
</li>
<li><em>Then, on your laptop:</em>
<ul>
<li><code class="language-plaintext highlighter-rouge">ssh pi@<rpi_ip_address></code></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="fun-tips">Fun tips</h2>
<ul>
<li>To use ssh with GUI, you must enable X11 (or, one assumes, Wayland probably).
<ul>
<li><code class="language-plaintext highlighter-rouge">ssh -X pi@<rpi_ip_address> evince /path/to/file.pdf</code> // or <code class="language-plaintext highlighter-rouge">eog /path/to/img.png</code>, etc</li>
</ul>
</li>
<li>To download files:
<ul>
<li>sudo scp pi@<rpi_ip_address>:/path/to/file ~/local/path/to/put/file`</rpi_ip_address></li>
<li>Now that you have the file on your laptop, you may use a GNOME app to view, e.g. <code class="language-plaintext highlighter-rouge">evince ~/local/path/to/put/file</code></li>
</ul>
</li>
</ul>
<h2 id="troubleshooting">Troubleshooting</h2>
<p>If you get:</p>
<blockquote>
<p>SSH warning: Remote host identification has changed</p>
</blockquote>
<ul>
<li>Solve by removing that key for that IP from <code class="language-plaintext highlighter-rouge">.ssh/known_hosts</code>:
<ul>
<li>Run <code class="language-plaintext highlighter-rouge">ssh-keygen -R <rpi_ip_address></code></li>
<li>Then try to ssh in again.</li>
</ul>
</li>
</ul>
<hr />
<h2 id="some-other-helpful-commands-and-related-knowledge">Some other helpful commands and related knowledge</h2>
<ul>
<li>Your <code class="language-plaintext highlighter-rouge">boot</code> drive will be FAT32 because that is the format required to use UEFI firmware.
<ul>
<li>
<p>UEFI is helpful to use in order to boot your modern device from a bootable drive easily.</p>
</li>
<li>
<p>There are differing opinions on this, but it’s probably best to just use FAT32.</p>
</li>
</ul>
</li>
<li>Your <code class="language-plaintext highlighter-rouge">root</code> drive will be <code class="language-plaintext highlighter-rouge">ext4</code>.
<ul>
<li>On a legacy BIOS system, /boot can be anything understood by the bootloader, so you can use ext2, 3, or 4.</li>
<li>On EFI systems you can set /boot to ext4, ESP to vfat and add ext4 driver to the bootloader.</li>
</ul>
</li>
</ul>
<p><span>categories: raspberrypi </span></p>Motivation This is a tutorial to get the Raspberry Pi (rpi) beginner up and running with the device using Linux.Converting a Redux app from thunks to sagas2020-03-22T08:03:00+00:002020-03-22T08:03:00+00:00http://amandafalke.com/tutorials/2020/03/22/converting-thunks-to-sagas<h2 id="motivation">Motivation</h2>
<p>Handling asynchronous effects within Redux apps has generally traditionally been handled with thunks, which are action creators that return functions to be executed later in a delayed way for async side effects such as API calls.</p>
<p>Thunks can involve a lot of nesting and what looks like “the pyramid of doom” and “callback hell.”</p>
<p>Thunks are also very hard to test.</p>
<p>Enter sagas, a long running process in Redux that can listen to actions being fired, dispatch (“put”) a new action, and do multiple things to make our apps more testable, snappy and responsive.</p>
<p>Sagas are generators, so if you don’t know what that means, check out the <a href="http://blog.amandafalke.com/tutorials/2018/02/24/async-await-infinite-regression.html">async await / generators post</a>.</p>
<h2 id="to-upgrade-a-repo-from-using-only-thunks-to-using-sagas">To upgrade a repo from using only thunks to using sagas:</h2>
<ol>
<li>Create a dummy saga</li>
<li>Add in Saga middleware to store configuration, and start/run sagas from store config</li>
<li>Test sagas (generators with generator.next() { value: someValue, done: false } until { … done: true }</li>
<li>Since thunks and sagas can live together in the same repo, you can now move forward with handling async side effects
with new code by using sagas (and being able to test them), and slowly migrate your legacy thunks over to sagas over time.</li>
</ol>
<h3 id="step-1-create-the-root-saga">Step 1. Create the root saga.</h3>
<blockquote>
<p>rootSaga.js</p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import { all, call } from 'redux-saga/effects';
import 'regenerator-runtime/runtime'; // Justification: https://github.com/redux-saga/redux-saga/issues/280
function sagaStub() {
return console.log('Dummy saga here ...');
}
function* dummySaga() {
const dummyReturn = yield call(sagaStub);
return dummyReturn;
}
export default function* rootSaga() {
try {
yield all([
dummySaga(),
]);
} catch (e) {
console.error(e);
}
}
export { dummySaga, sagaStub };
</code></pre></div></div>
<h3 id="step-2-store-configuration">Step 2. Store configuration</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// thunk stuff here ...
// 2a. then add the Saga middleware:
import createSagaMiddleware from 'redux-saga';
import rootSaga from '<path>/rootSaga';
const sagaMiddleware = createSagaMiddleware();
// 2b. there will be some thunk middleware; add in sagaMiddleware to the end of that array. e.g.
const middleware = [ thunk, routerMiddleware(history), createLogger(), otherStuffForThunks, sagaMiddleware ]
// 2c. Make sure that middleware, with your sagaMiddleware, is in the createStore() function ...
// 2d. Start your sagas.
sagaMiddleware.run(rootSaga);
// RESULT: This will just log a 'Dummy saga here ...' to Chrome devtools/Console when you npm start/run your app.
// It's just a dummy saga; it's not hooked into any actions, watching or listening for actions etc.
</code></pre></div></div>
<h3 id="step-3-test">Step 3. Test.</h3>
<blockquote>
<p>sagas-test.js (Enzyme, Jest)</p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import { call } from 'redux-saga/effects';
import { dummySaga, sagaStub } from './rootSaga';
describe('<path>/rootSaga.js', () => {
describe('dummySaga', () => {
it('should use call saga effect to ret console log', () => {
const generator = dummySaga();
const received = generator.next().value;
const expected = call(sagaStub);
expect(received).toEqual(expected);
});
it('should return done after a single yield is completed', () => {
const generator = dummySaga();
generator.next();
const next = generator.next();
expect(next.done).toEqual(true);
});
it('should return false for generator not done, after a single yield', () => {
const generator = dummySaga();
generator.next();
const next = generator.next();
expect(next.done).not.toEqual(false);
});
});
});
</code></pre></div></div>
<h3 id="step-4-have-your-sagas-listen-to-actions">Step 4. Have your sagas listen to actions!</h3>
<h3 id="step-5-over-time-replace-your-old-thunks-with-sagas">Step 5. Over time, replace your old thunks with sagas.</h3>
<p>That’s it for a brief high level overview.</p>
<p><a href="https://gist.github.com/abstractmachines/180c062794f70e75603e477e53006c02">My Github gist</a> on converting thunks to sagas</p>
<script src="https://gist.github.com/abstractmachines/180c062794f70e75603e477e53006c02.js"></script>
<p>Please also see <a href="[link](https://gist.github.com/abstractmachines/180c062794f70e75603e477e53006c02)">the gist itself</a> if you like.</p>
<p><span>Category: tutorials</span></p>MotivationIntro to modern JS for C/C++ developers, part 4: from callbacks to async/await2018-02-24T08:03:00+00:002018-02-24T08:03:00+00:00http://amandafalke.com/tutorials/2018/02/24/async-await-infinite-regression<p>References/Sources:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript">MDN JavaScript</a></li>
<li><a href="http://2ality.com/2018/04/async-iter-nodejs.html">Dr Axel Rauschmayer’s 2ality blog</a></li>
<li><a href="http://exploringjs.com/">Dr Axel Rauschmayer’s ExploringJS site</a></li>
<li><a href="http://javascriptissexy.com/">JavaScript Is Sexy</a></li>
<li><a href="http://www.zsoltnagy.eu/es6-iterators-and-generators-in-practice/">Zsolt Nagy</a></li>
<li>Wikipedia</li>
<li>Stack Overflow</li>
</ul>
<h1 id="table-of-contents">Table of Contents</h1>
<p>Section I. Overview</p>
<ul>
<li><a href="#about-this-article">About this article</a></li>
<li><a href="#higher-order-functions">Higher order functions</a></li>
<li><a href="#js-is-single-threaded-and-uses-async-queues">JS is single threaded and uses async queues</a></li>
<li><a href="#callbacks">Callbacks</a></li>
</ul>
<p>Section 2. The World Turtle</p>
<ul>
<li><a href="#objects">Objects</a></li>
<li><a href="#symbols">Symbols</a></li>
<li><a href="#iterators">Iterators</a></li>
<li><a href="#generators">Generators</a></li>
<li><a href="#promises">Promises</a></li>
<li><a href="#coroutines">Coroutines</a></li>
<li>
<h2 id="asyncawait"><a href="#async-await">Async/await</a></h2>
<h1 id="section-i-overview">Section I. Overview</h1>
<hr />
</li>
</ul>
<h1 id="about-this-article">About this article</h1>
<p>This article will cover a high level, holistic understanding of asynchronous
JavaScript as simply and accessibly as possible from the perspective of the low
level (C/C++/hardware) developer.</p>
<p>For more insight into functional programming I recommend the <a href="https://soundcloud.com/lambda-cast">LambdaCast podcast on SoundCloud</a>.</p>
<p><strong>Infinite regress: turtles all the way down</strong></p>
<p>The purpose of this article is to <a href="https://en.wikipedia.org/wiki/Turtles_all_the_way_down">find the “world turtle”</a> of all of these asynchronous concepts in JavaScript.</p>
<blockquote>
<p><strong>Async/await knowledge relies on Promises + Generators knowledge</strong></p>
<blockquote>
<p><strong>Promises knowledge relies on Generators</strong></p>
<blockquote>
<p><strong>Generators knowledge relies on Iterators</strong></p>
<blockquote>
<p><strong>Iterators knowledge relies on Symbols</strong></p>
<blockquote>
<p><strong>Symbols knowledge relies on Objects</strong></p>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
<h1 id="higher-order-functions">Higher order functions</h1>
<p>In computing, you’ll hear about “higher order functions” a lot.</p>
<p>A higher order function is a function that:</p>
<ul>
<li>Returns a function,</li>
<li>and/or, takes a function as an argument.</li>
<li><a href="https://en.wikipedia.org/wiki/Talk%3AHigher-order_function">see here for a debate on these two points.</a></li>
<li><a href="https://en.wikipedia.org/wiki/Talk%3AHigher-order_function#Is_%22higher-order_function%22_synonymous_with_%22functor%22?">on Functors</a></li>
</ul>
<p>It is often said:</p>
<blockquote>
<p>“In JavaScript, functions are first-class objects.”</p>
</blockquote>
<ul>
<li>In JS, functions are Objects. (<em>Functions are of the Function data type, which is an Object. <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions">MDN</a></em>)</li>
<li>That means that they can be used like any other Object.</li>
<li>So, you can do a lot of stuff with functions, including:</li>
<li>We can pass functions into functions as arguments, and operate on those args.</li>
<li>We can return functions from functions.</li>
</ul>
<blockquote>
<p>Callbacks are a great use case for “functions as first class objects” in JS; passing a function as arguments as per above.</p>
</blockquote>
<blockquote>
<p>Callbacks are higher order functions.</p>
</blockquote>
<h1 id="js-is-single-threaded-and-uses-async-queues">JS is single threaded and uses async queues</h1>
<p>Recall in Verilog and/or hardware/combinational logic that we have <a href="http://www.ee.surrey.ac.uk/Projects/CAL/seq-switching/synchronous_and_asynchronous_cir.htm">synchronous and asynchronous
circuits and hardware such as flip flops and asynchronous latches</a>;</p>
<p>Recall also that C languages are generally synchronous (pthread excepted); that C++
has std::thread, and that we use things in assembly code to pipeline and take into
account particular parts of the shift register pipeline of the CPU.</p>
<ul>
<li>Synchronous: “line 2 cannot execute until line 1 is complete.”</li>
<li>Asynchronous: “Whatever is available and convenient, executes now.”</li>
</ul>
<p>Ever hear this: “JavaScript is single threaded …. AND async.” Well, that’s not
exactly correct. The JS engine uses a call stack… <em>and it uses multiple queues
to simulate asynchronous operations.</em></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function first() {
setTimeout(function(){
console.log(1)
}, 500)
}
function second() {
console.log(2)
}
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>first()
second()
> 2
> 1
</code></pre></div></div>
<p>Wow - that’s cool. Is JS really a single threaded language?</p>
<p>Answer: It absolutely is. It just “emulates” asynchronous behavior via the use of
multiple queues which enqueue events, and fire those events on the call stack <em>when
the scheduler for those events has decided to push those events on the call stack.</em></p>
<p>The concepts above are similar to how Node (V8 Engine) uses a C++ worker queue threadpool
for jobs that have a different processing time (see operating systems and “CPU-Bound”
versus “IO-Bound” jobs).</p>
<p><a href="https://medium.com/@siddharthac6/javascript-execution-of-synchronous-and-asynchronous-codes-40f3a199e687">Read this for more information on the queues and stacks
JS uses to emulate an asynchronous language</a></p>
<p>Callbacks are one of those asynchronous constructs which are placed on a queue when
defined, and which the queue places on the call stack when the scheduler has determined
that it’s time to execute.</p>
<h1 id="callbacks">Callbacks</h1>
<p>Callbacks are functions which are passed as args to other functions, and then
usually <code class="language-plaintext highlighter-rouge">"called back"</code> (called within that containing function, either by name,
or by the arguments object which can be used to access lambdas/anonymous functions
passed in as args). <a href="http://blog.amandafalke.com/tutorials/2017/04/12/intro-to-modern-javascript-for-cpp-developers.html">See my first post in this series for more on the arguments object</a>. But usually, you pass them in - and invoke them - by name.</p>
<p>Since they’re invoked inside another function, <strong>callbacks are also closures.</strong></p>
<p><strong>This and callback context</strong></p>
<p><a href="http://blog.amandafalke.com/tutorials/2017/04/12/intro-to-modern-javascript-for-cpp-developers.html">See my first post in this series on “this/bind/call/apply” for more on setting the correct “this.”</a> - if you’re using “this” relevant to callbacks, make sure to handle
it correctly for how JavaScript scopes variables.</p>
<p>See also:</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Glossary/Callback_function">MDN on callbacks)</a>.</p>
<blockquote>
<p>For C/C++ developers: <a href="https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes/Declaring_and_Using_Callbacks">Callbacks are function pointers in C/C++ (MDN).</a></p>
</blockquote>
<p>A lot of the time, callbacks are used when processing time for a network request
is nondeterministic (which is, a lot of the time). Read more about callbacks on
MDN, Dr Axel Rauschmayer’s site, JavaScriptIsSexy, or similar.</p>
<hr />
<h1 id="section-ii-the-world-turtle">Section II. The World Turtle</h1>
<hr />
<h1 id="objects">Objects</h1>
<p>It’s relative at this point to bring up a few review topics about JS objects:</p>
<ul>
<li>Object property keys must be Strings (or Symbols), so they’re coerced using <code class="language-plaintext highlighter-rouge">.toString()</code></li>
<li>Square bracket notation can be used to access properties (keys) via expression assignment</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const obj = {}
const key = 2
obj[key] = 'yarp'
console.log(obj) // { 2: 'yarp' }
console.log(Object.keys(obj)) // [ '2' ] -> it's a string! Not a number.
</code></pre></div></div>
<h3 id="all-object-keys-must-be-strings">All Object keys must be strings</h3>
<p>See how the Number 2 was converted into a string? That’s because all Object keys
must be a string. <code class="language-plaintext highlighter-rouge">.toString()</code> is called under the hood to convert!</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Note the MDN polyfill</a>.</p>
<h1 id="symbols">Symbols</h1>
<p><strong>Totally Unique</strong></p>
<p>Recall that JavaScript object keys must always be a string (or Symbol), able to be coerced to a string, or an empty string.</p>
<p>So, Symbols are pretty weird. They’re a primitive type; you can’t call “new Symbol”,
because the <code class="language-plaintext highlighter-rouge">new</code> keyword is for Objects.</p>
<p>Every time you call <code class="language-plaintext highlighter-rouge">Symbol()</code>, you create a new unique Symbol, with its own <code class="language-plaintext highlighter-rouge">memory reference.</code></p>
<p>Use cases:</p>
<ul>
<li>Totally unique object keys (don’t appear in iterations*; a “hidden layer” in objects) … avoid name collisions, use globals without fear</li>
<li>Metadata in objects</li>
<li>Add hooks to objects</li>
<li>Enums (since values always different)</li>
<li>Privacy (see <a href="http://blog.amandafalke.com/tutorials/2018/02/23/information-hiding-weakmaps-weaksets.html">Information Hiding post</a>)</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let q = Symbol()
let obj33 = {
prop: 'a prop',
[q]: 'Symbolix'
}
console.log(obj33) // { prop: 'a prop' } ... Symbol doesn't show up!
</code></pre></div></div>
<p><a href="https://gist.github.com/abstractmachines/18ea0dc6b8b98e307e937806b772f974">My Github gist</a> on Well Known Symbols, Reflection and Metaprogramming in JS:</p>
<script src="https://gist.github.com/abstractmachines/18ea0dc6b8b98e307e937806b772f974.js"></script>
<p>Please also see <a href="[link](https://gist.github.com/abstractmachines/18ea0dc6b8b98e307e937806b772f974)">the gist itself</a> for info on information hiding, why instanceOf sometimes lies, and other nerdy arguments.</p>
<h1 id="iterators">Iterators</h1>
<p><strong>We’ve all iterated</strong></p>
<p>We’ve all used <code class="language-plaintext highlighter-rouge">for of</code>, <code class="language-plaintext highlighter-rouge">.forEach</code>, <code class="language-plaintext highlighter-rouge">.every</code>, <code class="language-plaintext highlighter-rouge">.some</code>, and similar constructs.</p>
<p>In ES6, the ES6 iteration protocol is used under the hood with the spread
operator, with array destructuring, Maps and Sets constructors, Promises,
Array methods, and much more.</p>
<h3 id="iterator-object">Iterator Object</h3>
<blockquote>
<p>An Iterator Object has a <code class="language-plaintext highlighter-rouge">next()</code> method which returns <code class="language-plaintext highlighter-rouge">done</code> and <code class="language-plaintext highlighter-rouge">value</code>,
and it iterates until done is truthy: <a href="http://www.zsoltnagy.eu/es6-iterators-and-generators-in-practice/">source</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let iteratorObject = {
next() {
return {
done: true,
value: null
};
}
};
</code></pre></div> </div>
</blockquote>
<h3 id="iterable-object-returns-iterator-object-via-symboliterator">Iterable Object returns Iterator Object via Symbol.iterator</h3>
<blockquote>
<p>An Iterable Object has an iterator method with the key Symbol.iterator that returns an iterator object: <a href="http://www.zsoltnagy.eu/es6-iterators-and-generators-in-practice/">source</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let iterableObject = {
[Symbol.iterator]() { return iteratorObject; }
};
</code></pre></div> </div>
</blockquote>
<h3 id="arrays-are-iterable">Arrays are Iterable</h3>
<p><a href="https://gist.github.com/abstractmachines/1c72a2bb4dee5b09abebee76fa77c0e0">My Github gist on Arrays:</a></p>
<script src="https://gist.github.com/abstractmachines/1c72a2bb4dee5b09abebee76fa77c0e0.js"></script>
<p>More info from <a href="https://gist.github.com/abstractmachines/1c72a2bb4dee5b09abebee76fa77c0e0">my gist</a>:</p>
<p><strong>Converting other things to arrays</strong></p>
<ul>
<li>Array.from()</li>
<li>
<p>Spread operator can convert Sets to Arrays</p>
</li>
<li>The spread operator inserts the values of an iterable into an Array (<a href="http://exploringjs.com/es6/ch_iteration.html">from Dr Axel</a>):</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const arr = ['b', 'c'];
const arr2 = ['a', ...arr, 'd']
// arr2 is now:
> ['a', 'b', 'c', 'd']
</code></pre></div></div>
<h3 id="maps-and-sets-are-iterable-and-plain-objects-arent">Maps and Sets are Iterable, and Plain Objects aren’t</h3>
<p>We don’t iterate with Objects via “Iterable” protocols because of problems with
the prototype chain, and for <a href="http://exploringjs.com/es6/ch_iteration.html#sec_plain-objects-not-iterable">other reasons as well</a>;
instead, we use <code class="language-plaintext highlighter-rouge">Object.entries()</code> and <code class="language-plaintext highlighter-rouge">Object.keys()</code>. In ES6 we also have Maps, Sets:</p>
<p><a href="https://gist.github.com/abstractmachines/ba21a7f296e6d1726a3a2e845834b2ec">My Github gist on Maps and Sets:</a></p>
<script src="https://gist.github.com/abstractmachines/ba21a7f296e6d1726a3a2e845834b2ec.js"></script>
<p>More info from <a href="https://gist.github.com/abstractmachines/ba21a7f296e6d1726a3a2e845834b2ec">my gist</a>:</p>
<h4 id="for-of-on-maps-and-sets">For of on Maps (and Sets)</h4>
<p><strong>Iterating through entire key-value collection with for of</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>> for ( let pair of artists) { console.log(pair) }
[ 'jazz', 'coltrane' ]
[ 'funk', 'curtis mayfield' ]
</code></pre></div></div>
<h4 id="same-thing-with-specifying-key-and-value-for-each-element">Same thing, with specifying key and value for each element</h4>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>> for ( let [key, value] of artists ) { console.log(key, value) }
jazz coltrane
funk curtis mayfield
</code></pre></div></div>
<h4 id="conversions">Conversions</h4>
<p>You can convert a Set to an Array with the Spread Operator : <code class="language-plaintext highlighter-rouge">let anArray = [...aSet]</code></p>
<h3 id="iterators-strings-spread-and-for-of">Iterators: Strings, spread, and for of</h3>
<p><a href="https://gist.github.com/abstractmachines/fb010c0385054237f8b04ae158aed873">Another little gist I made:</a></p>
<script src="https://gist.github.com/abstractmachines/fb010c0385054237f8b04ae158aed873.js"></script>
<h1 id="generators">Generators</h1>
<p>Use cases:</p>
<ul>
<li>Lazy evaluation : only evaluate parts of a function when necessary</li>
<li>Processing large data sets / lots of memory</li>
<li>Asynchronous programming</li>
</ul>
<p>The function signature of a Generator function uses a pointer:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let gen = function * generateRadness () {
// yield something
}
let callGen = gen()
gen.next() // return something that was yielded.
// goto back to Generator.... return (default undefined).
</code></pre></div></div>
<h3 id="generators-are-reentrant">Generators are reentrant</h3>
<p>Most people who have written Assembly have hand-written reentrant functions,
without an operating system. I’ve done this, and it has immensely helped me
to understand what all of this is about.</p>
<p>You can think of Generators as reentrant functions (<a href="https://en.wikipedia.org/wiki/Reentrancy_(computing)">description here</a>) that are “interrupted”
and <code class="language-plaintext highlighter-rouge">yield</code> control. The interrupt is initiated by the <code class="language-plaintext highlighter-rouge">next()</code> invocation
used by a reference to the Generator; when <code class="language-plaintext highlighter-rouge">next()</code> is completed, control flow
is returned to the Generator in the next line of code down. It’s similar to a
<code class="language-plaintext highlighter-rouge">goto</code> statement. A lot of high level developers think that <code class="language-plaintext highlighter-rouge">goto</code> statements are
always bad - but the Linux kernel has thousands of these statements.</p>
<ul>
<li>
<p>Generator functions return a generator object that’s both Iterable AND Iterator,
so they have a <code class="language-plaintext highlighter-rouge">Symbol.iterator</code> method for the traversal/pointer, AND a <code class="language-plaintext highlighter-rouge">.next()</code>.</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">yield</code>: pauses execution (in the Generator)</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">next()</code>: resumes execution (from the caller manipulating the Generator)</p>
</li>
</ul>
<h3 id="generators-implement-iterables">Generators implement iterables</h3>
<p>A generator function returns a generator object which is iterable, and hence may
be consumed by iterable constructs (<code class="language-plaintext highlighter-rouge">for of</code>, etc).</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> function * generateRadness () {
yield 'rad'
yield 'radder'
yield 'raddest'
}
let iterateRadness = generateRadness()
iterateRadness.next() // {value: "rad", done: false}
iterateRadness.next() // {value: "radder", done: false}
iterateRadness.next() // {value: "raddest", done: false}
iterateRadness.next() // {value: undefined, done: true}
</code></pre></div></div>
<p>We know iterables can be consumed with iterator constructors. Same for Generators.
Let’s use some ES6 spreading:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> let destructureRadness = generateRadness()
[ ... destructureRadness ] // (3) ["rad", "radder", "raddest"]
</code></pre></div></div>
<p>Where are we now? We’re at the end! Pointers, people!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> destructureRadness.next() // {value: undefined, done: true}
</code></pre></div></div>
<p>Generators return undefined by default. Let’s make a custom return.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> function * returnToForever () {
yield 'chickCorea'
yield 'is the best'
yield 'shredder'
return 'to forever'
}
let iterator = returnToForever()
iterator.next() // {value: "chickCorea", done: false}
iterator.next() // {value: "is the best", done: false}
iterator.next() // {value: "shredder", done: false}
iterator.next() // {value: "to forever", done: true}
</code></pre></div></div>
<p>You can do all sorts of stuff with Generators. Here’s an up counter.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> let getCountupIterator = function *() {
let i = 0;
while (i <= 10) {
yield i++;
}
}
</code></pre></div></div>
<p>It’s iterable, so we can spread it:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> console.log ( [ ...getCountupIterator() ] // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</code></pre></div></div>
<h3 id="consuming-and-controlling-a-generator-with-an-iterator">Consuming (and controlling) a Generator with an Iterator</h3>
<p>Or we can just create an iterator, and then call next:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> let it = getCountupIterator()
it.next() // {value: 0, done: false}
.....
.....
it.next() // {value: 10, done: false}
it.next() // {value: undefined, done: true}
</code></pre></div></div>
<p>You can also use arguments inside the caller to feed new values to the Generator
which are then used by the Generator in that new context when control flow
returns to the Generator after .next() completes.</p>
<p><strong>Generators Conclusion</strong></p>
<p>There’s a lot you can do here with Generators that I haven’t covered. Look it up!</p>
<h1 id="promises">Promises</h1>
<blockquote>
<p>This article is mostly about generators and async/await, not Promises. The “Promises” section is mostly included so that the reader makes a logical connection between promises and these other async operations. It’s not really a
section that actually covers a lot about Promises at this point.</p>
</blockquote>
<p><a href="https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Promise">Promises: MDN</a></p>
<p><a href="https://developers.google.com/web/fundamentals/primers/promises">Promises: Fundamentals (Google Developers)</a></p>
<p><a href="https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md">Promises: States and Fates</a> is a great document on Promises written by a Google developer Domenic Denicola.</p>
<p>From that article, let’s discuss Promise States and Promise Fates:</p>
<p>States:</p>
<ul>
<li>Fulfilled (settled)</li>
<li>Rejected (settled)</li>
<li>Pending</li>
</ul>
<p>Fates:</p>
<ul>
<li>Resolved</li>
<li>Unresolved</li>
</ul>
<p><em>(A promise is Resolved if resolution operations have no effect (because it’s either
already settled, or it’s chained into another promise).</em></p>
<p>Promise chains are great because they simulate synchronous code by catching all
Exceptions. If you throw an error, you can .catch() it later. <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises">See MDN: Using Promises</a></p>
<p>Most of the time we write Promises from scratch, we use them to wrap old APIs <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises">see MDN</a>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>setTimeout(() => saySomething("10 seconds passed"), 10000);
</code></pre></div></div>
<p>Let’s wrap that in a Promise:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback);
</code></pre></div></div>
<h1 id="coroutines">Coroutines</h1>
<p>See:
http://2ality.com/2015/03/no-promises.html</p>
<p>https://medium.freecodecamp.org/write-modern-asynchronous-javascript-using-promises-generators-and-coroutines-5fa9fe62cf74</p>
<h1 id="async-await">Async await</h1>
<h2 id="using-and-understanding-asyncawait">Using and understanding Async/await</h2>
<p>async/await works a lot like Generators:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">await</code> keyword replaces <code class="language-plaintext highlighter-rouge">yield</code>.</li>
<li>Instead of function*, it uses the async function keyword.
https://medium.freecodecamp.org/some-of-javascripts-most-useful-features-can-be-tricky-let-me-explain-them-4003d7bbed32</li>
</ul>
<p>Know what’d be cool? If Generators could return a promise instead of just a single value, and the external function that controls the .next() of the Generator, would handle the Promise chain until the Generator finally returns. Well, that’s actually the case - we have libraries to do that. Then the Generator still needs an external “controlling” function, like the Iterator above that consumes the Generator as it produces.</p>
<p>However, with async/await, that’s built in! AND we don’t need an external function for it.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> async function doStuff() {
const results = doAsyncXHRStuff() // yields, waits!
return results
}
</code></pre></div></div>
<p><em>Caveats:</em></p>
<ul>
<li>Async/await can only execute sequentially, not in parallel, so choose the use cases wisely;</li>
<li>Async/await always returns a Promise.</li>
</ul>
<p>See:
<a href="https://medium.com/front-end-hacking/modern-javascript-and-asynchronous-programming-generators-yield-vs-async-await-550275cbe433">https://medium.com/front-end-hacking/modern-javascript-and-asynchronous-programming-generators-yield-vs-async-await-550275cbe433</a></p>
<p>See also:
<a href="https://hackernoon.com/async-await-generators-promises-51f1a6ceede2">https://hackernoon.com/async-await-generators-promises-51f1a6ceede2</a></p>
<p><a href="http://www.zsoltnagy.eu/a-practical-introduction-to-es2017-async-await/">http://www.zsoltnagy.eu/a-practical-introduction-to-es2017-async-await/</a></p>
<p><span>Category: tutorials</span></p>References/Sources:Introduction to modern JavaScript, part 3: information hiding2018-02-23T15:03:00+00:002018-02-23T15:03:00+00:00http://amandafalke.com/tutorials/2018/02/23/information-hiding-weakmaps-weaksets<p><em>References:</em></p>
<ul>
<li><em><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap">MDN</a></em></li>
<li><em><a href="http://2ality.com/2016/01/private-data-classes.html">Dr Axel Rauschmeyer</a></em></li>
<li><em><a href="https://crockford.com/javascript/private.html">Douglas Crockford</a></em></li>
<li><em>David Manning</em></li>
</ul>
<h1 id="information-hiding-in-javascript-weakmaps-and-weaksets">Information Hiding in JavaScript: WeakMaps and WeakSets</h1>
<p>“Privacy” in Javascript, aka Encapsulation, if often emulated via Symbol() and similar constructs.</p>
<p>Douglas Crockford says that privacy/privileged methods are possible via <code class="language-plaintext highlighter-rouge">closures</code> (2001). Things have changed a little since then, but that’s a good start.</p>
<h2 id="4-different-ways-to-accomplish-information-hiding">4 different ways to accomplish information hiding</h2>
<p><a href="http://2ality.com/2016/01/private-data-classes.html">Rauschmeyer mentions</a> 4 different ways to accomplish privacy:</p>
<ol>
<li><strong>Keeping data private in the class constructor</strong></li>
<li><strong>Underscore prefix naming conventions for private member variables</strong></li>
<li><strong>WeakMaps and WeakSets</strong></li>
<li><strong>Using Symbols as keys for private properties</strong></li>
</ol>
<p>Let’s discuss these 4 techniques.</p>
<h3 id="option-1-keeping-data-private-in-the-class-constructor">Option 1. Keeping data private in the class constructor</h3>
<p>Methods in the constructor are private. These are called <code class="language-plaintext highlighter-rouge">instance methods</code>. This is very normal for most languages.</p>
<p><code class="language-plaintext highlighter-rouge">Instance methods</code> take up extra memory.</p>
<p><code class="language-plaintext highlighter-rouge">Prototype methods</code> are “shared”.</p>
<p>The constructor method is usually agreed on as one of the better methods. Use let or const to keep it block scoped.
The important part is that the arguments go into the constructor, not the class (similar to C++ copy constructors) in
the JS constructor, and we keep things in the constructor to guarantee privacy and encapsulation.</p>
<p>This article assumes a basic familiarity with C++ programming, the Rule of Three, and OOP. We won’t cover it here.</p>
<h3 id="option-2-underscore-prefix-naming-convention-for-private-member-variables">Option 2. Underscore prefix naming convention for private member variables</h3>
<p>This has the drawback of not actually being private. <code class="language-plaintext highlighter-rouge">_stuff</code></p>
<h3 id="option-3-weakmaps-and-weaksets">Option 3. WeakMaps and WeakSets</h3>
<p>Actual Use Cases for WeakMaps:</p>
<ul>
<li><a href="https://stackoverflow.com/questions/29413222/what-are-the-actual-uses-of-es6-weakmap">Actual Uses of WeakMaps, Stack Overflow</a></li>
<li>WeakMaps are used commonly in JS for information hiding.</li>
<li>They were (are?) used in Firefox Developer Tools.</li>
<li>They are used in credentials. (I’ve seen it).</li>
</ul>
<p>The use cases for these structures were not intuitively obvious to me at first.
It’s a little bit more intuitive when you recall how weak pointers pointers work.
Recall that smart pointers are used in modern C++ to allocate temporary ownership.
Weak pointers are a subset of that. If you’re confused by this, read first about
<code class="language-plaintext highlighter-rouge">smart pointers</code>, then about <code class="language-plaintext highlighter-rouge">weak pointers</code>.</p>
<p>WeakMaps/Set concepts and concerns are <strong>somewhat</strong> similar to the concepts of weak pointers and
shared memory and shared state concepts and concerns. These structures are created
to avoid memory leaks for collections - and also, they are commonly used for
information hiding/encapsulation.</p>
<ul>
<li><strong>Weakly held references (think about how weak/smart pointers work)</strong></li>
<li><strong>NOT enumerable!!</strong> If they were, you could see their data. (There are, of course, getters).
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>If WeakMaps were enumerable, state would depend on garbage collection. [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)
</code></pre></div> </div>
</li>
<li><strong>WeakMaps: keys must be Objects.</strong></li>
<li><strong>WeakSets: data types must be Objects.</strong></li>
</ul>
<h4 id="on-garbage-collection-and-weakmaps--weaksets">On Garbage Collection And WeakMaps / WeakSets</h4>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap">MDN</a></p>
<p>Garbage collection uses nondeterminism to intelligently clean up memory.</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap">MDN : Why WeakMaps</a></p>
<p><strong>With regular maps and sets, there is “no” garbage collection for recently deleted items.
The deleted items are GC’ed after the collection <em>itself</em> is deleted. There is no
element-by-element GC management.</strong></p>
<p>WeakMaps/WeakSets are JavaScript’s answer to the dangling pointer/reference
problem - they allow deleted elements to be garbage collected.</p>
<p><strong>Maps</strong></p>
<p>For the <em>lifetime</em> of the Map, references to its keys and values are held indefinitely.
This blocks garbage collection for keys and values of that Map.</p>
<p>Access happens via iteration/enumeration of keys via indexes.</p>
<p><strong>WeakMaps</strong></p>
<p>WeakMaps allow deleted elements to be garbage collected; the collection
itself does not indefinitely hold references to its keys. Garbage collection is
nondeterministic. That means that the order of and access to the WeakMap collection is
nondeterministic if based on enumeration/iteration.</p>
<p><strong>Hence, WeakMaps aren’t enumerable.</strong></p>
<p>This makes them more secure, because accessors must have a specific reference to
that items. WeakMaps can be used in credentials, for example, or</p>
<p>This also makes them better at handling state changes, Promise handling, and
much more.</p>
<p><a href="https://stackoverflow.com/questions/29413222/what-are-the-actual-uses-of-es6-weakmap">This Stack Overflow post covers</a>
a lot of what I’ve been told by senior engineers, which also aligns with my
research.</p>
<h3 id="option-4-using-symbols-as-keys-for-private-properties">Option 4. Using Symbols as keys for private properties</h3>
<p>The (somewhat obscure) case for using Symbols for privacy/information hiding <a href="https://medium.com/@davidrhyswhite/private-members-in-es6-db1ccd6128a5">has been made on occasion</a>, but <a href="http://2ality.com/2016/01/private-data-classes.html">as Rauschmeyer posits</a>,
it’s not the safest method because properties and Symbols are still enumerable using <code class="language-plaintext highlighter-rouge">Reflect.ownKeys</code>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Use common sense (i.e. constructors) most of the time for encapsulation of private member variables and data in JS.</p>
<p>When required, use WeakMaps and WeakSets.</p>
<p>See you next time,
Amanda</p>
<p><span>Category: tutorials</span></p>References: MDN Dr Axel Rauschmeyer Douglas Crockford David ManningIntroduction to modern JavaScript for C/C++ developers, part 22017-07-11T03:06:20+00:002017-07-11T03:06:20+00:00http://amandafalke.com/tutorials/2017/07/11/intro-to-modern-javascript-for-cpp-developers-2<h1 id="javascript-tutorials-for-the-cc-programmer-part-2--iterators">JavaScript Tutorials for the C/C++ programmer, part 2 : Iterators</h1>
<p>Make sure you’ve read over <a href="http://blog.amandafalke.com/tutorials/2017/04/12/intro-to-modern-javascript-for-cpp-developers.html">Part 1 of this tutorial</a>. Currently, this post “Part 2” is definitively a “work in
progress.”</p>
<p>References:</p>
<ul>
<li>MDN</li>
<li>Wikipedia</li>
<li>Dr Axel Rauschmeyer site</li>
<li>Eric Elliott’s Medium posts on JavaScript Scene</li>
</ul>
<p>Code will generally be restricted to Github gists which I’ll link to so that article can focus on the concepts.</p>
<h2 id="iterators">Iterators</h2>
<p>In JavaScript, an <strong>Iterable</strong> is a data structure that implements the <code class="language-plaintext highlighter-rouge">Symbol.iterator</code> <strong>factory</strong>. <a href="http://blog.amandafalke.com/tutorials/2018/02/24/async-await-infinite-regression.html">More on Symbols</a>.</p>
<p>An Iterator is just a pointer for traversal, similar to a database cursor, or a C++ 14 Iterator.</p>
<p>With iterations over collections, we always assume that we are mapping/transforming/producing outputs, and/or that a
statement can be executed for each element.</p>
<p>Recall that we don’t have to study much about Iterators in JS before we come across in-depth knowledge of how Symbols work.</p>
<blockquote>
<blockquote>
<p>String, Array, TypedArray, Map and Set are all built-in iterables, because each of their prototype objects implements an @@iterator method. In order to be iterable, an object must implement the @@iterator method, meaning that the object (or one of the objects up its prototype chain) must have a property with a @@iterator key which is available via constant Symbol.iterator… <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols">MDN</a></p>
</blockquote>
</blockquote>
<p>We will leave the discussion of Symbols to <a href="http://blog.amandafalke.com/tutorials/2018/02/24/async-await-infinite-regression.html">another future blog post</a>.</p>
<p>We will also assume that by covering Iterators for Arrays and Objects, that the use cases for Sets, Maps, TypedArray
will seem intuitive. We will leave WeakMaps and WeakSets for a later discussion as well.</p>
<h3 id="javascript-iterators-gists">JavaScript Iterators Gists</h3>
<h4 id="sets-and-maps">Sets and Maps</h4>
<p><a href="https://gist.github.com/abstractmachines/ba21a7f296e6d1726a3a2e845834b2ec">Gist “JavaScript Iterators: Sets and Maps” for more info</a>.</p>
<h4 id="arrays">Arrays</h4>
<p><a href="https://gist.github.com/abstractmachines/1c72a2bb4dee5b09abebee76fa77c0e0">Gist</a></p>
<h3 id="iterable-and-iterator-protocols">Iterable and Iterator Protocols</h3>
<p>Recall that <a href="Iterable and Iterator Protocols">an Object can be iterable</a>, and that an Object “is an iterator” when
it implements <code class="language-plaintext highlighter-rouge">next</code> and <code class="language-plaintext highlighter-rouge">done</code> values and API. We will leave the in-depth discussion of Iterators
to <a href="http://blog.amandafalke.com/tutorials/2018/02/24/async-await-infinite-regression.html">another future blog post</a>.</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of"><code class="language-plaintext highlighter-rouge">for of</code></a> iterates over the iterable properties of an Iterable. That’s one example of implementation of Iterable/Iterable protocols.</p>
<p>For now, we will just discuss simple ways to iterate over Arrays.</p>
<h3 id="array-iterators">Array iterators</h3>
<h3 id="use-cases">Use Cases:</h3>
<ul>
<li>Iterate over an Array and transform its values into an output / use existing values</li>
<li>Filter to filter out undesired elements</li>
<li>Map to apply one function to all elements (similar to transform)</li>
<li>Reduce to accumulate values</li>
</ul>
<p><strong><em>We will begin with the simpler Array iterators and work our way into transducers.</em></strong></p>
<p>Note that there are many, many Array.Prototype.DoAThing methods, search the MDN site to learn more.</p>
<h3 id="some">.some</h3>
<p><code class="language-plaintext highlighter-rouge">Array.prototype.some</code></p>
<p><strong>Returns:</strong> a boolean value … IF some elements meet requirement.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const above10 = elem => elem > 10
[1,2,3].some(above10) // false
[10,11].some(above10) // true
</code></pre></div></div>
<h3 id="every">.every</h3>
<p><strong>Returns:</strong> a boolean value … IF all elements meet requirement.</p>
<p>Code is pretty much the same as with <code class="language-plaintext highlighter-rouge">.some</code>.</p>
<h3 id="foreach">.forEach</h3>
<p>Just iterators for collections. Executes a provided function <code class="language-plaintext highlighter-rouge">for each</code> Array element.</p>
<h3 id="filter">Filter</h3>
<p>Filters out undesired elements. There’s a callback function that
returns a boolean whether or not the element is included in the new set.</p>
<p>Since filter returns “new data” instead of mutating existing data, we can
think of filter as being a safe function to use for immutability.</p>
<p>We will use the indexOf() function, which returns a position within the
selected data structure.</p>
<h4 id="filter-example-return-only-unique-elements-make-a-bag-into-a-set">Filter example: Return only unique elements (make a Bag into a Set)</h4>
<p>If you’re familiar with some aspects of Set theory, you’ll know that a Set
has only unique elements, and a Bag (or MultiSet) can have repeated elements.
Essentially, this question asks us to create a Set out of a Bag/MultiSet.</p>
<p>(For C++ related examples, recall Standard Library std::set, std::multiset)</p>
<p><strong>Input: “apple”, “pear”, “peach”, “pear”, “apple”, “kiwi”</strong></p>
<p><strong>Expected Output: “apple”, “pear”, “peach”, “kiwi”</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const fruit = ["apple", "pear", "peach", "pear", "apple", "kiwi"]
const aSet = fruit.filter((elem, index, fruity) => fruit.indexOf(elem) === index)
fruitySet // ["apple", "pear", "peach", "kiwi"]
</code></pre></div></div>
<p>Note the ES6 arrow function syntax. We could have used ES5:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const aSet =
fruit.filter(function(elem, index, fruity) {
fruit.indexOf(elem) === index
})
</code></pre></div></div>
<p>Which is logically equivalent to (and more verbose than):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const aSet = fruit.filter((elem, index, fruity) => fruit.indexOf(elem) === index)
</code></pre></div></div>
<h3 id="map">Map</h3>
<p>Map is used to transform an entire data structure. <a href="https://gist.github.com/abstractmachines/ba21a7f296e6d1726a3a2e845834b2ec">Please see my Sets and Maps Gist for more info</a>.</p>
<blockquote>
<blockquote>
<p>“Pure functions are all about mapping. Functions map input arguments to return values, meaning that for each set of inputs, there exists an output. A function will take the inputs and return the corresponding output.”
<a href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076bec976">“Mapping” — Eric Elliott</a></p>
</blockquote>
</blockquote>
<p>Since JS map returns “new data” instead of mutating existing data, we can
think of filter as being a safe function to use for immutability.</p>
<p>(For C++ related examples, recall Standard Library std::transform)</p>
<h3 id="map-example-double-all-numbers-transform-them">Map example: Double all numbers (transform them!)</h3>
<p><strong>Input: 1,2,3,4</strong>
<strong>Expected Output: 2,4,6,8</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const nums = [1,2,3,4]
const doubled = nums.map( (nums) => nums*2 )
doubled // [2, 4, 6, 8]
</code></pre></div></div>
<p>Again, we note ES6 arrow function syntax.</p>
<h3 id="reduce-and-transducers">Reduce and Transducers</h3>
<p>Reduce <strong>Iterates over a collection and returns an accumulated value.</strong></p>
<p>Transducers combine operations, hence skipping intermediary computational steps typically created by chaining JavaScript
methods together. <a href="https://gist.github.com/abstractmachines/06ac6e14ec8335c7873da3e5e8a9ecd8">Please see my Transducers Gist for more info</a>.</p>
<h2 id="object-set-map-iterators">Object, Set, Map Iterators</h2>
<h3 id="javascript-iterators-sets-and-maps">JavaScript Iterators: Sets and Maps</h3>
<p>In ES6 (and beyond) we tend to use Maps instead of Objects for iteration, because:</p>
<ul>
<li>the Object prototype chain can be problematic for iteration;</li>
<li>Maps are more performant;</li>
<li>Maps keys can be any data type; Object keys can only be a String or a Symbol.</li>
</ul>
<p><a href="https://gist.github.com/abstractmachines/ba21a7f296e6d1726a3a2e845834b2ec">Please see my Gist for more info</a>.</p>
<p>Before we go into Object iterators, let’s talk about how JS objects work.</p>
<ul>
<li>Enumerable Properties : does it have its own?</li>
<li>Iterator and Iterable Protocols</li>
</ul>
<h3 id="enumerable-properties-on-this-object-not-down-the-prototype-chain">Enumerable Properties: “On THIS object, not down the prototype chain”</h3>
<p>An Object has Enumerable properties when its properties are its own properties,
instead of just being properties that belong to another object somewhere in the Prototype Chain. Recall that we
covered the Prototype Chain in the <a href="http://blog.amandafalke.com/tutorials/2017/04/12/intro-to-modern-javascript-for-cpp-developers.html">first post of this series</a>.</p>
<p><strong>There are a lot of methods for Objects in JS on the MDN site. How can I intuitively tell the difference?</strong></p>
<p>To think simply about whether a method or context refers to the enumerability of an object, think about what it is.</p>
<p>If it’s <em>enumerable</em>, it <em>has its own stuff.</em></p>
<p>It makes sense now why <code class="language-plaintext highlighter-rouge">hasOwnProperty()</code> refers to whether an object’s property is an enumerable one.</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">See more on MDN</a>.</p>
<h3 id="objectentriesobj">Object.entries(obj)</h3>
<p>This method returns an array of object’s Own Enumerable Properties, in key value pairs.</p>
<h3 id="objectkeysobj">Object.keys(obj)</h3>
<p>This does the same thing, but only returns/operates on keys, not values/pairs.</p>
<p>Recall the Object keys can only be a String or a Symbol.</p>
<h3 id="objectvaluesobj">Object.values(obj)</h3>
<p>Same as above, only values instead of keys.</p>
<h3 id="for-in">for in</h3>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in"><code class="language-plaintext highlighter-rouge">for in</code></a> iterates over the enumerable properties of an Object. It <strong>returns unordered</strong> results. (If you want order, use a for loop or similar).</p>
<p><code class="language-plaintext highlighter-rouge">for in</code> is interesting because it enumerates over properties that are also in the Prototype Chain. MDN-recommended methods <code class="language-plaintext highlighter-rouge">.hasOwnProperty()</code> and <code class="language-plaintext highlighter-rouge">.propertyIsEnumerable()</code> can be used to. If you read the previous section, these should seem intuitive.</p>
<h2 id="subjects-i-will-cover-later-include">Subjects I will cover later include:</h2>
<ul>
<li>
<p>Isomorphic JS applications</p>
<p>Rendering JS on server, and hence being able to use same functions</p>
</li>
<li>
<p>Function Currying</p>
<p>In functional programming, functions aren’t “called”, they’re “applied.”
For partial application of functions – applying only one argument at a time.
Makes things more testable, easier to reason about…</p>
</li>
<li>
<p>Spread Operator, ES6 Destructuring, ES6 Shorthand</p>
</li>
<li>
<p>Functional programming : deterministic, predictable code</p>
</li>
<li>
<h5 id="immutability">Immutability</h5>
<blockquote>
<p>There are two ways to change data: update (mutate) existing data, or create a new/updated copy of the data.</p>
<blockquote>
<p>When we change existing data, side effects (bad things) can occur.</p>
</blockquote>
</blockquote>
</li>
<li>
<ul>
<li>Cover freeze() and clone() methods</li>
</ul>
</li>
<li>
<h6 id="pure-functions">Pure Functions</h6>
<p>In <a href="https://medium.com/@_ericelliott">Eric Elliot</a>’s functional programming tutorials on Medium, one of the first things he mentions in his <a href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076bec976">Pure Functions tutorial</a> is how objects
are passed into functions in JS <strong>by reference</strong> (and primitives are passed in by value).</p>
</li>
</ul>
<p>If we mutate that object inside of that function, it will mutate the original object <em>at its original memory location</em>.
That causes <strong>side effects</strong> which are unknown when we (“we” meaning, flow of execution control) are operating within
the context of the function that brings that object in as a parameter.</p>
<p>So long for now!</p>
<p>Amanda</p>
<p><span>Category: tutorials</span></p>JavaScript Tutorials for the C/C++ programmer, part 2 : IteratorsCookies with Node Express2017-04-14T13:01:23+00:002017-04-14T13:01:23+00:00http://amandafalke.com/tutorials/2017/04/14/cookies-with-node-express<h1 id="cookies-with-express--a-brief-overview-tutorial">Cookies with Express : A Brief Overview Tutorial</h1>
<p><a href="https://github.com/abstractmachines/cookies-with-node-express-tutorial">Github repo</a></p>
<p>Not covered in this tutorial: the details of cookies (expiration dates, etc). This is merely a succinct overview.</p>
<p>This tutorial was inspired by being asked by a mentee how cookies work, and by <a href="https://www.codementor.io/noddy/cookie-management-in-express-js-du107rmna">Codementor.io’s Noddy Pandey’s Cookie Management
with Express</a>
post. The elements that differ between my tutorial and the one linked above include:</p>
<ul>
<li>I use const, not var (see the <a href="http://blog.amandafalke.com/tutorials/2017/04/12/intro-to-modern-javascript-for-cpp-developers.html">JS for C/C++ developers tutorial</a> regarding why)</li>
<li>I use arrow functions for brevity</li>
<li>I’ll use verification - and show you how to verify whether your program works (or not)</li>
<li>I don’t like using global npm installations (I’ll explain why below)</li>
<li>I use nvm, Node Version Manager (reasoning below)</li>
</ul>
<p>Verification is done not
using extensive unit testing, but with basic tooling (curl HTTP, Node, Chrome).</p>
<p>I’m also going to include the step-by-step workflow of a typical JS developer
in this tutorial.</p>
<h2 id="installations">Installations</h2>
<h3 id="nvm-node-version-manager">nvm (Node Version Manager)</h3>
<p>It’s ideal to use <strong>nvm</strong>, or Node Version Manager, to install Node on different projects and manage versions.
If you don’t have nvm installed already and aren’t using, <a href="https://github.com/creationix/nvm">do that right away</a>.</p>
<p>Create an NVM ‘rc’, or <a href="https://en.wikipedia.org/wiki/Run_commands">Run Commands - see Kernigan and Ritchie</a>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ echo "6.9.2" > .nvmrc
</code></pre></div></div>
<p>This indicates that we are intending to use Node 6.9.2 for this project. To use that .rc file to run command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nvm use
</code></pre></div></div>
<p>Expected output:</p>
<blockquote>
<p>Found ‘/path/to/project/.nvmrc’ with version <6.9.2>
Now using node v6.9.2 (npm v3.10.9)</p>
</blockquote>
<h3 id="npm">npm</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm init
</code></pre></div></div>
<h3 id="express-middleware">Express middleware</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm install express --save
</code></pre></div></div>
<p>It’s important to not install npm packages globally, if we can help it.
Part of the npm’s appeal is the modularity and versioning for different
projects remain isolated; we pollute the global space, if you will, if we
install npm projects globally. Always opt for <code class="language-plaintext highlighter-rouge">npm install something --save</code>
or <code class="language-plaintext highlighter-rouge">--save-dev</code> rather than global installs of <code class="language-plaintext highlighter-rouge">npm install something</code>.</p>
<h3 id="cookie-parser-middleware">cookie-parser middleware</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ npm install cookie-parser --save
</code></pre></div></div>
<h2 id="testing">Testing</h2>
<h3 id="testing-node">Testing Node</h3>
<p>After you’ve written the code (see below), test it via curl HTTP. Specify plaintext type in content header.</p>
<ul>
<li>write code</li>
<li>restart node</li>
<li>hit it with curl</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ curl -X GET http://localhost:3000 -H "Content-Type: text/plain"
</code></pre></div></div>
<p>Expected Output:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>hello, worrrrllld!
</code></pre></div></div>
<hr />
<h3 id="testing-cookies-and-persistence">Testing cookies and persistence</h3>
<p><strong>Test that cookies are in persistent browser storage.</strong></p>
<p>Visit the route in browser for the get handler that sets the cookie,
view that cookie, change the cookie’s name, refresh everything, and
see if there are now TWO cookie names coming back from client’s request.</p>
<ul>
<li><strong>Expected Input:</strong> GET http://localhost:3000/cookie in Chrome</li>
</ul>
<p><strong>Expected Result:</strong> ‘cookie is set’</p>
<ul>
<li><strong>Expected Input:</strong> In Chrome console,
<code class="language-plaintext highlighter-rouge">document.cookie</code></li>
</ul>
<p><strong>Expected Result: (Chrome)</strong> “cookiename1=cookie_value”</p>
<ul>
<li><strong>Expected Input:</strong> Go back to JS and <strong>change value for cookie name</strong> to cookiename2,
restart node</li>
</ul>
<p>Repeat steps above (GET and document.cookie)</p>
<p><strong>Expected Result: (Chrome)</strong>
“cookiename1=cookie_value,cookiename2=cookie_value”</p>
<p>TEST PASSED, shows persistent storage on client.</p>
<hr />
<p><strong>Test that Node console working + Persistent Storage</strong></p>
<p><strong>Do the same thing you did in Test 2 with proving persistent storage, only
do it with Node instead of the browser.</strong></p>
<p>Write a console.log of cookies from client request in a get handler for any route,
visit that route, check Node console</p>
<ul>
<li>
<p>Add code: console.log(‘Cookies: ‘, req.cookies); to any get handler</p>
</li>
<li>
<p>Restart Node</p>
</li>
<li>
<p>Visit the route for that handler</p>
</li>
</ul>
<p><strong>Expected Result: (Node)</strong>
“cookiename3=cookie_value,cookiename4=cookie_value”</p>
<p>TEST PASSED, shows persistent storage on client.</p>
<h2 id="the-code">The code</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
// GET
app.get('/', (req,res) => {
res.send('hello, worrrrllld!');
});
// PORTS, SERVER
const server = app.listen(3000, () => {
const host = server.address().address;
const port = server.address().port;
});
// Run test 1 here before you write the following code
// COOKIES
const cookie_name = 'towersofhanoi';
app.get('/cookie', (req, res) => {
res.cookie(cookie_name , 'cookie_value').send('Cookie is set');
console.log('Cookies: ', req.cookies);
});
// Run tests 2 and 3 here
</code></pre></div></div>
<p><span>Category: tutorials</span></p>Cookies with Express : A Brief Overview TutorialIntroduction to modern JavaScript for C/C++ developers, part 12017-04-12T19:50:20+00:002017-04-12T19:50:20+00:00http://amandafalke.com/tutorials/2017/04/12/intro-to-modern-javascript-for-cpp-developers<h1 id="javascript-tutorials-for-the-cc-programmer-or-cs-grad-part-1">JavaScript Tutorials for the C/C++ programmer or CS Grad, Part 1</h1>
<p>This is a “bird’s eye” tutorial of JS which is very broad in scope. The purpose of
this document is to introduce C/C++ developers and/or CS grads to concepts in JavaScript.</p>
<p>As such, it is an overly long article, and should be used as as a reference for
basic information.</p>
<p>Not covered in this tutorial: Extensive Mozilla DOM API, JS libraries and frameworks, contextual implementation details.</p>
<p>This is the first tutorial in a series of similar tutorials I’ll be posting.</p>
<h1 id="sources">Sources</h1>
<p>This was written by me, with information gleaned from:</p>
<ol>
<li><a href="https://developer.mozilla.org/en-US/">Mozilla developer docs</a></li>
<li>Wikipedia</li>
<li><a href="https://en.wikipedia.org/wiki/Design_Patterns">Design Patterns by GoF</a></li>
<li>Stack Overflow</li>
<li><a href="http://www.2ality.com/">Dr Rauschmeyer’s JavaScript blog</a></li>
<li><a href="http://javascriptissexy.com/">JavaScript Is Sexy</a></li>
</ol>
<h1 id="table-of-contents">Table of Contents</h1>
<ul>
<li><a href="#typing">Typing</a></li>
<li><a href="#strict-mode">Strict Mode</a></li>
<li><a href="#objects-and-primitives">Objects and Primitives</a></li>
<li><a href="#on-js-inheritance-with-objects-and-the-prototype-chain">On JS Inheritance with Objects and the Prototype Chain</a></li>
<li><a href="#shallow-clone-and-deep-clone">Bitwise and Memberwise: Shallow Clone and Deep Clone</a></li>
<li><a href="#object-enumerable-properties">Object Enumerable Properties</a></li>
<li><a href="#object-iteration">Object Iteration</a></li>
<li><a href="#js-operators">JS Operators</a></li>
<li><a href="#js-functions">JS Functions</a></li>
<li><a href="#apply-call-and-bind">Apply Call And Bind</a></li>
<li><a href="#arrow-functions">ES6 Arrow Functions</a></li>
<li><a href="#const-let-var">Const, let, and var</a></li>
<li><a href="#es6-iterators-implicit-and-explicit">ES6 Iterators Implicit and Explicit</a></li>
<li><a href="#common-javascript-design-patterns">Common JavaScript Design Patterns</a></li>
</ul>
<h2 id="typing">Typing</h2>
<p>“Some languages, like Java and C++, have <strong>static typing</strong>.
Java is generally supposed to have <strong>strong (and static) typing.</strong>
C/C++ are statically typed languages with weak typing.”</p>
<p>… What’s this all mean?</p>
<p>Several computer science topics were just covered in the prior paragraph.
We’ll cover them briefly below.</p>
<p><em>Related Topics:</em></p>
<ul>
<li>Type Safety</li>
<li>Static Typing, Dynamic Typing</li>
<li>Type Checking (Strong and Weak)</li>
<li>Type Inference; Type Erasure</li>
<li>Type Conversions (any kind of type conversion),</li>
<li>Type Coercion</li>
<li>Implicit type conversions (little type safety),</li>
<li>Casting (explicit type conversions),</li>
<li>Compiled versus interpreted languages,</li>
<li>Other stuff.</li>
</ul>
<h3 id="type-safety">Type Safety</h3>
<p><strong>Type safety</strong> is the relative amount of type-related error prevention a
language has built in. The more type-related error prevention that a language
has, and/or the harder a language’s typing system is to subvert, means that the
typing system definition for that language will lean more towards the “strongly
typed” category; similarly, the easier a language’s typing system is to subvert,
the more that a language will lean towards the “weakly typed” category.</p>
<p><strong>Lots of type safety: Type conversions generally must be explicit</strong></p>
<p>Language tends do discourage and/or prevent type errors.</p>
<p><strong>Little type safety: Implicit conversions can happen fairly easily</strong></p>
<p>Language tends to implicitly allow type errors, often silently.</p>
<p><strong>What’s best? It depends.</strong></p>
<p>Not having type safety can be a feature. Consider “truthy” languages like JS
and other scripting languages.
See also: <a href="https://en.wikipedia.org/wiki/Duck_typing">Duck typing</a></p>
<p><strong>Related terminology:</strong></p>
<p><code class="language-plaintext highlighter-rouge">data type</code> … <code class="language-plaintext highlighter-rouge">size</code> … <code class="language-plaintext highlighter-rouge">offset</code></p>
<p><code class="language-plaintext highlighter-rouge">memory safety (RAM access problems including buffer overflows and dangling pointers)</code></p>
<h3 id="type-enforcement-static-or-dynamic-compile-time-check-or-runtime">Type enforcement: Static or Dynamic (compile time check or runtime)</h3>
<p><code class="language-plaintext highlighter-rouge">Static Type Enforcement:</code> at compile time</p>
<p><code class="language-plaintext highlighter-rouge">Dynamic Type Enforcement:</code> at run time</p>
<blockquote>
<p><strong>The term “memory-safe languages” does not include C/C++.</strong>
The use of reference counters, understanding of strong v. weak pointers,
C++11’s smart pointers, semaphores, reerence counting et al, are all tools
the modern C/C++programmer uses to prevent memory problems. This level of
consideration doesn’t even enter the mind of the programmer writing higher
level languages. Many higher level languages disallow pointer arithmetic and
casting to be accessed programatically, and hence those languages solve the
memory safety problem (sometimes at a performance cost particularly for RTOS).</p>
</blockquote>
<p><strong>The terms “memory-safe languages” “static typed language” and “dynamic typed
language” refers to the type enforcement that the language uses.</strong>
If a language’s type enforcement strategy is static, then it is called a
statically typed language. And so on and so forth.</p>
<p><strong>Static typed languages (Java, C, C++)</strong> determine type correctness at compile
time. Even if you don’t know this term already, you should be able to intuit its
meaning as a software engineer, namely due to the use of the term <strong>static.</strong>
Recall that <strong>static</strong> means <strong>at compile time</strong> and <strong>dynamic</strong> means
<strong>at runtime.</strong></p>
<p><strong>Dynamically typed languages (Ruby, Python, PHP)</strong> determine type correctness
at runtime, or execution time. As C programmers, we’ve heard runtime typing
referred to as “late” or “latent typing”, and many proponents of statically
typed languages state that to check for types so late is expensive. There are
many arguments against and for, but the purpose of this document is a tutorial,
not a nerd battle (fun as they can be).</p>
<p><strong>Strongly typed vs. weakly typed</strong></p>
<p><strong>If a type system is easy to subvert,</strong> then the language is considered
<strong>weakly typed</strong>.</p>
<p>If a <strong>variable remains a specific type unless explicitly reassigned to another
type, then the language is considered **strongly typed.</strong></p>
<p>Think about <strong>implicit type conversions in C/C++.</strong> Doesn’t that mean that the
type system is hence easy to subvert? Clearly. Therefore, C and C++ can be
considered weakly typed languages.</p>
<p>Think about <strong>casting in C/C++.</strong></p>
<p>In C/C++, any type can literally become another type. Void pointers…implicit
type conversions… <strong>“C/C++ is therefore weakly typed because its typing system
is easy to subvert.”</strong></p>
<p>In languages such as Java and C#, there are <strong>no/fewer implicit conversions</strong>
of types, because <strong>you have to explicitly convert types.</strong> These languages are
therefore known as <strong>strongly typed, because the type system is more difficult
to subvert, and the programmer must generally explicitly do so.</strong></p>
<p>The terms <strong>“strongly typed” (Java, Python)</strong> and “weakly typed” can refer to
either statically typed languages or dynamically typed languages, and seem
controversial/debatable.</p>
<p>Strongly typed seems to mean <strong>“variables must be declared before use.”</strong><br />
It could also mean <strong>“there are rules about types in this language, and those
rules are hard to break.”</strong> There must be a predetermined memory
offset/allocation for each data type built in as a primitive or used-defined
types.</p>
<blockquote>
<p>JavaScript is untyped; JavaScript is PROTO-typed.</p>
</blockquote>
<blockquote>
<p>“academic types use “untyped” to mean “no static types”.
they are smart enough to see that values have types (duh!). context matters.”
-Brendan Eich
https://twitter.com/brendaneich/status/166310376340848643</p>
</blockquote>
<p><strong>“Untyped languages”</strong> can also be used to refer to <strong>“dynamically typed
languages”</strong>, and that is often the case in the CS world:</p>
<p>http://stackoverflow.com/questions/9154388/does-untyped-also-mean-dynamically-typed-in-the-academic-cs-world</p>
<h2 id="strict-mode">Strict Mode</h2>
<blockquote>
<p>Strict Mode: less “undefined”, more checking</p>
</blockquote>
<p>JavaScript semantics, as we know them, often involve a silent or implicit
undefined value getting by us. This, as you may imagine, can be problematic.</p>
<p>Strict mode is a solution for these problematic semantics. Strict mode converts
that silent error into an explicit throw error.</p>
<p>Strict mode does more “checking”. Strict mode code can also be faster.</p>
<p>Strict mode <code class="language-plaintext highlighter-rouge">function calls</code> are different, too. In JS semantics as we know them,
function calls have a <code class="language-plaintext highlighter-rouge">this</code> value of the <code class="language-plaintext highlighter-rouge">global object</code> by default. In strict
mode, <code class="language-plaintext highlighter-rouge">it is undefined!!!!</code></p>
<h1 id="objects-and-primitives">Objects and Primitives</h1>
<h2 id="javascript-primitives-values">JavaScript Primitives (values)</h2>
<p>Anything that’s a primitive type such as boolean, number, string, null,
undefined, and in ES6, Symbol.</p>
<p>These primitives have “wrappers” that translate values to primitive types.
Those wrappers are called Boolean, String, Number, and in ES6, Symbol.</p>
<h2 id="anything-that-isnt-a-primitive-is-considered-an-object">Anything that isn’t a Primitive is considered an Object.</h2>
<h2 id="primitives-are-passed-by-value-objects-passed-by-implicit-reference-kinda">Primitives Are Passed by Value, Objects passed By Implicit Reference (kinda):</h2>
<p>Primitives (data types) are passed by value into functions, but any soft of
Object is passed by “reference,” implicitly. Passing an Object (a non primitive
inherent to JS which inherits from Number, Function, Object etc, or a
user-created Object) results in changes available outside the function’s scope.</p>
<h2 id="values">Values:</h2>
<ol>
<li>Immutable</li>
<li>Evaluated by value (equality/comparison operators <code class="language-plaintext highlighter-rouge">===</code>)</li>
</ol>
<h2 id="objects">Objects:</h2>
<ol>
<li>Mutable by default</li>
<li>Evaluated by reference (equality/comparison operators <code class="language-plaintext highlighter-rouge">===</code>)</li>
<li>Since JavaScript has Prototype Inheritance, and the Prototype Chain, the
only construct existing in JS “inheritance” is the Object and Prototype Chain</li>
<li>Have methods such as <code class="language-plaintext highlighter-rouge">isEnumerable</code> and <code class="language-plaintext highlighter-rouge">hasOwnPrototype</code> to peek at either object itself or objects in Prototype Chain</li>
<li>Passed into functions by reference, causing unwanted side effects (more on this later)</li>
</ol>
<p><strong>What is an Object?</strong>
Anything that doesn’t use the built-in primitives. JavaScript is fairly object-centric; its inheritance model is
based upon Object Prototypes.</p>
<ul>
<li>Object keys can only be a String or a Symbol (more on Symbols later)</li>
<li>Copying objects (cloning) is pretty weird</li>
</ul>
<h2 id="on-js-inheritance-with-objects-and-the-prototype-chain">On JS Inheritance with Objects and the Prototype Chain</h2>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">From Mozilla docs</a></p>
<p>JavaScript Inheritance doesn’t work like C/C++/Java does because those are
(usually) OOP-based languages. JavaScript inheritance is based only on
Objects, and the Prototype Chain.</p>
<ul>
<li>
<p>Each Object has an internal “link” to its Prototype. Its Prototype also has
its own Prototype (“the prototype of the prototype”), and so on, continuing.</p>
</li>
<li>
<p>When access to an Object’s property is requested, the accessor will look at
the Object’s properties as well as traverse the internal link to the Object’s
Prototype, to look for a match. If the match isn’t found, the accessor will
then traverse the internal link of the Object’s Prototype TO the Object’s
Prototype’s Prototype. This continues until a match is found OR end of chain.</p>
</li>
<li>
<p>Sound performance intensive? That’s because it is. Further, each time an
object’s properties are iterated over, each property is itself enumerated. This
is a very expensive operation. The method <code class="language-plaintext highlighter-rouge">hasOwnProperty</code> is, according to
Mozilla, the only method to avoid traversal of the prototype chain.</p>
</li>
</ul>
<p>https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain</p>
<h2 id="shallow-clone-and-deep-clone">Shallow Clone and Deep Clone</h2>
<h4 id="shallowbitwise-copy">Shallow/Bitwise Copy</h4>
<p>Recall that bitwise copy in C/C++ uses functions like <code class="language-plaintext highlighter-rouge">memcpy</code>, which don’t invoke the copy
constructor. Failing to invoke constructors can involve some bugs later on in the code.</p>
<p><em>Bitwise copy is an implementation of shallow copy. Shallow copy just means copying data.</em></p>
<h4 id="deepmemberwise-copy">Deep/Memberwise Copy</h4>
<p>Recall that memberwise copy in C/C++ often involves the Rule of Three, including constructors and
the use of copy constructors in order to copy all of the data over. Slow but reliable.</p>
<p><em>Memberwise copy is an implementation of deep copy. Shallow copy just means copying data and pointers.</em></p>
<p><code class="language-plaintext highlighter-rouge">Object.assign()</code> is used a lot to copy objects. Before we really can discuss copying or cloning of objects, we should first understand Deep Cloning and Shallow Cloning. It’s notable that Object.assign does a shallow clone <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign">see MDN’s Deep Clone warning here</a></p>
<p><img src="https://raw.githubusercontent.com/abstractmachines/abstractmachines.github.io/master/_posts/js-object-cloning.png" alt="Deep Clone and Shallow Clone graphic" />
<em>Image added in 2018 for clarity</em></p>
<p>How do we practically deep cloning? WE can use custom code… we can use for in loops with that custom code…
we can use lodash’s deepClone functionality, which is slow but commonly found in industry.</p>
<h3 id="object-enumerable-properties">Object Enumerable Properties</h3>
<blockquote>
<p>Enumerable Properties: “On THIS object, not down the prototype chain”</p>
</blockquote>
<p>An Object has Enumerable properties when its properties are its own properties,
instead of just being properties that belong to another object somewhere in the Prototype Chain.</p>
<p><strong>There are a lot of methods for Objects in JS on the MDN site. How can I intuitively tell the difference?</strong></p>
<p>To think simply about whether a method or context refers to the enumerability of an object, think about what it is.</p>
<p>If it’s <em>enumerable</em>, it <em>has its own stuff.</em></p>
<p>It makes sense now why <code class="language-plaintext highlighter-rouge">hasOwnProperty()</code> refers to whether an object’s property is an enumerable one.</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">See more on MDN</a>.</p>
<h2 id="object-iteration">Object iteration</h2>
<blockquote>
<p>Note: Iteration over JS objects can be a bit weird. We generally use another data structure such as Maps, for iteration.</p>
</blockquote>
<h4 id="objectentriesobj">Object.entries(obj)</h4>
<p>This method returns an array of object’s Own Enumerable Properties, in key value pairs.</p>
<h4 id="objectkeysobj">Object.keys(obj)</h4>
<p>This does the same thing, but only returns/operates on keys, not values/pairs.</p>
<p>Recall the Object keys can only be a String or a Symbol.</p>
<h4 id="objectvaluesobj">Object.values(obj)</h4>
<p>Same as above, only values instead of keys.</p>
<h4 id="for-in">for in</h4>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in"><code class="language-plaintext highlighter-rouge">for in</code></a> iterates over the enumerable properties of an Object. It <strong>returns unordered</strong> results. (If you want order, use a for loop or similar).</p>
<p><code class="language-plaintext highlighter-rouge">for in</code> is interesting because it enumerates over properties that are also in the Prototype Chain. MDN-recommended methods <code class="language-plaintext highlighter-rouge">.hasOwnProperty()</code> and <code class="language-plaintext highlighter-rouge">.propertyIsEnumerable()</code> can be used to. If you read the previous section, these should seem intuitive.</p>
<h2 id="js-operators">JS Operators</h2>
<p>Operators in JavaScript are pretty similar to C/C++. Remember that boolean
is a primitive type and that Boolean is a class wrapping that type with
functions you can inherit by using the new keyword and the Boolean data type.
View this is a analogy to inheritance - although it’s important to remember
that JavaScript is prototype-based, not class-based (the <code class="language-plaintext highlighter-rouge">class keyword</code>
introduced in ES2015 is just syntactic sugar (see the Prototype Chain, below).</p>
<p><strong><code class="language-plaintext highlighter-rouge">=></code></strong></p>
<p>One interesting operator in JavaScript is the operator or <code class="language-plaintext highlighter-rouge">token</code> <code class="language-plaintext highlighter-rouge">=></code> used
in <code class="language-plaintext highlighter-rouge">ES6 Arrow Functions.</code> It serves as “fat syntax” for brevity.</p>
<p>The triple equals operator <code class="language-plaintext highlighter-rouge">===</code> in JavaScript, as mentioned directly above,
compares primitives by value, and objects by reference. We’ve seen this
operator used for type checking, but in JavaScript there is some additional
behavior, from object reference comparisons to implicit type conversions.</p>
<blockquote>
<p>“In JavaScript objects are a reference type. Two distinct objects are never
equal, even if they have the same properties. Only comparing the same object
reference with itself yields true.” - Mozilla
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Comparing_Objects
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators?v=test</p>
</blockquote>
<h2 id="js-functions">JS Functions</h2>
<h3 id="javascript-functions-are-first-class-objects">JavaScript functions are first class objects</h3>
<p>• <strong>Can be passed an argument</strong>
This means that a function can be passed as a function <strong>argument,</strong> and
then be executed later. It can even be returned, to be executed later.</p>
<p>This is one of the fundamental elements of functional programming:</p>
<blockquote>
<blockquote>
<p><strong>Functional programming:</strong></p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<blockquote>
<p><strong>functions as arguments.</strong></p>
</blockquote>
</blockquote>
</blockquote>
<p>Note how functions as arguments utilizes the <strong>Inversion of Control</strong> Pattern. More on IoC later.</p>
<p>• <strong>Can be assigned to a variable</strong></p>
<p>• <strong>Can be returned as a value</strong></p>
<p>Hence, all JavaScript functions can be <code class="language-plaintext highlighter-rouge">passed around</code> in this way.</p>
<p>JavaScript functions <strong>return <code class="language-plaintext highlighter-rouge">undefined</code></strong> by default. So do variables that
are referenced without being defined first. (Unless you’re using strict mode.)</p>
<p>For constructors called with the <code class="language-plaintext highlighter-rouge">new</code> keyword, the default return type is the
<em>VALUE</em> of the <code class="language-plaintext highlighter-rouge">this</code> parameter. If a function is not a constructor function,
default return value is undefined.</p>
<h3 id="javascript-functions-and-return-values">JavaScript Functions and Return Values</h3>
<p>JavaScript functions return <code class="language-plaintext highlighter-rouge">undefined</code> by default, unless the function has a
return value. This is very intuitive.</p>
<p>Use of constructors with the <code class="language-plaintext highlighter-rouge">new</code> keyword: the default return type is the
<em>VALUE</em> of the <code class="language-plaintext highlighter-rouge">this</code> parameter. If a function is not a constructor function,
default return value is undefined (or return value is specified return value).
This is also very intuitive.</p>
<h3 id="primitives-passed-by-value-objects-by-implicit-reference">Primitives Passed By Value, Objects By Implicit Reference</h3>
<p>Primitives (data types) are passed by value into functions, but any soft of Object is passed by “reference,” implicitly. Passing an Object (a non primitive inherent to JS which inherits from Number, Function, Object etc, or a user-created Object) results in changes available outside the function’s scope.</p>
<h3 id="callbacks">Callbacks</h3>
<blockquote>
<p>What are callbacks or “higher order functions”?</p>
</blockquote>
<p>Callbacks are derived from functional programming. Callbacks are closures; a function within a function. Let’s play with code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function a(){
function b(){
console.log('b');
}
console.log('a');
b();
}
var c = a();
c;
console.log('c');
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">a b c</code></p>
<p>if we add <code class="language-plaintext highlighter-rouge">return b()</code> in a(), same results.</p>
<p>There’s a lot more to say about callbacks, but we’ll move on for now.</p>
<h3 id="javascript-function-scope">JavaScript function scope</h3>
<blockquote>
<p>Static scope: Lexical Scope or “Closure”</p>
</blockquote>
<p>In order to discuss “closures”, we first discuss “Lexical Scope.”</p>
<p><strong>What’s “lexical” mean?</strong></p>
<blockquote>
<p>“Lexical”: relating to the words or vocabulary of a language.”</p>
</blockquote>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<p>So <strong>lexical</strong> just means “words, <strong>wordy stuff</strong> and stuff about words.”</p>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
<p><strong>The term “lexical analysis”</strong>, in computer science, refers to the process of
converting characters, into <strong>meaningful tokens</strong> which can be used by a language
for specific purposes. <strong>Tokenizers, lexers are tools</strong> which perform these
actions. Together, lexers and parsers analyze a language’s syntax. A parser just takes in input and outputs a data structure and structured, hierarchical representation of the output (thanks Wikipedia!) https://en.wikipedia.org/wiki/Parsing#Computer_languages</p>
<p>There are a few terms in computer science / software that refer to scoping using the term “lexical.”</p>
<blockquote>
<blockquote>
<blockquote>
<p><strong>Static scoping == lexical scoping</strong></p>
</blockquote>
</blockquote>
</blockquote>
<p>Lexical scoping just means static or block scoping. “Statically scoped” means that a block defines a new scope. C is lexically scoped, with variables being allowed static, automatic, or manual lifetime.</p>
<blockquote>
<blockquote>
<blockquote>
<p><strong>Dynamic scoping</strong></p>
</blockquote>
</blockquote>
</blockquote>
<p>With dynamic scoping, we look locally for a variable’s definition. If not found, we look <strong>up the calling stack.</strong></p>
<p><strong>JavaScript has lexical scoping, and the global scope is the outer scope.</strong> <code class="language-plaintext highlighter-rouge">let</code> and <code class="language-plaintext highlighter-rouge">const</code> ES6 features allow for block scoping.</p>
<blockquote>
<p>Most languages with C curly brace syntax are block scoped. JavaScript is not one of them.</p>
</blockquote>
<p>JavaScript uses the same <code class="language-plaintext highlighter-rouge">{ block operators }</code> as C-syntax languages, but
JavaScript is weird, and so it uses function scope, not block scope. This is
unless we use ES6 or other techniques to block scope variables.</p>
<blockquote>
<p>Function scoping: This is how hoisting and closures are possible.</p>
</blockquote>
<blockquote>
<p><strong>“The phrase scope bubbles up” means:</strong> “When JavaScript tries to resolve an
identifier, it looks in the local function scope. If this identifier is not
found, it looks in the outer function that declared the local one, and so on
along the scope chain until it reaches the global scope where global variables
reside. If it is still not found, JavaScript will raise a ReferenceError exception.”
(Wikipedia)</p>
</blockquote>
<h3 id="closures-and-scope">Closures and scope</h3>
<p>Accessing a variable outside of its immediate/local block scope is one way to describe a <strong>closure</strong>; a closure is usually expressed as an inner function and an outer function. Mozilla Development Network(MDN) gives a great definition:
“A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created.” https://developer.mozilla.org/en-US/docs/Web/JavaScript</p>
<p><strong>Inner functions have access to a wrapper function’s variables.</strong>
This is made possible by function scoped variables instead of block scoped variables.</p>
<p>See 2ality.com, Axel Rauschmeyer’s blog, for more info on closures and hoisting.</p>
<p>Axel says “Closures don’t get snapshots of a certain point in time, they get “live” variables.” This can lead to <strong>inadvertent sharing of variables via closures.</strong></p>
<p>You can resolve this inadvertent sharing using an IIFE (Immediately Invoked Function Expression). <strong>IIEFs restrict a variable’s scope to current block.</strong></p>
<p><strong>IIEF’s have some drawbacks, as they can make code a lot less testable.</strong> In general, it’s <strong>often better to just name things</strong> rather than have anonymous stuff executing in your runtime.</p>
<h3 id="when-are-closures-interesting">When are closures interesting?</h3>
<p>It really seems like the concept of a closure - meaning, a function within a
function in a function-scoped language instead of a block-scoped language, is
a pretty simplistic and boring idea, and that’s because it is. The topic that
makes closures interesting as asychronicity; the inner function can outlive the
outer function.</p>
<h3 id="hoisting-event-bubbling-delegation">Hoisting, Event Bubbling, Delegation</h3>
<p>This means that variable declarations “bubble in scope” to the containing element.
Function scoped variables allows those variables to be assigned anywhere in
the container, including in nested / “child” functions.</p>
<p>Hoisting doesn’t make a variable “global”, rather, it makes the variable
available “file-wide”.</p>
<blockquote>
<p>“Thus a <code class="language-plaintext highlighter-rouge">var x = 1 statement</code> in the middle of the function is equivalent to
a <code class="language-plaintext highlighter-rouge">var x declaration statement at the top</code> of the function, <code class="language-plaintext highlighter-rouge">and an x = 1
assignment statement at that point in the middle of the function</code> –
<strong>only the declaration is hoisted, not the assignment.</strong>”
-Wikipedia on JavaScript</p>
</blockquote>
<h3 id="event-bubbling-capturing-and-delegation">Event Bubbling, Capturing, and Delegation</h3>
<p>In JavaScript, scope bubbles up. This means that event listeners can be
written with more succinct handlers on the parent or ancestor elements in
the DOM, rather than on each child. Less code! Here’s an example:</p>
<blockquote>
<p>Use Case: ul items all need click event handling. New items will be added by user.</p>
</blockquote>
<p>Option A: Write handler for each li item:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ul
li -> listener handled by click event listener/handler on li[0]
li -> listener handled by ANOTHER click event listener/handler on li[1]
li -> listener handled by YET ANOTHER click event listener/handler on li[2]
/ul
</code></pre></div></div>
<ul>
<li>lots of code, lots of browser memory</li>
<li>dynamic user-added DOM elements not included / would require even more code</li>
</ul>
<p>Option B: Write a single handler for well-chosen ancestor:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ul -> listener handles click events
li -> click event bubbles up to ancestor, is handled there. No code here.
li -> " "
li -> " "
/ul
</code></pre></div></div>
<p><strong>Choose Option B.</strong></p>
<ul>
<li>Less code, less browser memory</li>
<li>Handles any new li item user adds via JS event bubbling model</li>
<li>Best practices: try to choose an Element which is unlikely to be removed
from the DOM; try to choose an element with spatial proximity for performance.</li>
<li><strong>Event object, event.target, and Mozilla Event API’s:</strong>
Use event capturing/Mozilla API for Event.target.tagName name matching to
ensure desired child selector is the only node selected in DOM tree.
Another option is to use optional args for addEventListener().
Event Object is 1st argument of the event handler callback function:</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const aParentDiv = document.getElementById('aContainer');
aContainer.addEventListener('click', (event) => {
if(event.target.tagName = 'LI')
{
event.target.textContent = 'new text to add to this li.';
}
});
</code></pre></div></div>
<p>See <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener">MDN API</a>
for more information on Event Object and listeners, with
<code class="language-plaintext highlighter-rouge">useCapture</code>:
<code class="language-plaintext highlighter-rouge">EventTarget.addEventListener('event-type', callback, true)</code></p>
<blockquote>
<p>Use Case: Removing/appending an li element child node without already having a reference to its parent. Use a button to remove the element.</p>
</blockquote>
<ul>
<li>Traverse the DOM to find element’s parent node</li>
<li>Use .parentNode API</li>
<li>Set up a “little DOM tree”</li>
</ul>
<p>Sample code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>aParentDiv.addEventListener('click', (event) => {
if (event.target.tagName == 'BUTTON') {
let li = event.target.parentNode;
let ul = li.parentNode;
ul.removeChild(li);
}
});
</code></pre></div></div>
<p>Corresponding HTML layout:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>aParentDiv
ul
li
button
/li
/ul
/aParentDiv
</code></pre></div></div>
<p>Note: <strong>spatial locality</strong> can become an issue with DOM bubbling, so you may
need to select a parent element closer to the li > button. If you have issues
with the other button elements on the page deleting things they aren’t supposed
to after using this code, consider specifying the parent div rather than document:</p>
<p><code class="language-plaintext highlighter-rouge">const listUl = aParentDiv.querySelector('ul')</code>;</p>
<p>… and then add the event listener to listUl instead of aParentDiv.</p>
<p>See also:</p>
<ul>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore">Node.insertBefore(newNode, referenceNode)</a></p>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/NonDocumentTypeChildNode/previousElementSibling">Node.previousElementSibling</a></p>
</li>
</ul>
<h3 id="function-statements-and-function-expressions">Function Statements and Function Expressions</h3>
<p>Overall the difference is often not well explained in most tutorials you find
online. One of the differences, according to Rauschmeyer, is that expressions
produce a value, and statements take an action. So <code class="language-plaintext highlighter-rouge">statements</code> are things like
if statements, loops, and <code class="language-plaintext highlighter-rouge">"action oriented"</code> control structures, and
<code class="language-plaintext highlighter-rouge">expressions</code> are <code class="language-plaintext highlighter-rouge">value-producing</code> code such as <strong><code class="language-plaintext highlighter-rouge">a+b</code>.</strong></p>
<p>Whenever an identifier is NOT present, we know that we are dealing with a
function expression. However, if an identifier IS present, there are several
things that helps us identify between expressions and declarations.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function apple()
{
var size = "medium";
alert("Eat a " + size + " apple, fool");
return "eaten";
}
var fruit = apple();
fruit();
</code></pre></div></div>
<p>Result: <code class="language-plaintext highlighter-rouge">Performs alert</code> then <code class="language-plaintext highlighter-rouge">returns undefined.</code></p>
<h3 id="function-expressions">Function Expressions</h3>
<p>In the above functions, you have the function invocation apple(). That function
invocation is an expression of a function invocation.</p>
<p><strong>These are expressions. Expressions don’t “return.” They “evaluate to.”</strong></p>
<h2 id="cc-tends-to-use-statements-not-expressions">C/C++ tends to use statements, not expressions</h2>
<p><code class="language-plaintext highlighter-rouge">var foo = 1;</code></p>
<p>So this code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function apple()
{
var size = "medium";
alert("Eat a " + size + " apple, fool");
return "eaten";
}
</code></pre></div></div>
<p>This is just a function declaration/definition, nothing got called…</p>
<p>Calling <code class="language-plaintext highlighter-rouge">apple()</code> will invoke a function, via an expression, that evaluates
to <code class="language-plaintext highlighter-rouge">eaten.</code></p>
<p>You could also go:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var newEval = apple();
newEval; // evaluates to `eaten`
</code></pre></div></div>
<p>but use <code class="language-plaintext highlighter-rouge">newEval;</code> NOT <code class="language-plaintext highlighter-rouge">newEval();</code> because newEval isn’t something that needs
to be invoked. It’s just something that holds the evaluated value computed from
running <code class="language-plaintext highlighter-rouge">apple()</code> expression.</p>
<blockquote>
<p><strong>Difference #1: Named or anonymous?</strong></p>
</blockquote>
<p>“Function declarations” a.k.a. “function definitions” a.k.a. “function
statements” have an “identifier.” This means that the function is named.</p>
<blockquote>
<p>Difference #1: “Function expressions” can be anonymous. Function declarations
cannot. So the moment we see an anonymous function, we know that that’s a
function expression.</p>
</blockquote>
<blockquote>
<p>One of the primary reasons for having named function expressions is for debugging.</p>
</blockquote>
<blockquote>
<p>Function Declaration:</p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> function radFunk()
{
// do rad stuff
}
</code></pre></div></div>
<blockquote>
<p>Function Expression:</p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> var x = function ()
{
// do rad stuff
};
</code></pre></div></div>
<blockquote>
<p>Function Expression:</p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> var x = function yaGottaName()
{
// do rad stuff
};
</code></pre></div></div>
<p>Issue: The ins and outs of expressions
http://www.2ality.com/2012/09/expressions-vs-statements.html</p>
<p>Expressions create a value. Expressions can be function arguments, and can
replace a statement. This is called an <code class="language-plaintext highlighter-rouge">expression statement.</code> The reverse
doesn’t hold; a statement can’t be used in replacement of an expression.
Think of an if statement, versus a ternary conditional expression.</p>
<blockquote>
<p>statement: if a, then b. Else, c:</p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> if (a)
{
a = b;
}
else
{
a = c;
}
</code></pre></div></div>
<blockquote>
<p>expression: if a, then b. Else, c:</p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> var evaluation = a ? b : c;
</code></pre></div></div>
<blockquote>
<p>Another reason for giving a function expression its own name is for recursion,
so that that function may be called from within its own body.</p>
</blockquote>
<blockquote>
<p><strong>Difference #2: function expressions are inside of () grouping operators:</strong></p>
</blockquote>
<blockquote>
<p>Difference #2:<br />
Function expressions are inside of (grouping operators), such as <code class="language-plaintext highlighter-rouge">(function(){})</code></p>
</blockquote>
<blockquote>
<p><strong>Difference #3: Function declarations are often inside of function bodies.</strong></p>
</blockquote>
<blockquote>
<p><strong>Difference #4: Context</strong></p>
</blockquote>
<blockquote>
<p>In JavaScript, context really matters. Check out the <strong>apply, call, and bind</strong>
methods covered herein for more information.</p>
</blockquote>
<blockquote>
<p>Final note: Function invocation via variable assignment is also called a Function Expression.</p>
</blockquote>
<h3 id="function-constructors">Function constructors</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>new Function( arg1, arg2, functionBody )
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var adder = new Function('a', 'b', 'return a+ b');
</code></pre></div></div>
<h2 id="apply-call-and-bind">Apply Call And Bind</h2>
<p>This section is generally written from my own perspective, with some information gleaned directly from the <a href="http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/">JavaScript is Sexy article on the “this” keyword in JS.</a>, as well as other aforementioned sources.</p>
<h3 id="the-problem-the-this-keyword-in-js">The problem: the “this” keyword in JS</h3>
<p>The <em>this</em> keyword is something C/C++ programmers are used to seeing (except in ‘static’ contexts).</p>
<blockquote>
<p>“This” in JavaScript depends completely in the context of the invocation. JavaScript is “function scoped”, so “this” bubbles up.</p>
</blockquote>
<p>Another way to say that is:</p>
<blockquote>
<p>In JS, this/context is defined by when/where the function is called, i.e. the
context of that invocation. In C++, Java, Ruby, and other languages, this/self
will always point to the object in which the method is defined. Not so with JS!</p>
</blockquote>
<p>And THAT, creates a lot of problems.</p>
<p>Recall closures and “lexical scope” or “static scope”.
In closures, the <code class="language-plaintext highlighter-rouge">this</code> reference “bubbles up.”</p>
<p>Each scope just binds a different value of <code class="language-plaintext highlighter-rouge">this.</code> Since JavaScript is function
scoped, the <code class="language-plaintext highlighter-rouge">this</code> reference bubbles up to the global object. This means that
by default, <code class="language-plaintext highlighter-rouge">this</code> refers to the global object / <code class="language-plaintext highlighter-rouge">namespace</code> / window! That is
when the browser is concerned, of course. In Node, that global object may be
different.</p>
<p>In Chrome dev tools browser console:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>> this
Window {speechSynthesis: SpeechSynthesis, caches: CacheStorage, localStorage:
Storage, sessionStorage: Storage, webkitStorageInfo: DeprecatedStorageInfo…}
</code></pre></div></div>
<p>In JavaScript, just as in other languages, objects have a <strong>this keyword</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var animal = {
species: "kitteh",
age: 1,
ageGetter: function() { return this.age }
}
animal.age; // 1
animal.ageGetter(); // 1
</code></pre></div></div>
<p><strong>So how to solve THIS problem?</strong></p>
<p>• <strong>ES3:</strong> Use <code class="language-plaintext highlighter-rouge">"that"</code> variable to copy this.property value over inside of function body. Then refern to “that.property” instead of “this.property”.</p>
<p>• <strong>‘Modern JS’:</strong> Use <code class="language-plaintext highlighter-rouge">apply, call, and bind</code> to resolve the context of this, for borrowed functions, nested functions, and any context where a function is applied in a context in which it was not defined</p>
<p>• <strong>ES6</strong>: Use <code class="language-plaintext highlighter-rouge">arrow functions</code></p>
<h3 id="bind-assigning-a-different-this-object-when-in-an-undesired-context">Bind(): assigning a different “this” object when in an undesired context.</h3>
<p>https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind</p>
<blockquote>
<p>Return value: A new, bound function with the specified “this” value.</p>
</blockquote>
<blockquote>
<p>Call and apply are some of the most common functions in JavaScript. Mozilla
says that “while bind() does a [[ construct ]], apply() and call() do a [[ call ]].”
That’s why we are grouping call and apply together below, and bind separately
here; the nature of the return value.</p>
</blockquote>
<p>The bind() method creates a new bound function.
When that function is invoked, that function has its <code class="language-plaintext highlighter-rouge">this</code> keyword set to the
provided value.
That “provided value” essentially means “a contextual this” (my definition).</p>
<p><strong>Traditional uses for bind include</strong>:
• Set the “this” value on methods</p>
<p>• When calling a function from another function in a situation where you need to resolve context of this keyword</p>
<p>• Function currying by presetting parameters</p>
<p>• Borrowing methods</p>
<p>• Bind() is usually used when calling one function from another function, and
ensuring that the proper context (like scope) is used for the intent of the
function.</p>
<p>• While bind can technically be used to borrow methods, that is usually
left to call() and apply().</p>
<p><strong>Bind() Example 1: Vanilla JS</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.x = 1 // 1
someObj = {
x: 2,
getX: function(){return this.x}
}
someObj.getX() // 2
</code></pre></div></div>
<p>What about if I create a variable within the global context, though?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const globalX = someObj.getX
globalX() // 1
</code></pre></div></div>
<p>Whoops, we are getting 1, instead of 2. That’s because we are currently within
the <code class="language-plaintext highlighter-rouge">global context.</code></p>
<p>So, <strong>we need to bind it to the right context.</strong></p>
<p><strong>Solution: bind() this to proper context:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const globalXNow = globalX.bind(someObj)
globalXNow() // 2
</code></pre></div></div>
<p>or, for brevity:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>this.x = 1 // 1
someObj = {
x: 2,
getX: function(){return this.x}
}
const amod = someObj.getX.bind(someObj)
amod() // 3
</code></pre></div></div>
<p>Now we’ve bound that variable to the proper object context. You can clearly see
that in this way, functions can be shared as according to different contexts.
All you’d need to do to share a function between objects or contexts would be
to bind it to the context we want. Above, we could bind the context as either
global or ‘someObj.’ Pretty cool stuff - and it also illustrates why this
language is so confusing at times. Let’s do another example.</p>
<p><strong>Bind() example 2: jQuery</strong></p>
<p>The JavaScriptIsSexy blog notes the following code.</p>
<p>We have a simple object with a clickHandler method that we want to use when a
button on the page is clicked</p>
<p>(ps, note how <code class="language-plaintext highlighter-rouge">var</code> is used below. Well, don’t use <code class="language-plaintext highlighter-rouge">var.</code> Use const or let!)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var user = {
data:[
{name:"T. Woods", age:37},
{name:"P. Mickelson", age:43}
],
clickHandler:function (event) {
var randomNum = ((Math.random () * 2 | 0) + 1) - 1;
console.log (this.data[randomNum].name + " " + this.data[randomNum].age);
}
}
```
</code></pre></div></div>
<p>The button is wrapped inside a jQuery $ wrapper, so it is now a jQuery object,
And the output will be undefined because there is no data property on the button object</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ("button").click (user.clickHandler);
Cannot read property '0' of undefined
</code></pre></div></div>
<p><strong>Solution: bind() this to proper context</strong></p>
<blockquote>
<p>“Since we really want this.data to refer to the data property on the user
object, we can use the Bind (), Apply (), or Call () method to specifically
set the value of this.” - JavaScript is Sexy</p>
</blockquote>
<p>Change:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ("button").click (user.clickHandler);
</code></pre></div></div>
<p>To:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ("button").click (user.clickHandler.bind(user));
</code></pre></div></div>
<p>Understanding a bit more about JavaScript is always good. jQuery is easy to use
without understanding it completely; hopefully this clears up a lot of jQuery
you may see around!</p>
<h3 id="call-and-apply">Call() and apply()</h3>
<blockquote>
<p>Call and apply are some of the most common functions in JavaScript. Mozilla
says that “while bind() does a [[ construct ]], apply() and call() do a [[ call ]].”
That’s why we are grouping call and apply together here; the nature of the
return value.</p>
</blockquote>
<p><strong>Traditional uses of call and apply include:</strong>
• To resolve context with this keyword</p>
<p>• To borrow methods (for example, to borrow Array methods such as slice or push
to array-like objects that aren’t actually arrays)</p>
<p>• With apply(), variadic functions</p>
<h3 id="call">Call()</h3>
<blockquote>
<p>Call is very similar to apply(). Call() takes an argument list, like most functions do.</p>
</blockquote>
<blockquote>
<p>Return value: The result of calling the function with specified “this” value and arguments.</p>
</blockquote>
<h3 id="apply">Apply()</h3>
<blockquote>
<p>Apply(): assigning a different “this” object when calling an existing function.</p>
</blockquote>
<blockquote>
<p>Apply() accepts a single array of arguments.</p>
</blockquote>
<blockquote>
<p>Return value: Same as call(): The result of calling the function with specified “this” value and arguments.</p>
</blockquote>
<blockquote>
<p>“Apply is very similar to call(), except for the type of arguments it supports.
You can use an arguments array instead of a named set of parameters. With apply,
you can use an array literal, for example, fun.apply(this, [‘eat’, ‘bananas’]),
or an Array object, for example, fun.apply(this, new Array(‘eat’, ‘bananas’)).”
Mozilla Docs
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply</p>
</blockquote>
<p>It’s important to note that in functional programming, functions aren’t “called.”
They’re “applied.” See the section on <strong>partial applications</strong> and <strong>curried
functions.</strong> For now, we will continue with apply().</p>
<p>Apply() is great for <strong>variadic functions</strong> (aka <strong>variable arity functions</strong>)
because apply() takes in arrays of arguments as parameters. So, great for
functions where it’s less deterministic how many arguments may end up getting
passed in.</p>
<p>You can <strong>apply</strong> the contextual <strong>this</strong> to <strong>other objects</strong>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var stripeyAnimal = {
species: "zebra",
age: 2
}
animal.ageGetter.apply(stripeyAnimal); // 2
</code></pre></div></div>
<h3 id="the-arguments-object">The arguments object</h3>
<blockquote>
<p>The arguments object object is an array-like object available in every JS function.</p>
</blockquote>
<p>Let’s say you write something like
<code class="language-plaintext highlighter-rouge">var x = Array.prototype.slice.call(argument, 1);</code> - the return value you’ll
get for <code class="language-plaintext highlighter-rouge">x</code> is <code class="language-plaintext highlighter-rouge">every element of the x object from index 1 onwards.</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function x (name) = {
return Array.prototype.slice.call(arguments,2);
}
x(1,2,3,4,5); // 3 4 5
</code></pre></div></div>
<blockquote>
<p>Because the arguments object is an array-like object, we can use the Array’s slice method as above by borrowing it using call().</p>
</blockquote>
<p><strong>Here’s another example with the arguments object using ES6’s let.</strong> Sort this array.</p>
<blockquote>
<p>Input: [111,2,66, 1]</p>
</blockquote>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function variadicStuff() {
var argsArray = Array.prototype.slice.call(arguments);
return argsArray.sort();
}
let sortMe = variadicStuff(111,2,66, 1);
sortMe; // invoke!
</code></pre></div></div>
<p>output:</p>
<blockquote>
<p>[1, 111, 2, 66]</p>
</blockquote>
<p><strong>Let’s use apply() and a variadic function</strong> such as Math.max() which returns
the maximum number. The format will usually be</p>
<p><code class="language-plaintext highlighter-rouge">function.apply(this, stuff);</code></p>
<p>Let’s use this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var x = Math.max(1,2,3,4); // 4
</code></pre></div></div>
<p>for an ARRAY: we get NaN because Math.max cannot convert this array to a
number primitive.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var arr = [1, 3, 5, 7];
var maxish = Math.max(arr);
maxish; // NaN
</code></pre></div></div>
<p>So, use apply(): the first argument is null because there is no this in Math.max().</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var arr = [1, 3, 5, 7];
var maxish = Math.max.apply(null, arr);
maxish; // 7 ... good!
</code></pre></div></div>
<h2 id="es6">ES6</h2>
<h3 id="arrow-functions">Arrow Functions</h3>
<p>• Arrow functions are basically function expressions written in a more compact way.
• Always anonymous, so of course arrow functions cannot be used for constructors
or anything requiring the <code class="language-plaintext highlighter-rouge">new</code> keyword.
• Arrow functions allow for a simpler handling of this, because arrow functions
do not bind their own this, OR their own arguments. For this reason, arrow
functions are often used in nested JavaScript functions:</p>
<p>https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function Person() {
// The Person() constructor defines `this` as an instance of itself.
this.age = 0;
setInterval(function growUp() {
// In non-strict mode, the growUp() function defines `this`
// as the global object, which is different from the `this`
// defined by the Person() constructor.
this.age++;
}, 1000);
}
var p = new Person();
</code></pre></div></div>
<p>In ECMAScript 3/5, the this issue was fixable by assigning the value in this to
a variable that could be closed over.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function Person () {
.... blah blah
var that = this;
setInterval()
{
that.age = stuff
}
}
</code></pre></div></div>
<p>We could also bind it, and return a bound function such as
<code class="language-plaintext highlighter-rouge">that.age.bind(this)</code> or similar,</p>
<p>Or just use an arrow function:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
</code></pre></div></div>
<p>Source:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions</p>
<h3 id="const-let-var">Const let var</h3>
<p>Declaring <code class="language-plaintext highlighter-rouge">var</code> can be problematic because it can bubble up in scope (see the scoping sections of this tutorial). Some engineers may say “var is global.” While that’s a simplistic way of looking at it, let’s move forward with that assumption and discuss const and let for variabe declaration.</p>
<blockquote>
<p>There are several languages in which <code class="language-plaintext highlighter-rouge">let</code> is similar to <code class="language-plaintext highlighter-rouge">const</code>.
We can also consider the JS <code class="language-plaintext highlighter-rouge">Object.freeze</code> for immutability.</p>
</blockquote>
<h3 id="const-requiring-initialization-upon-declaration-sets-a-read-only">Const, requiring initialization upon declaration, sets a “read only”</h3>
<h3 id="reference-to-a-value">reference to a value.</h3>
<p><strong>Const is not considered immutable; for immutability, use Object.freeze().</strong></p>
<p>What const means is that the <strong>variable identifier cannot be reassigned.</strong></p>
<blockquote>
<p>Use const to do things like push() an item into an array, but you don’t want
the overall properties / name of that array to change.</p>
</blockquote>
<h3 id="let-limits-scope-of-variables-to-the-blockstatementexpression-where-declared">Let limits scope of variables to the block/statement/expression where declared.</h3>
<blockquote>
<p>use let to “block scope” variables. This is unlike the <code class="language-plaintext highlighter-rouge">var</code> keyword which
defines a variable globally.</p>
</blockquote>
<p>https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let</p>
<h3 id="var-keyword-defines-a-variable-globally">Var keyword defines a variable globally.</h3>
<p><strong>Think about block scoped versus function scoped variables when using the
var keyword.</strong> Doesn’t the var keyword include the native “vanilla JS behavior”
we know so well with hoisting and bubbling up scope? Yes, it does.</p>
<blockquote>
<p>use “var” for when you want the entire enclosing scope to have access to
the SAME variable. Better yet, don’t use var. This is ES6. Use const and let.</p>
</blockquote>
<h3 id="const-and-let-the-temporal-dead-zone">Const and Let: the temporal dead zone</h3>
<p>In older JavaScript, we could use a variable inside a block before declaring it.
When we’re using const and let, however, we need to pay closer and more careful
attention to our usage because we can’t reference a variable prior to declaration
in the block-scoping type of scenarios created by const and let. Not even
hoisting will always save you, so when using const and let, always declare
everything in the block prior to use.</p>
<h2 id="es6-iterators-implicit-and-explicit">ES6 Iterators Implicit and Explicit</h2>
<h3 id="for-in--pre-es5">for in : pre ES5</h3>
<p>We’ll recall using <code class="language-plaintext highlighter-rouge">for item in items</code> syntax with JavaScript.
Well, that syntax is pre-ES5 and is used for objects (an unordered collection
of elements). Contrary to how we think about arrays, the elements that <code class="language-plaintext highlighter-rouge">for
in</code> constructs loop over are not order-guaranteed because objects in JS are not
ordered items.</p>
<p>ES5 introduced the .forEach() property:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var arr = [ "doge", "so", "wow"];
arr.forEach(function(value,index){
console.log("index [" + index + "]"" + value);
});
</code></pre></div></div>
<p>output:</p>
<blockquote>
<p>index [0]doge index [1]so index [2]wow</p>
</blockquote>
<h3 id="implicit-es6-iterators--for-of">Implicit ES6 Iterators : for of</h3>
<p>For of syntax is very similar to for in syntax, just a bit simpler.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var obj;
var list = [0, 1, 2, 3]
for (let obj of list) {
console.log(obj)
}
</code></pre></div></div>
<p>output:</p>
<blockquote>
<p>0 1 2 3</p>
</blockquote>
<h3 id="es6-iterators-explicit--next-done-and-valueskeysentries-">ES6 Iterators: Explicit ( next(), .done, and .values/keys/entries )</h3>
<p>A Javascript iterator provides a next() method. Very similar to iterators and
containers in C/C++, or Java collections.</p>
<p>A generator function that returns a new object each time you call <code class="language-plaintext highlighter-rouge">next</code>. There
is a done property, and there are other properties like … .values, .keys,
.entries.</p>
<p>More on this later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators</p>
<p>And while we’re at it, we’ll mention ES6 <code class="language-plaintext highlighter-rouge">Symbol.</code> More on this, later, too.</p>
<h3 id="rest-parameters-for-variadic-functions-es6">Rest parameters for variadic functions (ES6)</h3>
<p>More soon on this.</p>
<h3 id="es6-and-angular">ES6 and Angular</h3>
<h4 id="refactoring-for-future-proof-angular-15---2--es6-js-the-future">Refactoring for future proof Angular 1.5 -> 2 + ES6 JS: the future</h4>
<p>• <strong>Creating future-proof 1.5 to Angular 2 with incremental steps:</strong></p>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">Use component directives instead of controllers</code>: like <code class="language-plaintext highlighter-rouge">Web Components</code>…
Angular 1.5 introduced the .component. For future-proof Angular 1.5,
use <code class="language-plaintext highlighter-rouge">controllerAs</code> syntax in component directives. You can do just about
everything you could do in <code class="language-plaintext highlighter-rouge">.directive</code> with the <code class="language-plaintext highlighter-rouge">.component</code> keyword instead,
and more. In Angular 2, controllers are going away, and we replace them
with the Web Components-like component directives. Remove controllers from
routers (ngRoute or UI-Router). Note that ngRoute is also fairly deprecated.</p>
</blockquote>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">Use arrow functions wherever possible</code>:
A simpler way to bind to the parent’s this in nested functions. Not appropriate
for Angular controllers, because Angular controllers “control” the context of
“this”. <code class="language-plaintext highlighter-rouge">Not appropriate for</code> constructor function or any function using the <code class="language-plaintext highlighter-rouge">new</code> keyword, as that would require a <code class="language-plaintext highlighter-rouge">name</code> and arrow functions are anonymous.</p>
</blockquote>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">Angular: Put logic in services (classes), and UI code in component directives</code>:
This is what modern Angular consists of: logic in services, and UI code
in directives/components - that is it! Classes map perfectly to services!</p>
</blockquote>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">Use const over let, so you can mutate later.</code></p>
</blockquote>
<h2 id="common-javascript-design-patterns">Common JavaScript Design Patterns</h2>
<h3 id="module-pattern--encapsulation">Module Pattern : “Encapsulation”</h3>
<p>The module pattern just refers to JavaScript modules, which are analogous to
classes; the module pattern addresses access (public, private, protected).</p>
<p>Protected data is usually wrapped in an IIEF to protect access for private data.</p>
<h3 id="singleton-pattern--globals--state">Singleton Pattern : Globals / State</h3>
<p>We’re familiar with the Singleton Design Pattern for sharing of state and
similar globally required data with reference counting or similar constructs.</p>
<h3 id="the-observer-and-publish-subscribe-patterns-streams-observables">The Observer and Publish Subscribe Patterns: Streams, Observables,</h3>
<h3 id="broadcast-events-data-binding">Broadcast, Events, Data Binding</h3>
<p>We’re familiar with the Observer Pattern, the more restricted/”exclusive”
version of the Publish-Subscribe Design Pattern.</p>
<h4 id="use-when">Use When:</h4>
<ul>
<li>broadcast situations such as an event bus</li>
<li>Reactive Programming / Streams / events / clicks</li>
<li>systems where control flow is difficult to follow in real time and hence
the engineer’s focus is placed on communication patterns instead of control
flow (Gang of Four)</li>
<li>contexts in which a part of the system will be updated, and that
part of the system needs to update another part of the system without needing
to know its implementation details (Gang of Four).</li>
</ul>
<h4 id="consequences-gang-of-four">Consequences (Gang of Four):</h4>
<ul>
<li>update another part of the system without needing to know its implementation
details (Gang of Four). Yay, good!</li>
<li>update another part of the system without needing to know its implementation
details (Gang of Four). Noo, bad! You don’t know WHAT is being updated, and
this may cause issues with <strong>unexpected updates</strong> and <strong>an update not
knowing the consequences, system-wide, of that update.</strong> Basically the
consequences of Observer/Publish Subscribe are <strong>hey, what happened?</strong></li>
</ul>
<h4 id="whats-the-difference-between-observer-and-publish-subscribe-patterns">What’s the difference between Observer and Publish Subscribe Patterns?</h4>
<p><strong>The difference is whether you have to register - hence, abstraction.</strong></p>
<p>Recall that PubSub Publisher broadcasts all messages non exclusively to any
Subscriber who will listen or subscribe. The Observer Design Pattern is slightly
different because the Observed or Subject or Observable maintains a list of the
Subscribers in a data structure, and the Observers must request access).
Methods for Attach() and Detach() and Notify() (and subscribe() and
unsubscribe() ) are relatively intuitive.</p>
<p>Observer hence <strong>notifies its registered subscribers</strong>, and Publish Subscribe
<strong>broadcasts messages to its listeners which it knows nothing about.</strong></p>
<h3 id="whats-an-example-of-an-observer-angular-watchers">What’s an example of an Observer? Angular Watchers.</h3>
<h3 id="whats-another-example-streams-are-observables-or-subjects">What’s another example? Streams are ‘Observables’ or ‘Subjects’</h3>
<h3 id="observables-promises-reactive-programming-streams">Observables, Promises, Reactive Programming, Streams:</h3>
<p>While Promises are often used in asynchronous, Reactive Programming tends to
use more Streams, which are Observables. Observables are Promises with
additional features such as being cancellable (via unsubscribe() or detach() )
whereas Promises do not offer the ability to cancel or unsubscribe.</p>
<h2 id="inversion-of-control-pattern-dependency-injection">Inversion of Control Pattern (Dependency Injection)</h2>
<p>Inversion of Control is the inversion of the expected relationship between
object and dependency; it is expected that an object will retrieve its own
dependencies. When passing a function in as an argument, the dependency is
passed directly to the object, and can hence influence the object. This is
referred to as “Inversion of Control”.</p>
<p>For an interesting and oppositional opinion on dependency injections,
read DHH’s
<a href="http://david.heinemeierhansson.com/2012/dependency-injection-is-not-a-virtue.html">Dependency injection is not a virtue</a>.
David is essentially saying that DI is used to make inflexible languages,
flexible.</p>
<p>… To be continued in Part 2!</p>
<p><span>Category: tutorials</span></p>JavaScript Tutorials for the C/C++ programmer or CS Grad, Part 1An AWS EC2 and Node/Express deployment tutorial2016-10-31T21:56:22+00:002016-10-31T21:56:22+00:00http://amandafalke.com/tutorials/2016/10/31/tutorial-node-express-aws-ec2<h1 id="deploying-an-express-node-app-to-aws--part-1-aws-linux-node-and-express">Deploying an Express Node app to AWS : Part 1 (AWS Linux, Node, and Express)</h1>
<h2 id="an-app-created-for-my-simple-educational-purposes-for-full-mean-stack-development">An app created for my simple educational purposes for full MEAN stack development.</h2>
<h2 id="there-is-no-magic-theres-only-software">There is no magic. There’s only software.</h2>
<h3 id="requirements--overview">Requirements + Overview:</h3>
<p>Make a vertical slice of a full stack application without using too many “magical abstractions”. In this way, gain a better understanding of the details of full stack application, sans reliance on “magic.”</p>
<h4 id="tools-you-can-use">Tools you can use:</h4>
<ul>
<li>Node, npm</li>
<li>AWS Ubuntu instance</li>
<li>nginx</li>
<li>bash</li>
<li>ssh</li>
<li>scp</li>
<li>process (whatever runs a service of your choice, usually Ubuntu’s upstart)</li>
</ul>
<h4 id="tools-you-can-not-use">Tools you can not use:</h4>
<ul>
<li>pm2</li>
<li>capistrano</li>
<li>Node’s ForeverJS</li>
<li>Heroku</li>
</ul>
<p>Hand out a public IP which can be hit with a curl request.</p>
<ol>
<li>
<p>Make a single-file express app.</p>
</li>
<li>
<p>Return a hardcoded bit of text in response to a curl. <em>re: app.js code and comments</em></p>
</li>
<li>
<p>Explain how request/response works. <em>re: app.js code and comments</em></p>
</li>
<li>
<p>Create custom HTTP headers as needed with proper MIME types for the plaintext request you’re making.</p>
</li>
<li>
<p>Clustering, “load balancing” emulation, server instances, and using ports. Connecting to an app’s endpoint. (Parameterize the application.) <em>re: app.js code and comments</em></p>
</li>
<li>
<p>Post to service via curl. Change/alter HTTP headers as necessary using proper MIME types. (Use express’ body-arser middleware.) <em>re: app.js code and comments</em></p>
</li>
<li>
<p>Recreate that process with a bash script to fire up Node; compare program exit codes with conditionals, and capture the output of the command in a variable. <em>re: verifyscript.sh</em></p>
</li>
<li>
<p>Deploy on AWS Linux Ubuntu EC2 VM instance.
<br /><br /> This will involve setting up the virtual Ubuntu machine (14.04) using the AWS Console as well as selecting appropriate security groups. This will also involve setting up a new or existing key pair for secure SSH. Server user administration should not involve logging in with a password; instead, allow users access via their keys, and remove their access by removing their keys. Once an AWS EC2 Ubuntu instance is up and running, you can install desired software using appropriate package management tools, as follows.</p>
</li>
</ol>
<p><strong>Logging in</strong></p>
<p>Getting started on AWS EC2 Ubuntu will involve first logging in using keys. Start by downloading your private key keyname.pem, putting it in:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~/.ssh/keyname.pem
</code></pre></div></div>
<p>Changing the permissions using chmod so that your private key isn’t publicly available:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ chmod 400 /path/to/keyname.pem
</code></pre></div></div>
<p>Shelling in using optarg -i for identity. Note that for Amazon EC2 Ubuntu instances, the username will not be <em>user</em> like the AMI AWS instances; rather, it will be <em>ubuntu</em>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ssh -i /path/to/keyname.pem user@AWSpublicDNS
</code></pre></div></div>
<p>Scp a file to user’s home ~/. Note that we aren’t using rsync at this time.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ scp -i /path/to/keyname.pem /path/file.txt user@AWSpublicDNS:~
</code></pre></div></div>
<p>Recall permissions are in binary/hex as such. Here is an example of our users group being able to read, write and execute, and everyone else can just read:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>User 'u' Group 'g' Others 'o'
r w x r - - r - -
1 1 1 1 0 0 1 0 0
7 4 4
</code></pre></div></div>
<p><strong>All users should be logging in with public/private keys, not with passwords.</strong></p>
<p>To do this, you will need to work with Ubuntu’s <strong>sshd_config</strong> OpenSSH daemon config file to:</p>
<ol>
<li>temporarily enable password logins (change “no” to “yes”) to set the proper public/private keys</li>
<li>copying the keys from local to AWS via <strong>ssh-copy-id.</strong></li>
<li>Once you’re done setting up keys and access on the server, ensure that you disable password authentication (change it to no in aforementioned server settings).</li>
<li>Try it out, you should be able to shell in without passwords.</li>
<li>
<p>Note that the <strong>USER GROUP for your deploy user,</strong> and it should be in the <strong> same user group as www-data.</strong></p>
<p>Set permissions as required, and remember, permissions are conservative, and restricted.</p>
<p>Here are some details on the user management I did:</p>
<p>Set Ubuntu’s sshd_config file to accept password authentication type: Do this for your non-“ubuntu-username” sudoer user:</p>
<p>```
$ cd /etc/ssh
$ sudo vim sshd_config</p>
</li>
</ol>
<p># Change to no to disable tunnelled clear text passwords
PasswordAuthentication no
```
Change that line to say yes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> PasswordAuthentication yes
</code></pre></div></div>
<p>Make an ssh directory for your user and change permissions to rwx for user:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ mkdir ~/.ssh
$ chmod 700 ~/.ssh
// confirm permissions with $ ls -al
</code></pre></div></div>
<p>The file that ssh-copy-id will create is in this ~/.ssh directory and it will be named authorized_keys.</p>
<p>Before we use ssh-copy-id, we will need to restart the ssh service that we just changed the configuration for. Ubuntu calls the service ssh, not sshd:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ sudo service ssh restart
ssh stop/waiting
ssh start/running, process 12345
</code></pre></div></div>
<p>ssh-copy-id from local to remote. If you don’t use -i option, ssh-copy-id just defaults to ~/.ssh/authorized_keys.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ ssh-copy-id gobbuth@awspublicIP
....INFO: 1 key(s) remain to be installed --
if you are prompted now it is to install the new keys
</code></pre></div></div>
<p>Now the system will prompt you for the user’s password, ONCE. Note, you’re not using it to login to the server. You’re using it so that ssh-copy-id works once:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> gobbluth@AWSpublicIP's password:
</code></pre></div></div>
<p>Enter the user’s password, then you’ll see:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Number of key(s) added:
1
Now try logging into the machine, with:
"ssh 'gobbluth@AWSPublicIP'"
and check to make sure that only the key(s)
you wanted were added.
</code></pre></div></div>
<p>Close. You want to ssh with verbose -v option selected. It’s just really fun to see the options you configured in Ubuntu’s sshd OpenSSH daemon configuration file here:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ ssh -v gobbluth@AWSPublicIP
</code></pre></div></div>
<p>Then you’ll see this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> debug1: Reading configuration data /etc/ssh/ssh_config
</code></pre></div></div>
<p>…followed by a TON of stuff..
…eventually you’ll see something like the following. It’s telling you that both password authentication and keypair authentication are enabled on the server, and that you’re authenticated (you hipster you):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /Users/yourLocalUser/.ssh/id_rsa
debug1: Server accepts key: blah blah blah
debug1: Authentication succeeded (publickey).
Authenticated to AWSPublicIP
... Welcome to Ubuntu.
</code></pre></div></div>
<p>Then we disable passwd authentication:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ cd /etc/ssh
$ sudo vim sshd_config
//password authentication yes
//change to no
//save
$ sudo service ssh restart
</code></pre></div></div>
<p><strong> And that’s how you set up and administer Linux users for keypair authentication rather than passwd authentication. Test it out by shelling into the server from your local machine simply using the ssh command followed by your server username@awspublicIP. Now we can look at further user admin:</strong></p>
<p>To see what users are on Debian:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ cat /etc/passwd
</code></pre></div></div>
<p><strong>To add a user,</strong> You can use the commands <strong>useradd</strong> or <strong>adduser.</strong> <em>“On Debian, administrators should usually <strong>use adduser(8)</strong> instead”</em> (http://askubuntu.com/questions/345974/what-is-the-difference-between-adduser-and-useradd). We will make a new user for GOB Bluth.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ sudo adduser gobbluth
</code></pre></div></div>
<p>Check the user group.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ id gobbluth
</code></pre></div></div>
<p>Add user to appropriate group. It involves something like this: ‘ sudo -a -G groupname username’… the options -a -G ADDS a user to a Group. http://www.howtogeek.com/50787/add-a-user-to-a-group-or-second-group-on-linux/.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo groupadd newGroupName
$ sudo -a -G newGroupName gobbluth
</code></pre></div></div>
<p>For example, to make a user a sudoer:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo groupadd newGroupName
$ sudo -a -G newGroupName gobbluth
// check your work:
$ id gobbluth
// should say gobbluth is a sudoer.
</code></pre></div></div>
<p>Another example, to make a user belong to the same group that www-data belongs to in order to create appropriate deployment permissions for our deploy user:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ sudo -a -G www-data gobbluth
// check your work:
$ id gobbluth
// should say gobbluth is a member of www-data group!
</code></pre></div></div>
<p><strong>After you add a user and group, set a password for that user, and add the user to the appropriate group, you’ll need to copy the public key for that user to the authorized keys directory for that user. </strong> <em>Check back with the numbered list items for user management above to ensure you went through all the steps. If you want another user to assume deploy, you’ll have to copy that user’s public key into the authorized_keys file for that user. Note that we normally wouldn’t have a user deploying code, we’d use Jenkins or similar CI.</em></p>
<p><strong>Once you’re set up properly with users, install git and curl using the Debian distro’s apt installer :</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ sudo apt-get install curl git
</code></pre></div></div>
<p><strong>Now we begin standing up the server:</strong></p>
<p><strong>First you have to install Node: </strong> <br />
I chose to install Node on AWS using nvm instead of using Debian’s apt-get package manager to install Node. That’s because nvm helps you manage specific versions of Node on a per-project basis. As with all npm-related projects, the point of a per-project package manager includes project-directory installations of software packages/versions <em>instead of global installs.</em></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ nvm script
// To verify installed version:
$ command -v nvm
// Install the version you want:
$ nvm install 4.2.3
// To specify version in nvmrc file for THIS project directory (remember that one of the points of using npm is to manage packages PER project, and that's why global installs are something to watch out for and often avoid:) From project root dir:
$ echo "4.2.3" > .nvmrc
// Now, to USE that Node version:
$ nvm use
</code></pre></div></div>
<p><strong>Second, you’ll need to install a web server. I chose nginx instead of Apache or other options, and I installed it using Debian (Ubuntu) Linux’s distribution’s package manager tools apt-get. </strong> The point here is that we are managing our own installations rather than always using installers providers give us. It’s always best to spin things up by hand so you learn the underlying logic/tech. MAGIC BAD.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ apt-get install nginx // or similar
// you can start and stop nginx signals as such:
$ sudo service yourappdirectory start
$ sudo nginx -s reload
</code></pre></div></div>
<p>Note that with the above, yourappdirectory will read nodeapp for us in the future.</p>
<p><strong>Third, you have to set up the proper users, groups, and permissions. </strong>
Set and manage shell users and permissions on EC2 instance. Your deploy user cannot be a sudo-er. You want to restrict permissions and be conservative.</p>
<p><strong>Fourth, you have to spin up a service by hand on the AWS EC2 Ubuntu instance using upstart daemon, make it executable, and set the proper Linux run levels. Of course, a sudoer must complete all of these tasks, not your deploy user. You’re replacing the start-at-boot init.d daemon with one of your own!</strong></p>
<p>Create the conf file: Where nodeapp is the name of your app’s directory:</p>
/etc/init/nodeapp.conf
<p>Make it executable for the user group containing the www-data and your deploy users:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ chmod u+x conf-file // similar to this
</code></pre></div></div>
<p>Set the proper Linux runlevels. Odd levels are for shutdown-related stuff, and even levels are for startup-related stuff. You’ll also need to setuid to your deploy user and set the proper directory :</p>
///etc/init/nodeapp.conf FILE:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> description "my rad daemon"
author "Amanda Falke"
start on runlevel[2345]
stop on runlevel[016]
respawn
setuid deploy
chdir /home/sudousername/yourappdirectory
exec node app.js
</code></pre></div></div>
<p>Reboot the web server:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ sudo nginx -s reload
</code></pre></div></div>
<p>Spawn the daemon:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo service nodeapp start
</code></pre></div></div>
<p>The npm script</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ npm run deploy
</code></pre></div></div>
<p>will deploy changes. Make sure that you don’t follow the standard “npm” instructions of placing your binary, also known as deployscript.sh or scpscript.sh, in project_root/node_modules/.bin/scpscript.sh, along with “scripts”: { “deploy”: “scpscript.sh” } because <em>node_modules is git-ignored.</em> So place that script in project root, “scripts”: { “deploy”: “./scpscript.sh” }</p>
<p>And test this by cloning into a new directory, pulling down changes, and running npm run deploy. Should be successful.</p>
<h1 id="final-result-public-ip-and-curl-results-for-aws">Final result: public IP and curl results for AWS:</h1>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ curl -X POST -d
name=GobBluthBeesHowHardCanItBe
http://54.148.122.112:5001/foo
-H "Content-Type: text/plain"
</code></pre></div></div>
<p>Response received:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>name=GobBluthBeesHowHardCanItBe
</code></pre></div></div>
<p>Success!</p>
<h3 id="notes">Notes:</h3>
<h4 id="nginx">nginx</h4>
<p>Sudoer creates nginx conf file with env PORT = 5100, this may remove paramaterization of ports which conflicts with existing program.</p>
<h2 id="to-be-continued-in-part-2-mongodb-with-mongoose-client">To be continued in part 2: MongoDB with Mongoose client!</h2>
<p><span>Category: tutorials</span></p>Deploying an Express Node app to AWS : Part 1 (AWS Linux, Node, and Express)