<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: malik</title>
    <description>The latest articles on DEV Community by malik (@milkstarz).</description>
    <link>https://dev.to/milkstarz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F38714%2Fd7fc80b8-4bb8-402d-8df9-bac418c5e6d4.jpeg</url>
      <title>DEV Community: malik</title>
      <link>https://dev.to/milkstarz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/milkstarz"/>
    <language>en</language>
    <item>
      <title>A Beginner's Guide: Glob Patterns</title>
      <dc:creator>malik</dc:creator>
      <pubDate>Fri, 08 Nov 2019 02:02:25 +0000</pubDate>
      <link>https://dev.to/milkstarz/a-beginner-s-guide-glob-patterns-3gh3</link>
      <guid>https://dev.to/milkstarz/a-beginner-s-guide-glob-patterns-3gh3</guid>
      <description>&lt;p&gt;This post was originally posted on &lt;a href="https://www.malikbrowne.com/blog"&gt;malikbrowne.com&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Recently, one of my coworkers was having trouble because Jest wasn't running tests on a new folder he had created. &lt;/p&gt;

&lt;p&gt;After some investigation, it turns out that the Jest configuration glob didn't include this whole folder of tests that weren't running! (Scary!)&lt;/p&gt;

&lt;p&gt;Understanding how globs work was essential to understanding how to fix this problem, and there isn't a &lt;em&gt;ton&lt;/em&gt; of documentation on it other than the &lt;a href="http://man7.org/linux/man-pages/man7/glob.7.html"&gt;Linux manual&lt;/a&gt;. Let's change that!&lt;/p&gt;

&lt;p&gt;In this post, we'll go over the history of globs, how to use wildcard characters, and define the three main characters of wildcard matching.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the heck are globs?
&lt;/h2&gt;

&lt;p&gt;Globs, also known as &lt;em&gt;glob patterns&lt;/em&gt; are patterns that can expand a wildcard pattern into a list of pathnames that match the given pattern.&lt;/p&gt;

&lt;p&gt;On the early versions of Linux, the command interpreters relied on a program that expanded these characters into unquoted arguments to a command: &lt;code&gt;/etc/glob&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This command was later on provided as a library function, which is now used by tons of programs, including the shell. Several different tools and languages have adopted globs, putting their little spin on it. It's quite the extensive list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;li&gt;Haskell&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Ruby&lt;/li&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that we know a little bit about the history of globs, let's get into the part that makes it useful: wildcard matching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wildcard Matching
&lt;/h2&gt;

&lt;p&gt;A string can be considered a wildcard pattern if it contains one of the following characters: &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;?&lt;/code&gt;, or &lt;code&gt;[&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Asterisks (*)
&lt;/h3&gt;

&lt;p&gt;The most common wildcard that you'll see is the asterisk. This character is used in many ways but is mainly used to match any number of characters (like parts of a string).&lt;/p&gt;

&lt;p&gt;The three main use cases of asterisks that I've seen used are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; - On Linux, will match everything except slashes. On Windows, it will avoid matching backslashes as well as slashes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;**&lt;/code&gt; - Recursively matches zero or more directories that fall under the current directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*(pattern_list)&lt;/code&gt; - Only matches if zero or one occurrence of any pattern is included in the pattern-list above &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These use cases can also be used in conjunction with each other! For example, to find all Markdown files recursively that end with &lt;code&gt;.md&lt;/code&gt;, the pattern would be &lt;code&gt;**/*.md&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;*.md&lt;/code&gt; would only return the values in the current directory, which is why we append &lt;code&gt;**/&lt;/code&gt; at the beginning. &lt;/p&gt;

&lt;h3&gt;
  
  
  Question Marks (?)
&lt;/h3&gt;

&lt;p&gt;The question mark wildcard is commonly used to match any single character.&lt;/p&gt;

&lt;p&gt;For example, let's say were given a list of files:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Cat.png&lt;/li&gt;
&lt;li&gt;Bat.png&lt;/li&gt;
&lt;li&gt;Rat.png&lt;/li&gt;
&lt;li&gt;car.png&lt;/li&gt;
&lt;li&gt;list.png&lt;/li&gt;
&lt;li&gt;mom.jpg&lt;/li&gt;
&lt;li&gt;cat.jpg&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you wanted to find all the files that had &lt;code&gt;_at&lt;/code&gt; in the folder, you could conveniently use a pattern like &lt;code&gt;?at&lt;/code&gt; which would return the following results:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Cat.png&lt;/li&gt;
&lt;li&gt;Bat.png&lt;/li&gt;
&lt;li&gt;Rat.png&lt;/li&gt;
&lt;li&gt;cat.jpg&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: A cool thing about this pattern is that it didn't care about the case of the character. I've found this useful in scripts when trying to find files that I've marked with certain dates.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Character classes and Ranges ([)
&lt;/h2&gt;

&lt;p&gt;The square brackets ( [, and ] ) can be used to denote a pattern that should match a single character that is enclosed inside of the brackets. These are called character classes. &lt;/p&gt;

&lt;p&gt;An important thing to know is that the string inside of the brackets is &lt;strong&gt;not allowed to be empty.&lt;/strong&gt; This can lead to misunderstandings of weird patterns like this: &lt;code&gt;[][!]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This would match the first three characters in a string that had &lt;code&gt;"\["&lt;/code&gt;, &lt;code&gt;"\]"&lt;/code&gt;, and &lt;code&gt;"!"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, let's continue to use the same list we used in the previous example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Cat.png&lt;/li&gt;
&lt;li&gt;Bat.png&lt;/li&gt;
&lt;li&gt;Rat.png&lt;/li&gt;
&lt;li&gt;car.png&lt;/li&gt;
&lt;li&gt;list.png&lt;/li&gt;
&lt;li&gt;mom.jpg&lt;/li&gt;
&lt;li&gt;cat.jpg&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you wanted to match only the title cased files in this list, you could use the pattern &lt;code&gt;[CBR]at&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This would return the result:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Cat.png&lt;/li&gt;
&lt;li&gt;Bat.png&lt;/li&gt;
&lt;li&gt;Rat.png&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Ranges
&lt;/h3&gt;

&lt;p&gt;A cool feature that is available for globs are ranges, which are denoted by two characters that are separated by a dash '-'.&lt;/p&gt;

&lt;p&gt;For example, the pattern &lt;code&gt;[A-E]&lt;/code&gt; would match any starting character that included &lt;code&gt;ABCDE&lt;/code&gt;. Ranges can be used in conjunction with each other to make powerful patterns. &lt;/p&gt;

&lt;p&gt;A common pattern that you may have seen before is the pattern to match alphanumerical strings: &lt;code&gt;[A-Za-z0-9 ]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This would match the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[A-Z]&lt;/code&gt; All uppercase letters from A to Z &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[a-z]&lt;/code&gt; All lowercase letters from a to z&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[0-9]&lt;/code&gt; All numbers from 0 to 9 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can be used for data validation in tons of different areas since ranges work in regex expressions as well!&lt;/p&gt;

&lt;h2&gt;
  
  
  Complementation
&lt;/h2&gt;

&lt;p&gt;A feature worth mentioning is that globs can be used in complement with special characters that can change how the pattern works. The two complement characters that I see are exclamation marks (&lt;code&gt;!&lt;/code&gt;) and backslashes (&lt;code&gt;\&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The exclamation mark can negate a pattern that it is put in front of. In the character class example I shared above, we used the pattern &lt;code&gt;[CBR]at&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If we wanted to explicitly filter the results we wanted, we could negate the pattern by placing the exclamation point in front of the class &lt;code&gt;[!CBR]at&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Backslashes are used to remove the special meaning of single characters &lt;code&gt;'?'&lt;/code&gt;, &lt;code&gt;'*'&lt;/code&gt;, and &lt;code&gt;'['&lt;/code&gt;, so that they can be used in patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are globs useful?
&lt;/h2&gt;

&lt;p&gt;I've found globs extremely useful for doing a lot of scripting and automation tasks in recent months. Being able to specify certain files recursively in a directory tree is invaluable - especially when working in CI environments where you don't have control over the names of root directories.&lt;/p&gt;

&lt;p&gt;Something important that I want to note is that while wildcard patterns are similar to regex patterns, they are &lt;strong&gt;not&lt;/strong&gt; explicitly the same for two main reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Globs are meant to match filenames rather than text&lt;/li&gt;
&lt;li&gt;Not all conventions are the same between them (example: &lt;code&gt;*&lt;/code&gt; means zero or more copies of the same thing in regex)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hopefully, this overview of globs provides some transparency when looking over different configuration files in the future. I know this is something that I struggled with understanding when trying to read webpack/typescript/jest configurations, so if this is helpful to you, let me know in the comments or on &lt;a href="https://twitter.com/milkstarz"&gt;Twitter!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful Links/Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.globtester.com/"&gt;http://www.globtester.com/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Glob_(programming)"&gt;https://en.wikipedia.org/wiki/Glob_(programming)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://commandbox.ortusbooks.com/usage/parameters/globbing-patterns"&gt;https://commandbox.ortusbooks.com/usage/parameters/globbing-patterns&lt;/a&gt;&lt;br&gt;
&lt;a href="http://teaching.idallen.com/cst8207/15w/notes/190_glob_patterns.html"&gt;http://teaching.idallen.com/cst8207/15w/notes/190_glob_patterns.html&lt;/a&gt;&lt;br&gt;
&lt;a href="http://man7.org/linux/man-pages/man7/glob.7.html"&gt;http://man7.org/linux/man-pages/man7/glob.7.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>bash</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Helpful Terminal Commands for Beginners!</title>
      <dc:creator>malik</dc:creator>
      <pubDate>Wed, 05 Sep 2018 05:39:12 +0000</pubDate>
      <link>https://dev.to/milkstarz/helpful-terminal-commands-for-beginners-5cjh</link>
      <guid>https://dev.to/milkstarz/helpful-terminal-commands-for-beginners-5cjh</guid>
      <description>&lt;p&gt;This cheat sheet was originally posted on &lt;a href="https://www.malikbrowne.com/blog"&gt;malikbrowne.com&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;love&lt;/strong&gt; learning new commands and tools to optimize my workflow on my Mac. Since I have started working with more terminal-oriented applications, there are several commands that I use that I'd love to share with beginners and terminal lovers alike.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This article assumes that you're using some type of &lt;strong&gt;UNIX shell&lt;/strong&gt;, with a preference towards Mac. Some of these commands may not work on Windows CMD/Powershell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Commands
&lt;/h2&gt;

&lt;p&gt;Commands in a shell can be used in a ton of different ways - but I'd say that the important ones to learn fall under three main categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigating and Working with Files &amp;amp; Directories&lt;/li&gt;
&lt;li&gt;Manipulating Output for Input&lt;/li&gt;
&lt;li&gt;Finding Things&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Navigating and Working with Files &amp;amp; Directories
&lt;/h3&gt;

&lt;p&gt;On a computer, files and directories (otherwise known as folders) are responsible for managing information. Here are some commands to make your life easier when working with files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cd&lt;/code&gt; - navigate to different directories&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pwd&lt;/code&gt; - see the name of the current directory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ls&lt;/code&gt; - lists all files in the current directory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mkdir&lt;/code&gt; - make a new directory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;touch&lt;/code&gt; - make a new file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cp&lt;/code&gt; - copy a file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mv&lt;/code&gt; - move a file or directory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rm&lt;/code&gt; - removes a file or directory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;zip&lt;/code&gt; - compresses files into a zip archive&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unzip&lt;/code&gt; extracts files from a zip archive&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chmod&lt;/code&gt; - Allows you to make a file executable and change permissions granted to it by your machine.

&lt;ul&gt;
&lt;li&gt;In order to make a file executable, you can type &lt;code&gt;chmod +x [name of file]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tar&lt;/code&gt; - Allows you to work with tarballs in a Linux command line. It has a long list of uses, including package management for systems.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tar -cvf&lt;/code&gt; allows you to create a &lt;strong&gt;.tar&lt;/strong&gt; archive&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tar -xvf&lt;/code&gt; allows you to "untar" a &lt;strong&gt;.tar&lt;/strong&gt; archive&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tar -tvf&lt;/code&gt; list the contents of a &lt;strong&gt;.tar&lt;/strong&gt; archive&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Honorary Mention: &lt;code&gt;sudo&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo&lt;/code&gt; is a very widely used command in bash interfaces that allows you to run a command with administrative or root privileges. &lt;/p&gt;

&lt;p&gt;For example, if you edit any files in the root directory (also known with the path &lt;code&gt;/&lt;/code&gt;) of your machine without &lt;code&gt;sudo&lt;/code&gt; privileges, you will be denied permissions to edit the file. &lt;/p&gt;

&lt;p&gt;For your safety, there are a couple of things your computer will not allow you to do as a &lt;code&gt;sudo&lt;/code&gt;'d command, i.e. running bash scripts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manipulating Output for Input
&lt;/h3&gt;

&lt;p&gt;Often times when scripting the goal you are trying to achieve is to run filters through text, check output logs from a server, or run batch commands on multiple files. &lt;/p&gt;

&lt;p&gt;Here are some commands that can be beneficial for manipulating file output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cat&lt;/code&gt; - show a file's contents&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;head&lt;/code&gt; - displays the first few lines of a file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tail&lt;/code&gt; - displays the last few lines of a file

&lt;ul&gt;
&lt;li&gt;Using the &lt;code&gt;-f&lt;/code&gt; flag with &lt;code&gt;tail&lt;/code&gt; will allow you to see updates to the file as they are coming in. This is extremely helpful for tracking log output from servers.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;|&lt;/code&gt; - The pipe character take a command's output and uses it for the input of another command&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; - matches zero or more characters in a filename

&lt;ul&gt;
&lt;li&gt;There is actually a whole way of matching multiple files and names via globs!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;?&lt;/code&gt; - matches any single character in a filename&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;gt;&lt;/code&gt; - stores a command's output to a file, and creates a new file if one doesn't already exist

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WARNING:&lt;/strong&gt; This will override and replace all contents that were in the original file.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; - concatenates a command's output to a file, creates a new file if none is found&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Finding things
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;echo&lt;/code&gt; - show text or the compiled text of other commands. Great for testing commands out.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;grep&lt;/code&gt; - allows you to find results line by line using some sort of pattern or regular expression.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ack&lt;/code&gt; - similar to grep, but has a better code search because it knows to search in places you'd expect it to search. (ignores version control directories, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Other helpful commands I've found
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pbcopy&lt;/code&gt; - Copy selected text into your clipboard buffer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;history&lt;/code&gt; - Prints the command history for your session

&lt;ul&gt;
&lt;li&gt;This is really useful with grep and the pipe symbol, which will allow you to search through your history: &lt;code&gt;history | grep [part of command]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pbpaste&lt;/code&gt; - Paste the selected text in the terminal from your clipboard buffer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;curl&lt;/code&gt; - Allows you to make HTTP calls RESTful endpoint&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kill&lt;/code&gt; - Kills a running process given a process id (pid)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;killall&lt;/code&gt; - Kills all running processes of a certain type&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lsof -i tcp:[port number here]&lt;/code&gt; - list all running processes on a specific port

&lt;ul&gt;
&lt;li&gt;This one is particularly useful for when you get an error like:
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Error: listen EADDRINUSE :::3005
        at Object.exports._errnoException (util.js:1023:11)
        at exports._exceptionWithHostPort (util.js:1046:20)
        at Server._listen2 (net.js:1261:14)
        at listen (net.js:1297:10)
        at Server.listen (net.js:1375:9)
        at Object.&amp;lt;anonymous&amp;gt; (/path/to/node/server/server.js:15:34)
        at Module._compile (module.js:571:32)
        at loader (/path/to/node/modules/node_modules/babel-register/lib/node.js:144:5)
        at Object.require.extensions.(anonymous function) [as .js] (/var/www/html/gcsbpo/rocc/node_modules/babel-register/lib/node.js:154:7)
        at Module.load (module.js:488:32)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It provides an easy way to find out the pid to kill the running process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shortcuts/Tips &amp;amp; Tricks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;!$&lt;/code&gt; expands the final argument of the previous command. Useful for chaining commands on the same file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;!!&lt;/code&gt; - repeats the last command executed

&lt;ul&gt;
&lt;li&gt;These are thanks to &lt;a href="https://dev.to/ferricoxide"&gt;Thomas&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;![number]: Repeat command from your history (you can see the available command-history using fc -l (or fc -l 1 to see all the contents of your history)&lt;/li&gt;
&lt;li&gt;!! [extra stuff]: Re-execute last command, tacking on  at the end of the command.&lt;/li&gt;
&lt;li&gt;[extra stuff]!!: Re-execute last command, tacking on [extra stuff] at the beginning of the command. Very handy for executing something as a regular user that needs to be ran with &lt;code&gt;sudo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;!!:s/[SEARCH]/[REPLACE]: Re-execute last command, replacing first substring [SEARCH] with [REPLACE]&lt;/li&gt;
&lt;li&gt;!!:s/[SEARCH]/[REPLACE]: Re-execute last command, replacing all substring [SEARCH]es with [REPLACE]es&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clear&lt;/code&gt; - clears all output from the terminal, old output - can still be accessed by scrolling up&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CMD + k&lt;/code&gt; - clears all output from the session, only  previously called commands are retained&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CTRL + c&lt;/code&gt; - Aborts the current running process and closes it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CTRL + z&lt;/code&gt; - Pauses (&lt;code&gt;SIGSTP&lt;/code&gt;) any the current running process

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;code&gt;CTRL + C&lt;/code&gt; aborts the process, but &lt;code&gt;CTRL + z&lt;/code&gt; leaves it idling in memory.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CTRL + a&lt;/code&gt; - Takes you to the beginning of the bash input&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CTRL + e&lt;/code&gt; - Takes you to the end of the bash input&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CTRL + u&lt;/code&gt; - Clears all input &lt;em&gt;before&lt;/em&gt; the cursor&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CTRL + r&lt;/code&gt; - Opens a prompt that will search the previous commands from your session&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Learning how to navigate the terminal is definitely daunting at first, but after spending some time scripting you'll find that these commands can save you tons of time on a day to day tasks that you do.&lt;/p&gt;

&lt;p&gt;Personally, I'm starting to reach the point where I navigate faster via Terminal than when I use Finder.&lt;/p&gt;

&lt;p&gt;If you have any commands, shortcuts, or tips I should add to this post, please leave me a comment! Would love to add more.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>bash</category>
      <category>productivity</category>
      <category>linux</category>
    </item>
    <item>
      <title>A Beginner's Guide: Memoization</title>
      <dc:creator>malik</dc:creator>
      <pubDate>Sat, 28 Jul 2018 19:02:24 +0000</pubDate>
      <link>https://dev.to/milkstarz/a-beginners-guide-memoization-22f0</link>
      <guid>https://dev.to/milkstarz/a-beginners-guide-memoization-22f0</guid>
      <description>&lt;p&gt;This article was originally posted on &lt;a href="https://www.malikbrowne.com/blog" rel="noopener noreferrer"&gt;malikbrowne.com&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Last week, I was browsing different articles for guidance on the new lifecycle methods in React v16.3. I came across &lt;a href="https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html" rel="noopener noreferrer"&gt;this article&lt;/a&gt; that talks about how a lot of developers may be using &lt;code&gt;getDerivedStateFromProps&lt;/code&gt;  wrong.&lt;/p&gt;

&lt;p&gt;If you're not familiar with React, the method simply allows a component to update its internal state, as a result of a change in its props. However, the article recommended to &lt;strong&gt;not&lt;/strong&gt; do something that I would do all the time in my code:&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;getDerivedStateFromProps&lt;/code&gt; or &lt;code&gt;componentWillReceiveProps&lt;/code&gt; to ensure that a component only performs an expensive calculation for a re-render when the inputs change. &lt;/p&gt;

&lt;p&gt;However, an easier and more concise way of performing this can be done with a functional programming technique called &lt;a href="https://en.wikipedia.org/wiki/Memoization" rel="noopener noreferrer"&gt;memoization&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As a growing programmer interested in performance, I love to come across new functional programming techniques that help speed up the code that I write on a day to day basis. Memoization was something that I had heard other engineers talk about in different algorithm problems. However, I never took the time to see what all the hype was all about - mostly because it sounded &lt;em&gt;really&lt;/em&gt; complicated. &lt;/p&gt;

&lt;p&gt;In this post, I'm gonna explain what pure functions are, how memoization works, and how YOU can combine them in React components to make your code more performant. &lt;/p&gt;

&lt;p&gt;Let's start off by talking about &lt;strong&gt;pure functions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gifer.com%2FKQ73.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gifer.com%2FKQ73.gif" alt="let's get started"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a pure function?
&lt;/h3&gt;

&lt;p&gt;By definition, a pure function is a function that meets the following criteria:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It is a function that &lt;strong&gt;always&lt;/strong&gt; returns the same result if the same arguments are passed in.&lt;/li&gt;
&lt;li&gt;It is a function that does not produce any &lt;strong&gt;observable side effects&lt;/strong&gt; to your application including:

&lt;ul&gt;
&lt;li&gt;Network requests&lt;/li&gt;
&lt;li&gt;Data mutation&lt;/li&gt;
&lt;li&gt;Logging to files&lt;/li&gt;
&lt;li&gt;Change application state&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It is a function that only accesses the data you pass into it, making dependencies easy to define.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Something that may help this idea click is an analogy from &lt;a href="https://www.sitepoint.com/functional-programming-pure-functions/" rel="noopener noreferrer"&gt;this article&lt;/a&gt; which compares pure functions to a coffee grinder.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A pure function is like a coffee grinder: beans go in, the powder comes out, end of story.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;p&gt;There are a few benefits to pure functions - two of them being:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They can lead to more declarative programs which describe how different inputs relate to outputs. &lt;/li&gt;
&lt;li&gt;They can increase the testability of your code, and make debugging your code less of a nightmare.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, it's good to note that &lt;strong&gt;side effects, in general, are not bad&lt;/strong&gt; - which means that we don't have to make every single function pure.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example of a pure function
&lt;/h4&gt;

&lt;p&gt;Let's say that we have a recursive function that returns the &lt;a href="https://www.mathsisfun.com/numbers/factorial.html" rel="noopener noreferrer"&gt;factorial of a number&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;factorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// factorial(4)&lt;/span&gt;
&lt;span class="c1"&gt;// 4! === 4 * 3 * 2 * 1 === 24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we pass in &lt;code&gt;factorial(4)&lt;/code&gt;, our calculations would be made and return us the result,  24, &lt;strong&gt;every single time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Since we now know a pure function will return the same value every time, wouldn't it be convenient if our function could remember (or cache) our results? That way the next time someone wants to calculate &lt;code&gt;factorial(100)&lt;/code&gt;, we could save time and resources and just give them the already stored answer.&lt;/p&gt;

&lt;p&gt;That, my friends, is memoization.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is memoization, really?
&lt;/h3&gt;

&lt;p&gt;By definition,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Memoization is an optimization technique used primarily to speed up programs by &lt;strong&gt;storing the results of expensive function calls&lt;/strong&gt; and returning the cached result when the same inputs occur again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In layman's terms, this means the function will memorize the solution to a problem if you give it the same question. To achieve a simple solution of memoization, we can implement some type of cache in the form of a map, which our function could then refer to. &lt;/p&gt;

&lt;p&gt;Here's what our factorial solution would look like with a memoized function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// our original factorial function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;factorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// a memoized function used to calculate our factorial&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scopedMemoizedFactorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fakeCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;fakeCache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// return the value from our fake cache&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fakeCache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// calculate our factorial&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;fakeCache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Things to notice
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;scopedMemoizedFactorial&lt;/code&gt; returns a function which is called later. We can do this in JavaScript because functions are first class objects, which means we can use them as higher order functions and return another function.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;fakeCache&lt;/code&gt; can remember the values because of the closure it's implemented in&lt;/li&gt;
&lt;li&gt;This only works because the function we're working with is pure, like we talked about before. If it didn't return the same value, our cache wouldn't return the right value for the output!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd like to see an example of a general memoized function, check out &lt;a href="https://gist.github.com/dannycallaghan/6897874" rel="noopener noreferrer"&gt;this gist&lt;/a&gt; which shows a memoization pattern from &lt;code&gt;JavaScript Patterns&lt;/code&gt; by Stoyan Stefanov.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Memoization in React
&lt;/h3&gt;

&lt;p&gt;For our example, let's pretend we have a third party API that returns back some JSON about all of the users on our application. The data structure looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Malik&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;company&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Meetup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// ...and a bunch of other fields like this&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// ...and 996 other entries just like this&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you would like to see what the whole data set looks like, check out &lt;a href="http://www.json-generator.com/api/json/get/bVHdtPdtmG?indent=2" rel="noopener noreferrer"&gt;this link&lt;/a&gt;. (Thank you to &lt;a href="https://www.json-generator.com" rel="noopener noreferrer"&gt;JSON Generator&lt;/a&gt; for this!)&lt;/p&gt;

&lt;p&gt;The requirements for our application is to create a search box that will filter through our list of users and return a sorted list of all users whose name matches a query.&lt;/p&gt;

&lt;p&gt;The code without memoization would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PureComponent&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;filterList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="nx"&gt;sortList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;handleInputChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;inputChanged&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputChanged&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredMembers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;members&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sortList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filteredMembers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;Memoization&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Search&lt;/span&gt;
          &lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;onInputChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleInputChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
          &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Search for a member&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;members&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;members&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Member&lt;/span&gt; &lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;          &lt;span class="p"&gt;})}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out the code in action &lt;a href="https://codesandbox.io/embed/ymlk2mmq39?module=%2Fsrc%2Fno-memoize.js&amp;amp;moduleview=1" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This solution will work perfectly fine in most situations, but with large sets of data  the application will slow down a lot. &lt;/p&gt;

&lt;p&gt;This happens for two reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filtering large sets of data is an expensive operation&lt;/li&gt;
&lt;li&gt;Other re-renders of the application will cause the function to call the expensive operation again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the helper &lt;code&gt;memoize-one&lt;/code&gt; we can easily add memoization to this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;memoize&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;memoize-one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PureComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;filterList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memoize&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;sortList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memoize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;handleInputChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredMembers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;members&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sortList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filteredMembers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;With&lt;/span&gt; &lt;span class="nx"&gt;Memoization&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Search&lt;/span&gt;
          &lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;onInputChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleInputChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
          &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Search for a member&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;members&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;members&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Member&lt;/span&gt; &lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;          &lt;span class="p"&gt;})}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;memoize-one&lt;/code&gt; is great because it only stores the results of the &lt;em&gt;last&lt;/em&gt; function call, so you don't have to worry about &lt;a href="https://www.keycdn.com/support/what-is-cache-busting/" rel="noopener noreferrer"&gt;cache busting issues&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Important notes for performance
&lt;/h3&gt;

&lt;p&gt;The idea of memoization is great and all, but keep in mind the main benefit of memoization: to store the results of &lt;strong&gt;expensive&lt;/strong&gt; function calls. &lt;/p&gt;

&lt;p&gt;I took our factorial solution and used the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance/now" rel="noopener noreferrer"&gt;Performance Timeline API&lt;/a&gt; to time how long our function calls took (down to the microsecond):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// we use performance.now() to keep track of how long each call takes&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;optimizedFactorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// calculated&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`The first call took &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;t0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// The first call took 0.3999999971711077ms.&lt;/span&gt;

&lt;span class="nf"&gt;optimizedFactorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// cached&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Our memoized call took &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Our memoized call took 2.2000000026309863ms.&lt;/span&gt;

&lt;span class="nf"&gt;optimizedFactorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4999&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// calculated again with different param&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`A call that wasn't stored in our cache took &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;t3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// A call that wasn't stored in our cache took 0.3999999971711077ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, on my computer the memoized call took &lt;strong&gt;over five times longer&lt;/strong&gt; to get the same result. This is because, in order for our memoization technique to work, the computer needs to allocate memory for a new variable and instantiate it, which takes a chunk of time respectively before it can perform the calculation.&lt;/p&gt;

&lt;p&gt;As a result, we can see that using the memoize technique in this solution would be a premature optimization -  and would &lt;strong&gt;negatively&lt;/strong&gt; impact the performance of our application.&lt;/p&gt;

&lt;p&gt;Another thing to note is that this solution doesn't handle many pains in relation to "busting" a cache including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting a max age or size &lt;/li&gt;
&lt;li&gt;Exclusions for our cache &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of these pains can lead to memory leaks in our application, which can be a nightmare to debug. Because of this, a lot of engineers tend to use memoization helpers which have already implemented solutions to the pains to handle those common issues. Some of these include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/alexreardon/memoize-one" rel="noopener noreferrer"&gt;memoize-one&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lodash/lodash/blob/master/memoize.js" rel="noopener noreferrer"&gt;Lodash's memoize function&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In regards to memoization in React, this &lt;a href="https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization" rel="noopener noreferrer"&gt;React blog post&lt;/a&gt; covers some of the main constraints. Since they used a similar example, I'll share them below:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt; In most cases, you’ll want to  &lt;strong&gt;attach the memoized function to a component instance&lt;/strong&gt;. This prevents multiple instances of a component from resetting each other’s memoized keys.&lt;/li&gt;
&lt;li&gt; You will also want to use a memoization helper with a  &lt;strong&gt;limited cache size&lt;/strong&gt;  in order to prevent memory leaks over time.&lt;/li&gt;
&lt;li&gt; None of the implementations shown in this section will work if  &lt;code&gt;props.members&lt;/code&gt;  is recreated each time the parent component renders. But in most cases, this setup is appropriate.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Memoization is an awesome technique, that if used correctly, can supercharge your applications. Using more functional programming techniques can lead to easier and more predictable code, with high testability. &lt;/p&gt;

&lt;p&gt;I highly recommend trying out memoization in one of your application via a package called &lt;a href="https://github.com/alexreardon/memoize-one" rel="noopener noreferrer"&gt;memoize-one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any questions about any of the concepts in this article, feel free to leave a question in the comments!&lt;/p&gt;

&lt;p&gt;I'm always open to hearing from people in the dev community, so feel free to reach out to me on  &lt;a href="https://twitter.com/milkstarz" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; as well. Tell me your opinion on using memoization for performance!&lt;/p&gt;

&lt;p&gt;See you in the next one.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tech</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Contentful and Netlify: The Dynamic Duo of Static Site Management</title>
      <dc:creator>malik</dc:creator>
      <pubDate>Thu, 16 Nov 2017 16:33:29 +0000</pubDate>
      <link>https://dev.to/milkstarz/contentful-and-netlify-the-dynamic-duo-of-static-site-management-55i</link>
      <guid>https://dev.to/milkstarz/contentful-and-netlify-the-dynamic-duo-of-static-site-management-55i</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YEXQNOZh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/iu14ksqbpu5fr50plw26.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YEXQNOZh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/iu14ksqbpu5fr50plw26.jpg" alt="Welcome!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Earlier this year I had a goal to step up my blogging game.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When it comes to blogging there are tons of platforms available for people to use. A blog could be using a static site generator like &lt;a href="https://jekyllrb.com/"&gt;Jekyll&lt;/a&gt;, or a powerful content management system (CMS) like &lt;a href="https://wordpress.com/"&gt;Wordpress&lt;/a&gt; or &lt;a href="https://www.drupal.org/"&gt;Drupal&lt;/a&gt;. Each of these tools has their own specific process for development.&lt;/p&gt;

&lt;p&gt;Both of these approaches have their own strengths and weaknesses, and whatever solution a blogger chooses will come with its own set of constraints. &lt;/p&gt;

&lt;p&gt;I was partial towards Jekyll, mostly because I didn’t really enjoy writing in PHP if I could help it. &lt;/p&gt;

&lt;p&gt;I also considered writing all of my blog posts on Medium, and then porting it to my blog via &lt;a href="https://github.com/Medium/medium-api-docs"&gt;Medium’s REST API.&lt;/a&gt; However, I wanted to be able to separate my technical writing from my future plans of writing about motivation and productivity.&lt;/p&gt;

&lt;p&gt;After some good ol’ google-fu, I came across a combination of tools that really changed the game for me in an unexpected way: &lt;strong&gt;Contentful and Netlify.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Contentful?
&lt;/h3&gt;

&lt;p&gt;Contentful is a powerful SaaS platform that provides developers and small businesses with a highly configurable CMS that lives independently from the user’s publishing platform.&lt;/p&gt;

&lt;p&gt;I like to think of it as a easily-accessed cloud database for different types of content.&lt;/p&gt;

&lt;p&gt;Using Contentful, a blogger can create models to represent different types of content they may want to include in their blog. I like to think of these models as &lt;strong&gt;entities&lt;/strong&gt; which then have &lt;strong&gt;attributes&lt;/strong&gt; that describe them.&lt;/p&gt;

&lt;p&gt;As an aside, if you’re not familiar with the idea of entities and attributes in database design, I highly recommend you check out &lt;a href="https://www.youtube.com/watch?v=QpdhBUYk7Kk"&gt;this video that covers how you can make visual models to describe a database&lt;/a&gt;. Modeling is an awesome tool for orienting your thoughts about a project before you’re first getting started.&lt;/p&gt;

&lt;p&gt;Let’s dive into an example of a Contentful model.&lt;/p&gt;

&lt;p&gt;In my opinion, a simple blog post can be broken down into several attributes. If you think about it, the main attributes are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A blog title&lt;/li&gt;
&lt;li&gt;Slug (unique path to the content)&lt;/li&gt;
&lt;li&gt;Author of the post&lt;/li&gt;
&lt;li&gt;Category&lt;/li&gt;
&lt;li&gt;Post body (your content)&lt;/li&gt;
&lt;li&gt;A featured image (an optional image that can be shown to readers as they scroll throw your posts)&lt;/li&gt;
&lt;li&gt;Post published date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you put all of these together, you have a basic skeleton of a blog post already done, without worrying about styling or formatting.&lt;/p&gt;

&lt;p&gt;Here is an example of a model on Contentful. I use this as my standard scaffold for posts on my blog:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8_GDtqM1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/T54EKTj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8_GDtqM1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/T54EKTj.png" alt="blog model"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Awesome features of Contentful
&lt;/h3&gt;

&lt;p&gt;When I first got started with Contentful, there were two features when describing a model that I found particularly useful:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dynamic field entries&lt;/li&gt;
&lt;li&gt;Field validation based on customizable criteria&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Dynamic Fields
&lt;/h4&gt;

&lt;p&gt;A good example of a dynamic field is the slug (the path to the specific post). For SEO purposes, it’s a best practice to put hyphens in between the words in your slug, because when you use spaces, it is encoded as “%20”.&lt;/p&gt;

&lt;p&gt;This is because Google and other search engines only treat hyphens as word separators, and ignores alternatives like underscores and spaces. &lt;br&gt;
If you’re interested in a little bit of history into why this became a standard, &lt;a href="https://www.youtube.com/watch?v=AQcSFsQyct8"&gt;check out this video by Google's Matt Cutt on the topic.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For an example, let’s use spaces inside of our slug. When the browser encodes the URL, the result will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://malikbrowne.com/blog/contentful%20and%20netlify%20the%20dynamic%20static%20site%20duo"&gt;https://malikbrowne.com/blog/contentful%20and%20netlify%20the%20dynamic%20static%20site%20duo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yuck.&lt;/p&gt;

&lt;p&gt;The whole idea behind SEO is to make your content readable. Let’s take a look at another example with dashes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://malikbrowne.com/blog/contentful-and-netlify-the-dynamic-static-site-duo"&gt;https://malikbrowne.com/blog/contentful-and-netlify-the-dynamic-static-site-duo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is much easier to read. It’s a minor difference in ranking, but there definitely is a difference.&lt;/p&gt;

&lt;p&gt;As a convenience, Contentful will automatically convert your title into a properly formatted slug if you set the option “slug”.&lt;/p&gt;

&lt;p&gt;Contentful also allows you to create new instances of each model you define. These individual units of a model are then considered the “content” itself by the CMS.&lt;/p&gt;

&lt;h4&gt;
  
  
  Field Validation
&lt;/h4&gt;

&lt;p&gt;In a blog, you can’t really have a post without a body or title. Those can be set as required fields so that Contentful won’t publish a post unless they are filled.&lt;/p&gt;

&lt;p&gt;Out of all the validation features they have, the one I use the most is image requirements. When working with multiple people on a piece of content, requirements can easily get lost in the mix, and if you’re not careful, bad images could break the layout and functionality of your site.&lt;/p&gt;

&lt;p&gt;For example, to optimize loading times you may want to limit the file size of an image that someone sets as the featured image of a blog post, since Contentful doesn’t compress your images for you.&lt;/p&gt;

&lt;p&gt;Contentful allows you to set multiple different image parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image file size&lt;/li&gt;
&lt;li&gt;Image proportions (width and height)&lt;/li&gt;
&lt;li&gt;Type of file (jpg, png, gif)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a really useful feature that allows you to have a lot of granular control when working with a group of editors.&lt;/p&gt;

&lt;p&gt;If creating these complex models seems daunting, don’t fret. Contentful has plenty of basic content model templates available to users once they sign up.&lt;/p&gt;

&lt;p&gt;On top of that, Contentful allows you to create up to 10,000 new content records in their system for &lt;strong&gt;free.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/J8yfTm3pxSMlG/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/J8yfTm3pxSMlG/giphy.gif" alt="Talk about a free trial,"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Talk about a free trial.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After you or a collaborator has filled out the content of a post and hits that green publish button, Contentful will make your content accessible via a convenient REST API.&lt;/p&gt;

&lt;p&gt;This allows developers to query and manipulate all of the available &lt;strong&gt;models&lt;/strong&gt;, &lt;strong&gt;assets&lt;/strong&gt;, and &lt;strong&gt;content data&lt;/strong&gt; that you provide.&lt;/p&gt;

&lt;p&gt;Contentful also stores metadata about of your models, provides parameters for filtering your blog to allow pagination, and provides you with a basic markdown editor to write your blog posts if you don’t have a setup already.&lt;/p&gt;

&lt;p&gt;(I personally use this application called &lt;a href="https://typora.io"&gt;Typora&lt;/a&gt;, it’s increased my productivity when writing Markdown by a ton.)&lt;/p&gt;

&lt;p&gt;Markdown can be easily parsed down into HTML using &lt;a href="http://lmgtfy.com/?q=markdown+to+html+converter"&gt;a whole bunch of tools on the internet.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions about the static site generators or either service, I'm more than happy to answer questions in the comments, or continue the conversation on &lt;a href="https://twitter.com/milkstarz"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After writing your posts, you can pull the information you need either through the previously mentioned REST API, or Contentful’s SDK.&lt;/p&gt;

&lt;p&gt;The next issue you would need to think about is deployment.&lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;Netlify&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Netlify?
&lt;/h3&gt;

&lt;p&gt;Netlify is an automation platform that focuses on providing the easiest flow for managing deployments, covering everything from continuous integration to CDN distribution and caching.&lt;/p&gt;

&lt;p&gt;Some of my favorite features that Netlify offers are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A global CDN that distributes your content across the globe&lt;/li&gt;
&lt;li&gt;A fast native DNS service&lt;/li&gt;
&lt;li&gt;Automatic deployments, bundled with one click rollbacks&lt;/li&gt;
&lt;li&gt;Build automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.netlify.com/features/"&gt;You can check out a list of all the awesome features that Netlify provides here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Netlify makes the process extremely simple — you only have to &lt;strong&gt;push your code to Github.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When Netlify detects a change in your linked git repository, it will start the deployment by checking your package.json file in your Github repo for any build scripts. You can also specify which build script Netlify runs.&lt;/p&gt;

&lt;p&gt;Another thing to note is that Netlify scales with your website, no matter how big it gets. Also, just like AWS you only pay for what you use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use Netlify and Contentful together?
&lt;/h3&gt;

&lt;p&gt;When I first created my blog, I was deploying my website manually, using &lt;a href="https://github.com/geelen/react-snapshot"&gt;react-snapshot&lt;/a&gt; to create the newly rendered HTML files (for SEO purposes), and dragging these production-ready files onto my FTP server.&lt;/p&gt;

&lt;p&gt;Whenever I wanted to make CSS changes after testing on other devices, I had to rebuild my create-react-app project and then re-run react-snapshot every single time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let me tell you something: that got old. FAST.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/E7iIfUlWHBmh2/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/E7iIfUlWHBmh2/giphy.gif" alt="seriously."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is where web hooks came in.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you’re not familiar with webhooks, a webhook is a way for an application to provide other applications with real-time information. A webhook delivers data to other applications as it happens, which means you get data immediately.&lt;/p&gt;

&lt;p&gt;In a normal API, you need to make a network request frequently to simulate real-time data. This is very inefficient, and is the reason why webhooks are growing in popularity.&lt;/p&gt;

&lt;p&gt;Contentful allows you to set a webhook that gets called based on different actions a user can do in their application.&lt;br&gt;
These actions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating or updating a new asset, entry, or content type&lt;/li&gt;
&lt;li&gt;Publishing or unpublishing an asset, entry, or content type&lt;/li&gt;
&lt;li&gt;Deleting an asset, entry, or content type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When any of these actions occur, Contentful will send out a request to a specific URL, telling all listeners that data has been changed.&lt;/p&gt;

&lt;p&gt;Netlify can listen to this webhook, and trigger a build command when it receives a network request for this URL.&lt;/p&gt;

&lt;p&gt;These are my personal webhook settings in Contentful:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Pk3CPLRg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/JNOaU1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Pk3CPLRg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/JNOaU1j.png" alt="webhook settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the help of Netlify and these webhooks in Contentful, everything that I had to do manually before is now done with a “git push” command, and the push of a button on Contentful.&lt;/p&gt;

&lt;p&gt;I have also switched over to GatsbyJS, which does several things for me that I had to do manually before. This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Providing a nice templating system for my blog posts&lt;/li&gt;
&lt;li&gt;Creating a sitemap for search engines&lt;/li&gt;
&lt;li&gt;Providing new HTML pages for ones that didn’t exist previously&lt;/li&gt;
&lt;li&gt;Optimizing images on my website.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Powerful, helpful, and super intuitive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools to use with Contentful and Netlify
&lt;/h3&gt;

&lt;p&gt;There are tons of static site generators out there. But a real pain point that I faced when working with other development environments was that adding functionality was an extremely daunting process.&lt;/p&gt;

&lt;p&gt;Most of the time, the solutions were either unidiomatic or unintuitive.&lt;/p&gt;

&lt;p&gt;After doing some more research into the JAMstack, I came across these two projects that stood out to me as great tools for optimal server-side rendering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gatsbyjs.org/"&gt;Gatsby.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zeit/next.js/"&gt;Next.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of these tools are compatible with React out of the box, which gives your static site the potential to have the same functionality as a complex web application.&lt;/p&gt;

&lt;p&gt;If you’re a developer and you’re looking to create a new blog, I highly recommend using these tools together with one of the static site generators I mentioned.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading :) If you liked this post, please let me know in the comments below. It'll let me know if I should write more articles like this on dev.to!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="https://www.malikbrowne.com/blog/contentful-and-netlify-the-dynamic-duo"&gt;malikbrowne.com&lt;/a&gt;. You can find more articles like this on my website!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;*I’m always interested in hearing from people in the dev community, so feel free&lt;br&gt;
to say hello to me on &lt;a href="https://twitter.com/milkstarz"&gt;Twitter&lt;/a&gt;. Tell me your opinion on the JAMstack!&lt;/p&gt;

</description>
      <category>tech</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Three Job Sites for Finding Your Next Developer Job</title>
      <dc:creator>malik</dc:creator>
      <pubDate>Wed, 25 Oct 2017 19:55:42 +0000</pubDate>
      <link>https://dev.to/milkstarz/three-job-sites-for-finding-your-next-developer-job-49e</link>
      <guid>https://dev.to/milkstarz/three-job-sites-for-finding-your-next-developer-job-49e</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqe6chu128lp64ca64ufv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqe6chu128lp64ca64ufv.jpg" alt="welcome!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whether you’re looking for your next gig, or you’re trying to break into the industry, you can’t deny that tech hiring situation is &lt;strong&gt;frustratingly difficult.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you’re just starting your job search, let me give you a recent example of when I was trying to &lt;em&gt;“break into the industry”.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For a little background, I don’t have a previous history in Computer Science and learned most of my skills through various online resources.&lt;/p&gt;




&lt;p&gt;A little over a year ago, I had recently graduated college, and was starting down the job application grind. I remember working through applications on Indeed, Monster, and Dice – altering my resume and cover letter specifically for each company.&lt;/p&gt;

&lt;p&gt;I did tons of research on each company I applied to, and made sure to give my due diligence and make sure I was a good fit for each position.&lt;/p&gt;

&lt;p&gt;(&lt;em&gt;You know, just like everyone says.&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Doing hard work doesn’t bother me as long as there is some sort of result, but the nail in the coffin is when you get back that &lt;strong&gt;generic rejection email:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Dear [candidate] Thanks for taking the time to meet with our team about the&lt;br&gt;
[role title] at [company name]!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It was nice to read about your skills and accomplishments.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unfortunately our team did not select you for further consideration. We will&lt;br&gt;
keep your resume on file for future openings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Regards,&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;[recruiter]&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I even once received an email from a recruiter where they didn’t even bother changing out the template and &lt;strong&gt;left the fields in the email…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/10BCjQLluBeWly/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/10BCjQLluBeWly/giphy.gif" alt="INTERNAL SCREAMING"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Kill me.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are several startups that are trying to fix that exact problem. Here are three other companies that are trying to fix the tech hiring problem!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Please note that these are in no specific order, this is just the order that I found out about them!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://triplebyte.com/" rel="noopener noreferrer"&gt;Triplebyte&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; Employers and &lt;em&gt;engineers of all skill levels&lt;/em&gt; are matched with companies. You take a quiz, then do a two-hour interview. Based on performance, you’re put on their marketplace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My experience:&lt;/strong&gt; Was very close to making it to the next stage, the interviewer was very friendly and made the interview process very simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rating:&lt;/strong&gt; &lt;strong&gt;9/10&lt;/strong&gt; – Although I didn’t make it, Triplebyte’s process feels like what recruitment should be. Very helpful feedback as well. I’ll get more into details later.&lt;/p&gt;

&lt;p&gt;The first job site on the chopping block is Triplebyte, a company founded on the belief that the current technical hiring process doesn’t do enough to help engineers show their strengths. &lt;/p&gt;

&lt;p&gt;Their goal is to help people find great jobs by assessing their abilities without relying on things like the “years of experience” on their resume.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://triplebyte.com/manifesto" rel="noopener noreferrer"&gt;They actually have a whole manifesto on their view of hiring.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With support from some of the best angel investors in the tech startup scene, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drew Houston the CEO of Dropbox&lt;/li&gt;
&lt;li&gt;Sam Altman: President at YCombinator&lt;/li&gt;
&lt;li&gt;Paul Graham, the co-founder of YCombinator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Triplebyte has managed to make a pretty big disruption in the tech recruiting space.&lt;/p&gt;

&lt;h3&gt;
  
  
  Things I like
&lt;/h3&gt;

&lt;p&gt;Here’s how their process is different and why I highly recommend them for recent to 1-year grads:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; They want to see what you do, and what you’re good at.&lt;/li&gt;
&lt;li&gt; You get PERSONALIZED feedback and are encouraged to reapply every 4 months if
rejected.&lt;/li&gt;
&lt;li&gt; They take your feedback seriously and iterate on suggestions to improve the
platform&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I went through their process six months ago, so here’s a sum of their steps:&lt;/p&gt;

&lt;h4&gt;
  
  
  You take a quiz depending on what your interests are: front end, back end, dev ops, software engineering generalist
&lt;/h4&gt;

&lt;p&gt;They have several different “paths” that you can take, and the questions are all related to that “path.” Naturally, I chose the front end path where I received a bunch of questions covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML and CSS&lt;/li&gt;
&lt;li&gt;JavaScript concepts like hoisting and the &lt;em&gt;this&lt;/em&gt; keyword&lt;/li&gt;
&lt;li&gt;ReactJS core concepts and principles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you do well, you go on to the next step:&lt;/p&gt;

&lt;h4&gt;
  
  
  Get called to set up a two-hour interview where they go over several different topics
&lt;/h4&gt;

&lt;p&gt;This is a very in-depth interview, where the first hour is spent doing a coding challenge, and the second hour is spent answering a bunch of technical questions about web development in general. For my coding challenge, I had to make a &lt;a href="https://www.google.com/search?q=kanban+board&amp;amp;rlz=1C1CHBF_enUS720US720&amp;amp;oq=kanban+board&amp;amp;aqs=chrome..69i57j0l5.2903j0j7&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8" rel="noopener noreferrer"&gt;kanban board&lt;/a&gt; based on a set of rules and restrictions they gave me.&lt;/p&gt;

&lt;p&gt;I was still relatively new to React at this point (about four months), so I struggled with this part of the interview, but the interviewer made me feel comfortable about the whole situation.&lt;/p&gt;

&lt;p&gt;The next hour was spent going over several different topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript: HTTP, local caching&lt;/li&gt;
&lt;li&gt;CSS: CSS sprites, difference between classes and IDs, CSS specificity rules,
building a responsive site&lt;/li&gt;
&lt;li&gt;Security: Bloom Filters, XSS, CSRF&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I felt I did a lot better on this section, as I read blog posts on a bunch of these topics. After a few days, although I got rejected, I got probably the most detailed feedback from an interview I had ever gotten. Here’s the feedback they gave me, maybe it will help you prepare for an upcoming interview:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Hey Malik!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unfortunately, we’re not going to move forward with your application right now. Interviewing is a messy process, and we know that we’ll inevitably make mistakes as we iron out our process. We also believe in giving the people we interview honest feedback.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You talked well about CSS. And you were friendly and we enjoyed talking to you.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here are the areas where we thought you could improve. You didn’t make much progress on the Kanban project. You had a lot of trouble with small-scale coding in Javascript. Your code was occasionally unidiomatic or inelegant. We didn’t see the depth of knowledge that we look for in front end programmers: you didn’t show very deep knowledge of Javascript, HTTP, security, and data structures.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;To move forward with candidates who don’t have much industry experience, we need to see exceptional strength. You did well in many parts of the interview, but we didn’t see the exceptional strength in an area that we require.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here’s our advice.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You’ll do better in front-end focused interviews if you’re more productive at quickly implementing front-end features. You already know how to do this, but practicing it more will help you get faster and better at it. It makes sense to both practice building out small apps (so that you’re comfortable with how the basics of your framework works) and also try building out more complicated features.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Practicing small scale programming will be useful. On several occasions in the programming problem, you got stuck on minor programming bugs that aren’t directly related to front end development. To get better at this, you could try practicing small problems from sources like LeetCode. It’s particularly useful to read how other people solved particular problems after you solve them – often other people spotted cool solutions that you didn’t think of. This kind of practice is useful for your programming in general and particularly useful in the context of interviews.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We recommend you study algorithms more deeply. If you want to study algorithms some more, The Algorithm Design Manual is a particularly good and practically oriented algorithms textbook, and it’s freely available on the internet. Reading the third chapter, which is about how to think about data structures, would be really helpful. There are also many algorithms MOOCs: doing one of these would be good practice. You also might enjoy the advice about studying algorithms on *&lt;a href="https://teachyourselfcs.com/#algorithms" rel="noopener noreferrer"&gt;this page&lt;/a&gt;&lt;/em&gt;. In particular, you should know the runtimes for all the methods on the collections classes available in your language.*&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And again, we know this isn’t a perfect process and we’d love to hear your honest feedback on how we might have improved it. We’re also happy to hear any other questions you have.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Best,&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Triplebyte Team&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Fkmgse8OMKn9C/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Fkmgse8OMKn9C/giphy.gif" alt="It's beautiful."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's... it's beautiful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Things I don’t like
&lt;/h3&gt;

&lt;p&gt;There wasn’t much to dislike. The only thing that was mildly displeasing was that the two hour interview was a bit long for my taste, but I know several people that didn’t really mind.&lt;/p&gt;

&lt;p&gt;There’s not much more you could ask for an interview. If all of the above sounds even slightly interesting to you, &lt;a href="https://triplebyte.com/iv/VSuuESo/cp" rel="noopener noreferrer"&gt;definitely give it a try.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Up next, we have a company you may have heard of already, Hired.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://hired.com/" rel="noopener noreferrer"&gt;Hired&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; &lt;strong&gt;Experienced engineers&lt;/strong&gt; are matched with companies. There are “auctions”, and employers bid on you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My experience:&lt;/strong&gt; Didn’t make it to the auction stage, but I have friends with more experience that have gone through it, and received a few on-site interviews&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rating:&lt;/strong&gt; &lt;strong&gt;8/10&lt;/strong&gt; – They have a few things I don’t like, I’ll go over them below.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Please note that they’re not the best platform for inexperienced engineers!&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Hired is an opportunity network that &lt;em&gt;intelligently matches&lt;/em&gt; experienced engineers to fulltime and contract opportunities at innovative companies. &lt;/p&gt;

&lt;p&gt;Located in San Francisco, they have matched tons of engineers with new and exciting companies and opportunities. Since 2012, they have expanded to a bunch of different locations including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Los Angeles&lt;/li&gt;
&lt;li&gt;San Diego&lt;/li&gt;
&lt;li&gt;Seattle&lt;/li&gt;
&lt;li&gt;Denver&lt;/li&gt;
&lt;li&gt;Austin&lt;/li&gt;
&lt;li&gt;Chicago&lt;/li&gt;
&lt;li&gt;New York &lt;strong&gt;(represent!)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Boston&lt;/li&gt;
&lt;li&gt;Washington D.C.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They also plan to expand &lt;em&gt;internationally&lt;/em&gt;, placing candidates in a bunch of other locations like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paris&lt;/li&gt;
&lt;li&gt;London&lt;/li&gt;
&lt;li&gt;Sydney, Australia&lt;/li&gt;
&lt;li&gt;Melbourne, Australia&lt;/li&gt;
&lt;li&gt;Toronto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So basically, &lt;strong&gt;tons of options&lt;/strong&gt; – especially if you’re looking to relocate.&lt;/p&gt;

&lt;p&gt;Their timeline can take up to seven days to get you approved.&lt;/p&gt;

&lt;p&gt;The way it works is you create a profile that gives a strong outline of your career experience and your skill set. (Make sure you’re specific with that!)&lt;br&gt;
Once you’ve done that Hired will review your profile, and if you are accepted they will place you in their “marketplace.”&lt;/p&gt;

&lt;p&gt;Since I haven’t made it past the auction phase, you can &lt;a href="http://rebootjeff.github.io/blog/2014/06/28/dev-job-search-tools-part-1/#hired" rel="noopener noreferrer"&gt;check out this blog post&lt;/a&gt; for a more detailed description of what it’s like.&lt;/p&gt;

&lt;h3&gt;
  
  
  Things I like:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; Companies that are interested in you are &lt;strong&gt;really interested in you.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Salary offers are amazing, ranging from $100k – $125k&lt;/li&gt;
&lt;li&gt; If you get hired, you get a bonus (who doesn’t like money?)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Things I don’t like:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; They don’t give a good reason to why you are rejected. No feedback can suck if
you’re not sure how you could do better.&lt;/li&gt;
&lt;li&gt; Some of the companies are kind of boring and try to low ball you.&lt;/li&gt;
&lt;li&gt; You’re still assigned a “recruiter”, who manages all your interviews
accordingly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’re a developer with at least a year or two under your belt, &lt;a href="https://hired.com/x/1as89" rel="noopener noreferrer"&gt;you should definitely try out Hired.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last but not least, we have a service available from a company that everyone applying for tech jobs knows, but didn’t know the service existed: Indeed Prime.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.indeed.com/prime" rel="noopener noreferrer"&gt;Indeed Prime&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; Engineers are matched with companies. You fill out a profile, and if your skill set matches, they go straight into a phone screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My experience:&lt;/strong&gt; Didn’t make it to the auction stage, but I have friends with more experience that have gone through it, and received a few on-site interviews&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rating:&lt;/strong&gt; &lt;strong&gt;7/10&lt;/strong&gt; – Better than spam applying for jobs, but I like the effort the other alternatives give.&lt;/p&gt;

&lt;p&gt;I’m sure everyone has &lt;a href="https://www.youtube.com/watch?v=bcJ78-z6_0U" rel="noopener noreferrer"&gt;heard of Indeed.&lt;/a&gt; If you don’t, you really need to** crawl out from under the digital rock you’re stuck under**.&lt;/p&gt;

&lt;p&gt;Indeed is currently the world’s #1 job site with over &lt;strong&gt;200 million&lt;/strong&gt; unique visitors every month from over &lt;strong&gt;60 different countries&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But for some reason, a lot of people I meet haven’t heard of Indeed’s free job matching service, Indeed Prime.&lt;/p&gt;

&lt;p&gt;Just like Hired, Indeed Prime allows you to fill out a profile, and submit it to be reviewed. After about 2–3 days, Indeed will get back to you letting you know whether you have been accepted or not. (I heard back in less than 24 hours so they’re very responsive!)&lt;/p&gt;

&lt;p&gt;An awesome part about this is that if you already have an Indeed account, you can use that prefilled information on your prime account, taking some time out of the process.&lt;/p&gt;

&lt;p&gt;After a week of your profile being approved, your prime profile will be live to potential employers! The response time from these companies are really fast, I was able to reach the technical interview stage with multiple companies in the span of the first three to four days.&lt;/p&gt;

&lt;p&gt;Overall, the process is pretty straightforward. Since the companies are picking you, and you have to be approved to make it into the candidate pool, you already know that there is initial interest.&lt;/p&gt;

&lt;p&gt;Indeed Prime is simple and straightforward, and definitely worth giving a shot. If you’re interested in upping your Indeed game, &lt;a href="https://prime.indeed.com/refer/c-kBCWrSW" rel="noopener noreferrer"&gt;you should try it out!&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;There are a whole bunch of other resources that are available like &lt;strong&gt;Vettery&lt;/strong&gt;, &lt;strong&gt;underdog.io,&lt;/strong&gt; or &lt;strong&gt;WhiteTruffle&lt;/strong&gt;. However, from my time interviewing for jobs, the aforementioned services really stood out to me as awesome, and all shared a common goal.&lt;/p&gt;

&lt;p&gt;If you’ve applied through one of these services before, please share a comment below! I’d love to hear about different people’s experiences with these platforms.&lt;/p&gt;

&lt;p&gt;In my next blog post, I plan to talk about using LinkedIn and AngelList to find more jobs that you’d be interested in.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading :) If you liked this post, please let me know in the comments below. It'll let me know if I should continue this series on dev.to!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="https://www.malikbrowne.com/blog/three-job-sites-for-finding-your-next-developer-job" rel="noopener noreferrer"&gt;malikbrowne.com&lt;/a&gt;. You can find more articles like this on my website!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I’m always interested in hearing from people in the dev community, so feel free&lt;br&gt;
to say hello to me on &lt;a href="https://twitter.com/milkstarz" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. Tell me how your job hunt is going!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tech</category>
      <category>interview</category>
      <category>jobhunting</category>
      <category>hiring</category>
    </item>
  </channel>
</rss>
