<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[chriscolborne.com]]></title><description><![CDATA[An Aussie software engineer, talking tech and more.]]></description><link>https://chriscolborne.com</link><generator>GatsbyJS</generator><lastBuildDate>Thu, 09 Oct 2025 03:23:02 GMT</lastBuildDate><item><title><![CDATA[Don't use method syntax for your TypeScript function types!]]></title><description><![CDATA[In TypeScript, there are a few ways to type functions. But did you know that using the method syntax to define your functions in TypeScript…]]></description><link>https://chriscolborne.com/dont-use-method-syntax-typescript-function-types/</link><guid isPermaLink="false">https://chriscolborne.com/dont-use-method-syntax-typescript-function-types/</guid><pubDate>Thu, 31 Mar 2022 10:43:29 GMT</pubDate><content:encoded>&lt;p&gt;In TypeScript, there are a few ways to type functions. But did you know that using the method syntax to define your functions in TypeScript is not type safe?&lt;/p&gt;&lt;h2&gt;Typing Functions&lt;/h2&gt;&lt;p&gt;There are three main ways you can type a function in TypeScript.&lt;/p&gt;&lt;h3&gt;1. Function type expression syntax&lt;/h3&gt;&lt;p&gt;The most common and recommended way is to type it as a function type expression, which uses a syntax like an arrow function:&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;ts&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;MyObj&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (a&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, b&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;2. Call signature syntax&lt;/h3&gt;&lt;p&gt;Another less common way is as a call signature. This is often useful if the function has properties as well as being callable.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;ts&quot; data-index=&quot;1&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;MyObj&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  add&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    description&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    (a&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, b&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;3. Method syntax&lt;/h3&gt;&lt;p&gt;The final way is method syntax. This often makes sense when talking about classes but is also valid for interfaces.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;ts&quot; data-index=&quot;2&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;MyCalculator&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(a&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, b&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;MyObj&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(a&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, b&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But did you know if you use the method signature syntax (#3 above), it’s actually not completely typesafe.&lt;/p&gt;&lt;h2&gt;strictFunctionTypes flag in TSConfig&lt;/h2&gt;&lt;p&gt;The &lt;a href=&quot;https://www.typescriptlang.org/tsconfig#strictFunctionTypes&quot;&gt;&lt;code&gt;strictFunctionTypes&lt;/code&gt; flag in TSConfig&lt;/a&gt;, when enabled (as it is with &lt;code&gt;strict: true&lt;/code&gt;), causes functions parameters to be checked more correctly.&lt;/p&gt;&lt;p&gt;However &lt;a href=&quot;https://www.typescriptlang.org/tsconfig#strictFunctionTypes&quot;&gt;from the docs&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;During development of this feature, we discovered a large number of inherently unsafe class hierarchies, including some in the DOM. Because of this, the setting only applies to functions written in function syntax, not to those in method syntax.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;That means, if you type your function with the method syntax, &lt;code&gt;strictFunctionTypes&lt;/code&gt; does not apply! 🙀&lt;/p&gt;&lt;p&gt;Let’s see an example.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;ts&quot; data-index=&quot;3&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;PrintMethod&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(a&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;PrintFunction&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (a&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;PrintCall&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  print&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    (a&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;printFunc&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (a&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;hello&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;MyAddingMethod&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;PrintMethod&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  print: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;printFunc&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// uh oh - this isn&amp;#x27;t flagged as an error&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;MyAddingFunction&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;PrintFunction&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  print: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;printFunc&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// this is correctly flagged&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;MyAddingCall&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;PrintCall&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  print: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;printFunc&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// this is correctly flagged&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgApVGAshMALAewBNkBvAWAChlkAHDcACjgC5kBnMBgc2QB9kIAK4BbAEbQAlG048A3FQC+VKpmjwkaBmACCUKAQDuZKjXqY2zGV1C8Bw8VOQBeAHwcbIbgsrLKq8HVEFHRMAGE4ABtIk2o6bTYKOJorDx5+QVEJKGk021NkPz8qBAIQTnjMADEhEAQXZFTZW0kXdwByPAhognafErKKrABPHSIiWxx8YjZQ8CnCEmdYmkrwNnNwGrrkAHpd5CE8ZAJjgFpkfGB2ZGuQdrBkGEi4bm4IEjgbuBBkaAMoEoVJRSuVHiMxhMvHoDIZZtoYUYGklVpswBttNt6vtLnhrrcbqV9BAEGBIsMni83h8gf4QYNwaNxrYItF4eEojFliizAk1mAsXsDlcbviiVASWSKc9Xu8iEogA&quot;&gt;TypeScript Playground&lt;/a&gt;&lt;/p&gt;&lt;p&gt;It’s not all bad news - it &lt;em&gt;will&lt;/em&gt; correctly catch it if the type changes completely, for instance from a `string` to a `number`, however I’d argue that that makes it even more insidious, sometimes it catches it, sometimes it doesn’t.&lt;/p&gt;&lt;h2&gt;What should you use?&lt;/h2&gt;&lt;p&gt;Long story short, you should avoid using the method syntax (even for classes) when typing your functions in TypeScript. Use the function syntax (or the call signature if you need the additional properties) and your code will be much type-safer for it!&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtki { font-style: italic; }
  .solarized-dark .mtkb { font-weight: bold; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk4 { color: #CB4B16; }
  .solarized-dark .mtk7 { color: #268BD2; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk12 { color: #2AA198; }
  .solarized-dark .mtk3 { color: #657B83; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[How can I run some code after changing state with React hooks?]]></title><description><![CDATA[Running some code after changing state is a common desire. Let's look at how to do that with hooks. Method 1 - useEffect hook The first and…]]></description><link>https://chriscolborne.com/react-hooks-run-code-after-changing-state/</link><guid isPermaLink="false">https://chriscolborne.com/react-hooks-run-code-after-changing-state/</guid><pubDate>Sat, 05 Dec 2020 14:49:14 GMT</pubDate><content:encoded>&lt;p&gt;Running some code after changing state is a common desire. Let’s look at how to do that with hooks.&lt;/p&gt;&lt;h2&gt;Method 1 - useEffect hook&lt;/h2&gt;&lt;p&gt;The first and most commonly used method to run a function after updating state is the &lt;code&gt;useEffect&lt;/code&gt; hook. &lt;code&gt;useEffect&lt;/code&gt; runs its function only when the items in the dependency array change. Sounds pretty spot on for what we want huh? Let’s see it in action:&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;John Doe&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(() &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// run something every time name changes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}, [&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;]); &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// &amp;lt;-- dependency array&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pretty simple, every time &lt;code&gt;name&lt;/code&gt; changes, we’ll run the function, which &lt;code&gt;console.log&lt;/code&gt;s the name out. &lt;/p&gt;&lt;h2&gt;Method 2 - useReducer hook&lt;/h2&gt;&lt;p&gt;When you find yourself needing more complex state updates, where updating one item of state affects another item of state, you can reach for &lt;code&gt;useReducer&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;What if we had a status, and wanted to save a history of the last 10 statuses? Because the history relies on changes to the status, &lt;code&gt;useReducer&lt;/code&gt; would be a good choice here. Let’s see it in action:&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;1&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CHANGE_STATE&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;CHANGE_STATE&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CLEAR_HISTORY&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;CLEAR_HISTORY&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;reducer&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (state, action) &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;history&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;newStatus&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CHANGE_STATE&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;newHistory&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;history&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;newHistory&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.length &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;newHistory&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { status: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;newStatus&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, history: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;newHistory&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CLEAR_HISTORY&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, history: [] };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;StatusHistory&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; () &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;useReducer&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;reducer&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    status: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;stopped&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    history: []&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; () &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;({ type: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CHANGE_STATE&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, newStatus: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;started&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; () &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;({ type: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CHANGE_STATE&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, newStatus: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;finished&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; () &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;({ type: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CLEAR_HISTORY&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;Current status: &lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;ul&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;history&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;((previousStatus) &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;previousStatus&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ))&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;ul&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; onClick&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;Start it&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; onClick&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;Finish it&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; onClick&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;Clear History&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  );&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hopefully, this has shown you two options for running code after changing state with React hooks.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; - if the state (and code to run) is simple, you can go with &lt;code&gt;useEffect&lt;/code&gt;. If you’ve got multiple items of state that need to be updated based on changes, go with &lt;code&gt;useReducer&lt;/code&gt;. &lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtki { font-style: italic; }
  .solarized-dark .mtkb { font-weight: bold; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk7 { color: #268BD2; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk12 { color: #2AA198; }
  .solarized-dark .mtk3 { color: #657B83; }
  .solarized-dark .mtk6 { color: #D33682; }
  .solarized-dark .mtk15 { color: #D30102; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Object Destructuring 101]]></title><description><![CDATA[aka what on Earth does  doIt({ x: x2 = getX() } = {})  mean?! You're getting used to React. You've got components and arrow functions down…]]></description><link>https://chriscolborne.com/object-destructuring-101/</link><guid isPermaLink="false">https://chriscolborne.com/object-destructuring-101/</guid><pubDate>Sun, 08 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;aka what on Earth does &lt;code&gt;doIt({ x: x2 = getX() } = {})&lt;/code&gt; mean?!&lt;/h2&gt;&lt;p&gt;You’re getting used to React. You’ve got components and arrow functions down pat. But then you run into this beast:&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;doRender&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  ui,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    state: initialState,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    options &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;getOptions&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;({ &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;overrides&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; })&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;) { &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// ... }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Wait, what, how? Brackets and colons and equals, oh my! This little snippet breaks your brain. What was this developer thinking? Were they just being too clever, or what?!&lt;/p&gt;&lt;p&gt;Although it certainly is bracket soup, there &lt;strong&gt;is&lt;/strong&gt; a method to the madness.&lt;/p&gt;&lt;p&gt;This is a few different levels of object destructuring, layered on top of each other, inside a function call. Let’s break it down bit by bit, so that you can read it like a pro.&lt;/p&gt;&lt;h2&gt;Level 1: Basic Destructuring&lt;/h2&gt;&lt;p&gt;First up, let’s start with the basics. Object destructuring is just a way of extracting certain keys directly from an object. It’s used quite heavily in React and other modern JavaScript frameworks. In fact you probably already use it. It looks like this in its basic form.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;1&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  name: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Chris&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  email: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;chris@example.com&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  city: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Brisbane&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// extracts &amp;#x27;Brisbane&amp;#x27; and assigns it to a variable `city`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Easy right? Let’s keep going.&lt;/p&gt;&lt;h2&gt;Level 2: Renaming Destructuring&lt;/h2&gt;&lt;p&gt;So next level, what if we already had a variable &lt;code&gt;city&lt;/code&gt;? Let’s rename it as we extract it:&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;2&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  name: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Chris&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  email: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;chris@example.com&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  city: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Brisbane&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// oops we already have city in scope&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Sydney&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// extracts &amp;#x27;Brisbane&amp;#x27; and assigns it to a variable `myCity`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { city: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myCity&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Two from two, got it.&lt;/p&gt;&lt;h2&gt;Level 3: Multi-Level Destructuring&lt;/h2&gt;&lt;p&gt;Next up let’s tackle multi-level destructuring. That’s when the variable you want to destructure is actually nested inside another key. Let’s try and get at &lt;code&gt;city&lt;/code&gt; and &lt;code&gt;state&lt;/code&gt; in this nested object.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;3&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  name: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Chris&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  email: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;chris@example.com&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  address: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    city: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Brisbane&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    state: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;QLD&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// now city variable is &amp;#x27;Brisbane&amp;#x27; and state variable is &amp;#x27;QLD&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  address: { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;} &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice a trick here - &lt;code&gt;address&lt;/code&gt; isn’t actually destructured, it’s just used to get at its children. If you wanted the full address as well, you could either destructure the address first, then destructure address into city and state, or destructure twice.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;4&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// destructure `address` then `city` from `address`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// destructure `address` itself, then `city` from within it&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  address: { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;} &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Great, we’re starting to look like that initial snippet.&lt;/p&gt;&lt;h2&gt;Level 4: Destructuring Defaults&lt;/h2&gt;&lt;p&gt;Next level is destructuring defaults. Up until now, we’ve been assuming the data is there. But what happens if a particular key &lt;em&gt;might&lt;/em&gt; be there, or &lt;em&gt;might&lt;/em&gt; not? That’s where defaults come into play.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;5&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  name: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Chris&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  email: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;chris@example.com&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// city is missing for this one&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// `city` in this case will be `undefined`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// let&amp;#x27;s add a default&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// now `city` will be &amp;#x27;Sydney&amp;#x27; since it&amp;#x27;s not set in `myObject`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Sydney&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject2&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  city2: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Brisbane&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// but `city2` here will be &amp;#x27;Brisbane&amp;#x27; since it was set in `myObject2`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city2&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Sydney&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject2&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When we try to do multi-level destructuring (or more generally try to destructure something that might be undefined), that’s where we might run into problems. Take this example, we try and get the &lt;code&gt;city&lt;/code&gt; from the &lt;code&gt;address&lt;/code&gt;, but there is no &lt;code&gt;address&lt;/code&gt; in &lt;code&gt;myObject&lt;/code&gt;.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;6&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  name: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Chris&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  email: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;chris@example.com&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// sometimes we have address, but not this time&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// address: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;//   city: &amp;#x27;Brisbane&amp;#x27;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// bah bow - cannot read property &amp;#x27;city&amp;#x27; of undefined&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  address: { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;} &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// so let&amp;#x27;s fix that with a default empty object&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// now we&amp;#x27;re looking for `city` in an empty object,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// which won&amp;#x27;t fail - `city` will be undefined&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// but won&amp;#x27;t blow up&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { address: { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {} } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;myObject&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Full Circle&lt;/h2&gt;&lt;p&gt;So now we’re back to our original brain breaker. We can see now that all we’ve got is some multi-level destructuring with defaults.&lt;/p&gt;&lt;p&gt;Still not convinced? Ok, we’ll step through it bit by bit to make sure it sinks in:&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;7&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// function call&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;doRender&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// first parameter called `ui`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  ui,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// destructure the second parameter&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// extract and rename `state` to variable `initialState`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    state: initialState,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// extract `options` to a variable, and if it&amp;#x27;s unset,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// default to the result of `getOptions()`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    options &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;getOptions&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;({ &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;overrides&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; })&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// finally, default the second parameter to empty object, as it is optional&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;) { &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// ... }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hopefully, this has helped you see that even the most confusing looking destructuring is made up of these 4 levels. Parse them one by one, and you’ll be reading and writing code like this in no time.&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtki { font-style: italic; }
  .solarized-dark .mtkb { font-weight: bold; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk7 { color: #268BD2; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk3 { color: #657B83; }
  .solarized-dark .mtk12 { color: #2AA198; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Which Headless CMS should I use for a new Gatsby site?]]></title><description><![CDATA[Gatsby is an awesome static site generator, but you need to get your data from somewhere. What are your options for headless CMSs? What is…]]></description><link>https://chriscolborne.com/which-headless-cms-for-gatsby/</link><guid isPermaLink="false">https://chriscolborne.com/which-headless-cms-for-gatsby/</guid><pubDate>Sun, 19 Apr 2020 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Gatsby is an awesome static site generator, but you need to get your data from somewhere. What are your options for headless CMSs?&lt;/p&gt;&lt;h2&gt;What is Gatsby?&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.gatsbyjs.org/&quot;&gt;Gatsby&lt;/a&gt; is a free and open source framework based on React that helps developers build blazing fast websites and apps. It basically bashes together React, GraphQL and the so called JAM Stack to make some serious awesomeness.&lt;/p&gt;&lt;h2&gt;What is the JAM Stack?&lt;/h2&gt;&lt;p&gt;The JAM Stack is a name standing for a modern way of building sites/apps with JavaScript, APIs and Markup. Commonly it involves server side generated code from Markdown and/or API endpoints.&lt;/p&gt;&lt;h2&gt;What is a headless CMS?&lt;/h2&gt;&lt;p&gt;In this new JAM Stack world, your CMS backend and your frontend site are split. A headless CMS is simply a CMS which instead of pumping out HTML and CSS views, produces an API. There are many options from open source, to paid SaaS options, to trusty old WordPress.&lt;/p&gt;&lt;h2&gt;What are the options?&lt;/h2&gt;&lt;h3&gt;Open source options&lt;/h3&gt;&lt;h4&gt;&lt;a href=&quot;https://www.netlifycms.org/&quot;&gt;Netlify CMS&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Netlify is one of the most common hosting providers for the JAM stack. They’ve built an open source SPA which you can install as an npm module on your site, to provide a CMS experience over GitHub and Markdown, complete with editorial workflow using pull requests.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.gatsbyjs.org/starters/netlify-templates/gatsby-starter-netlify-cms/&quot;&gt;Try it out&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;&lt;a href=&quot;https://strapi.io/&quot;&gt;Strapi&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Strapi is an open source, self hosted headless CMS written in Node. It provides both REST and GraphQL endpoints, with a customisable admin portal and API.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/strapi/strapi-starter-gatsby-blog&quot;&gt;Try it out&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;&lt;a href=&quot;https://www.keystonejs.com/&quot;&gt;Keystone&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Keystone is a scalable, extensible and open-source platform to build NodeJS applications. It has first-class GraphQL support, and a great Admin UI.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.gatsbyjs.org/docs/third-party-graphql/&quot;&gt;Try it out&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;&lt;a href=&quot;https://www.wordpress.org&quot;&gt;WordPress&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Even though WordPress is obviously a full CMS and blogging platform, it can also be used as a headless CMS by using its &lt;a href=&quot;https://developer.wordpress.org/rest-api/&quot;&gt;REST API&lt;/a&gt; or using the &lt;a href=&quot;https://www.wpgraphql.com/&quot;&gt;WPGraphQL plugin&lt;/a&gt; to provide a GraphQL endpoint. One thing to note is that you may have more or less success depending on how many plugins you use.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.gatsbyjs.org/starters/GatsbyCentral/gatsby-starter-wordpress/&quot;&gt;Try it out&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Software as a Service (SaaS)&lt;/h3&gt;&lt;h4&gt;&lt;a href=&quot;https://sanity.io/&quot;&gt;Sanity&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Sanity is one of the new breed of SaaS headless CMSs. It consists of an open source CMS admin UI which you install as an npm package and host. This allows you to easily extend for your own workflow with their extension ecosystem. The admin then connects to Sanity for storing the data, and for authentication.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/sanity-io/gatsby-source-sanity&quot;&gt;Try it out&lt;/a&gt; |
&lt;a href=&quot;https://www.sanity.io/pricing&quot;&gt;Pricing&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;&lt;a href=&quot;https://www.contentful.com/&quot;&gt;Contentful&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Contentful is one of the larger SaaS headless CMSs, and the oldest on our list here, being launched back in 2014. Clearly pitching themselves as the Enterprise solution, Contentful has the most clout, but also the price point to match. One thing to watch is that they may not have the features and extensibility common in the current generation of SaaS headless CMSs.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.gatsbyjs.org/starters/contentful-userland/gatsby-contentful-starter/&quot;&gt;Try it out&lt;/a&gt; |
&lt;a href=&quot;https://www.contentful.com/pricing/&quot;&gt;Pricing&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;&lt;a href=&quot;https://prismic.io/&quot;&gt;Prismic&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Prismic is another of the new breed of SaaS headless CMSs. It provides an excellent hosted admin with the ability to easily add custom types, and publishes a REST and GraphQL API.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/prismicio/gatsby-blog&quot;&gt;Try it out&lt;/a&gt; |
&lt;a href=&quot;https://prismic.io/pricing&quot;&gt;Pricing&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;&lt;a href=&quot;https://www.forestry.io/&quot;&gt;Forestry&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Forestry has been described as Netlify CMS on steroids. Like Netlify CMS, it connects to GitHub to store markdown files which is great for portability. Unlike Netlify CMS however, Forestry also provides a hosted CMS admin UI, providing a more polished, managed solution. However you can also deploy the editor to your own site with &lt;a href=&quot;https://forestry.io/docs/editing/remote-admin/&quot;&gt;Forestry Remote Admin&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/forestryio/gatsby-starter-blog&quot;&gt;Try it out&lt;/a&gt; |
&lt;a href=&quot;https://www.forestry.io/pricing/&quot;&gt;Pricing&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Which one should you use?&lt;/h2&gt;&lt;p&gt;Like everything, it depends! 🤷‍♂️&lt;/p&gt;&lt;p&gt;A lot of it comes down to how you want to store your data (git / hosted service) and the editing experience.&lt;/p&gt;&lt;p&gt;If it’s a commercial site, you’ve got the money, or just really want something turnkey, then try one of the SaaS options. They all have free plans to start, so sign up and try them out to see what fits.&lt;/p&gt;&lt;p&gt;If it’s a simple blog, Netlify CMS will do great. (in fact, I’m using it for  this blog!)&lt;/p&gt;&lt;p&gt;If it’s a bigger site / application, give a more full powered solution a go such as Keystone or Strapi.&lt;/p&gt;&lt;p&gt;And if you need to work with clients, you might be stuck with WordPress, but at least you can have some shiny front end tech and they get the benefits of a performant, secure site.&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Can I use React Helmet to add social card meta tags for Twitter and Facebook?]]></title><description><![CDATA[So you've built an awesome React powered site. It's shiny, and cool, and does everything you need... until your client/boss/best mate's dad…]]></description><link>https://chriscolborne.com/react-helmet-social-card-meta-tags/</link><guid isPermaLink="false">https://chriscolborne.com/react-helmet-social-card-meta-tags/</guid><pubDate>Tue, 18 Feb 2020 08:30:00 GMT</pubDate><content:encoded>&lt;p&gt;So you’ve built an awesome React powered site. It’s shiny, and cool, and does everything you need… until your client/boss/best mate’s dad asks about social sharing meta tags. ‘Hey mate, I’ve heard you can put some tags in and I’ll get the cool card when I share my pages on Twitter and Facebook?’ Uhhh sure, just chuck them in &lt;a href=&quot;https://github.com/nfl/react-helmet&quot;&gt;React Helmet&lt;/a&gt; and you’ll be sweet right? But hang on, it’s not working!&lt;/p&gt;&lt;p&gt;So what’s the deal, can you add social share meta tags with React Helmet?&lt;/p&gt;&lt;p&gt;Absolutely… with a caveat.&lt;/p&gt;&lt;p&gt;See, the problem is that the various social networks don’t run your JavaScript and so won’t see your dynamically updated meta tags as they’re added on page load.&lt;/p&gt;&lt;p&gt;So the answer is that you need a way to either statically generate, or server-side render your React app.&lt;/p&gt;&lt;p&gt;Whilst not exhaustive, here are a couple of ways you can do that.&lt;/p&gt;&lt;h2&gt;React Snapshot&lt;/h2&gt;&lt;p&gt;Probably the easiest if you’ve just got a Create React App (CRA) app, is to use &lt;a href=&quot;https://github.com/geelen/react-snapshot&quot;&gt;React Snapshot&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;React Snapshot takes your CRA app, follows any internal links it can find and generates a static site.&lt;/p&gt;&lt;p&gt;Just a simple npm install, update 3 lines and you’ve got a statically generated site.&lt;/p&gt;&lt;h2&gt;static-site-generator-webpack-plugin&lt;/h2&gt;&lt;p&gt;If you’ve got a custom Webpack setup, you can use the &lt;a href=&quot;https://github.com/markdalgleish/static-site-generator-webpack-plugin&quot;&gt;static-site-generator-webpack-plugin&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This plugin formed the basis of Gatsby (mentioned next) before version 2.&lt;/p&gt;&lt;h2&gt;Gatsby&lt;/h2&gt;&lt;p&gt;As primarily a static site generator, &lt;a href=&quot;https://www.gatsbyjs.org/&quot;&gt;Gatsby&lt;/a&gt; can do this out of the box. If you use the &lt;a href=&quot;https://github.com/gatsbyjs/gatsby-starter-blog&quot;&gt;blog starter&lt;/a&gt;, you can use the &lt;a href=&quot;https://github.com/gatsbyjs/gatsby-starter-blog/blob/master/src/components/seo.js&quot;&gt;SEO component&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Even if you’re not using the blog starter, you can use the SEO component for inspiration and implement it in your site.&lt;/p&gt;&lt;h2&gt;Next.js&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://nextjs.org/&quot;&gt;Next.js&lt;/a&gt; has a feature called &lt;a href=&quot;https://nextjs.org/docs/advanced-features/static-html-export&quot;&gt;Static HTML Export&lt;/a&gt; which can statically render your site.&lt;/p&gt;&lt;p&gt;&lt;code&gt;$ next build &amp;amp;&amp;amp; next export&lt;/code&gt;&lt;/p&gt;&lt;p&gt;And if you’re not using &lt;code&gt;getInitialProps&lt;/code&gt;, you might not even need to use &lt;code&gt;next export&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Next.js has a feature called &lt;a href=&quot;https://nextjs.org/docs/advanced-features/automatic-static-optimization&quot;&gt;Automatic Static Optimization&lt;/a&gt; which will automatically prerender &lt;code&gt;.html&lt;/code&gt; files for those it can.&lt;/p&gt;&lt;h2&gt;Testing your social cards&lt;/h2&gt;&lt;p&gt;Once you’ve set up your social card meta tags, you can test your meta tags using the following tools.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://cards-dev.twitter.com/validator&quot;&gt;Twitter Card Validator&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://developers.facebook.com/tools/debug/&quot;&gt;Facebook Sharing Debugger&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/post-inspector/&quot;&gt;LinkedIn Post Inspector&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Is it ever OK to set state directly? A setState cheat sheet]]></title><description><![CDATA[One of the parts of React that trips people up is understanding state and how to update it. A lot of this confusion comes from the fact that…]]></description><link>https://chriscolborne.com/setstate-cheat-sheet/</link><guid isPermaLink="false">https://chriscolborne.com/setstate-cheat-sheet/</guid><pubDate>Tue, 04 Feb 2020 08:30:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the parts of React that trips people up is understanding state and how to update it. A lot of this confusion comes from the fact that setState is asynchronous.&lt;/p&gt;&lt;p&gt;As they write in the &lt;a href=&quot;https://reactjs.org/docs/react-component.html#setstate&quot;&gt;React docs&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Think of setState() as a &lt;strong&gt;request&lt;/strong&gt; rather than an immediate command to update the component.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;(Note: I’ll be referring to setState, but it applies equally to the useState hook which we’ll cover later)&lt;/p&gt;&lt;h2&gt;So if I want to update immediately, I should just update the state object directly… right?&lt;/h2&gt;&lt;p&gt;&lt;code&gt;this.state.myValue = &amp;#x27;newValue&amp;#x27;;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;NO! If you do this, you’re opting out of React’s handling, and your component won’t re-render.&lt;/p&gt;&lt;p&gt;The reason setState exists is to allow React to produce a more efficient and better experience for the end user. By batching the state updates, it can prevent needless re-renders and can allow React to do even more smart handling of different priority updates, aka &lt;a href=&quot;https://reactjs.org/docs/concurrent-mode-intro.html&quot;&gt;concurrent mode&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;OK, OK, I’ll use setState. But what about the weird updater function syntax? Surely I don’t need that?&lt;/h2&gt;&lt;p&gt;Actually you do.&lt;/p&gt;&lt;p&gt;setState (and useState) have two forms, the updater function and the stateChange object syntax.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// Updater function&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// pass a function to show what to update&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(prevState &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { count: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;prevState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// stateChange object&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// pass an object to show what to update&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;({ name: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;New Name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Which one should I use when?&lt;/h2&gt;&lt;p&gt;Here’s a quick rule of thumb.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;If your next state depends on the current state, use the updater function. Otherwise you’re fine to pass an object in the stateChange syntax.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;For example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;updating a count (updater function)&lt;/li&gt;&lt;li&gt;updating an object (updater function)&lt;/li&gt;&lt;li&gt;toggling a boolean (updater function)&lt;/li&gt;&lt;li&gt;setting a new string value (stateChange object)&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;What about hooks and useState?&lt;/h2&gt;&lt;p&gt;All the cases above apply equally to the useState hook.&lt;/p&gt;&lt;p&gt;Where you would use the updater function in setState, use the updater function in your hook setter function.&lt;/p&gt;&lt;p&gt;See the below examples in both setState and useState hook.&lt;/p&gt;&lt;h2&gt;So how about that cheat sheet?&lt;/h2&gt;&lt;p&gt;Most situations can be boiled down to one of a few examples, shown below:&lt;/p&gt;&lt;h3&gt;Updating a count&lt;/h3&gt;&lt;p&gt;Relies on previous state, use updater function&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;1&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// this.setState()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(prevState &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { count: &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;prevState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// useState hook&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setCount&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;setCount&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(prevCount &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;prevCount&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Updating an object&lt;/h3&gt;&lt;p&gt;Relies on previous state, use updater function&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;2&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// this.setState()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(prevState &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { config: { &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;prevState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;updatedValues&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// useState hook&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setConfig&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;({});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;setConfig&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(prevConfig &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; ({ &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;prevConfig&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;updatedValues&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; }));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Toggling a boolean&lt;/h3&gt;&lt;p&gt;Relies on previous state, use updater function&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;3&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// this.setState()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(prevState &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { isEnabled: &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;prevState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;isEnabled&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// useState hook&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;isEnabled&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setIsEnabled&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;setIsEnabled&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(prevIsEnabled &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;prevIsEnabled&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Setting a new string value&lt;/h3&gt;&lt;p&gt;Doesn’t rely on previous state, use stateChange object&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;4&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// this.setState()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;({ stringValue: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;doesn&amp;#x27;t rely on previous state&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// useState hook&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;stringValue&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setStringValue&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;a default string&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;setStringValue&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;doesn&amp;#x27;t rely on the previous state&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;To wrap up&lt;/h2&gt;&lt;p&gt;Component state is one of the main concepts you need to understand in React. Remember these simple rules and you’ll never be confused by setState again!&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Never change state directly: always use setState or the useState setter function.&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;If your next state depends on the current state, use the updater function.&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtkb { font-weight: bold; }
  .solarized-dark .mtki { font-style: italic; }
  .solarized-dark .mtk3 { color: #657B83; }
  .solarized-dark .mtk7 { color: #268BD2; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk6 { color: #D33682; }
  .solarized-dark .mtk12 { color: #2AA198; }
  .solarized-dark .mtk5 { color: #B58900; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Avoid npm build errors by tracking your Node version with nvm]]></title><description><![CDATA[You know the feeling. You get a spare moment jump in and do some updates on an old app. But you try to get it running and the dreaded npm…]]></description><link>https://chriscolborne.com/avoid-npm-build-errors-with-nvm/</link><guid isPermaLink="false">https://chriscolborne.com/avoid-npm-build-errors-with-nvm/</guid><pubDate>Tue, 21 Jan 2020 08:15:00 GMT</pubDate><content:encoded>&lt;p&gt;You know the feeling. You get a spare moment jump in and do some updates on an old app. But you try to get it running and the dreaded npm errors come up.&lt;/p&gt;&lt;p&gt;Oftentimes, the issue is that you’ve updated Node since you last ran it. Many issues with dependencies and npm can been easily solved by switching Node versions.&lt;/p&gt;&lt;p&gt;Easy, so just go back to the version of node you used when you originally developed it. But how do you know which version to jump to? Just guess and check?&lt;/p&gt;&lt;p&gt;Perhaps you can leave a note in your README saying “This works in Node version X.” And sure, that’s certainly one way of solving it.&lt;/p&gt;&lt;p&gt;But using &lt;code&gt;nvm&lt;/code&gt;, we can track the version, as well as automate the switch back, and that’s what we’ll talk about today.&lt;/p&gt;&lt;p&gt;&lt;code&gt;nvm&lt;/code&gt; is &lt;a href=&quot;https://nvm.sh&quot;&gt;Node Version Manager&lt;/a&gt;. It primarily allows you to switch between isolated Node environments for different versions. If you’ve used rvm/rbenv in Ruby, it’s similar to that.&lt;/p&gt;&lt;p&gt;For our purposes today however, the killer feature is the &lt;code&gt;.nvmrc&lt;/code&gt; file. &lt;code&gt;.nvmrc&lt;/code&gt; is a file you commit with your project which contains a single line with the version of Node to use for this project.&lt;/p&gt;&lt;p&gt;In a project with an &lt;code&gt;.nvmrc&lt;/code&gt; file, you can type &lt;code&gt;nvm use&lt;/code&gt; and it will automatically switch back to the version you’ve stated. If you’re really keen, you can (and I’d say you should) also set up your shell to &lt;a href=&quot;https://github.com/nvm-sh/nvm/blob/master/README.md#deeper-shell-integration&quot;&gt;automatically &lt;code&gt;nvm use&lt;/code&gt;&lt;/a&gt; when it encounters an &lt;code&gt;.nvmrc&lt;/code&gt; file.&lt;/p&gt;&lt;p&gt;So start using &lt;code&gt;nvm&lt;/code&gt; and &lt;code&gt;.nvmrc&lt;/code&gt; in your projects and next time you’re returning to an old project, you’re just an &lt;code&gt;nvm use&lt;/code&gt; away from being back up and running quick smart.&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Arrow functions coming soon to PHP 7.4]]></title><description><![CDATA[The latest version of PHP 7.4 is coming soon. Release candidate 1 (the first of 6 planned RCs) was just released on 5th September and 7.4 is…]]></description><link>https://chriscolborne.com/php-74-arrow-functions/</link><guid isPermaLink="false">https://chriscolborne.com/php-74-arrow-functions/</guid><pubDate>Sun, 08 Sep 2019 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The latest version of PHP 7.4 is coming soon. Release candidate 1 (the first of 6 planned RCs) was just released on 5th September and 7.4 is scheduled for General Availability on November 28, 2019.&lt;/p&gt;&lt;p&gt;If you’re like me, one of the cooler additions to look forward to coming to the language is &lt;a href=&quot;https://wiki.php.net/rfc/arrow_functions_v2&quot;&gt;arrow functions&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Arrow functions in ES6&lt;/h2&gt;&lt;p&gt;If you’ve done any modern JavaScript, you’re probably familiar with arrow functions which came in ES6. In case you’re not, they look like this:&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// in JavaScript arrow functions looks like this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// add numbers and return the result&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;addSomeNumbers&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (a, b) &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// echo out a message and return the input parameter&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;doTheThing&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; theThing &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;`I&amp;#x27;m doing ${&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;theThing&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;}`&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;theThing&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Arrow functions in PHP&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;prefix with &lt;code&gt;fn&lt;/code&gt;&lt;/li&gt;&lt;li&gt;only single statement implicit return style arrow functions are implemented currently, no block based style like the first JavaScript example (although the block style is in the future scope - named multi-statement bodies &lt;a href=&quot;https://wiki.php.net/rfc/arrow_functions_v2&quot;&gt;in the RFC&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;supports implicit variable binding, in other words, &lt;code&gt;use&lt;/code&gt; is not required&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Here are the examples from the RFC showing the arrow syntax and implicit variable binding:&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;1&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// in PHP arrow functions look like this&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// long version required currently&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;array_values_from_keys&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;array_map&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) { &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;]; }, &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// long&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;keys&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    );&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// with arrow functions&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;array_values_from_keys&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;array_map&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;], &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// short&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;keys&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    );&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// note the difference&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) { &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;]; };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;short&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Try it out&lt;/h2&gt;&lt;p&gt;I’ve created a simple test repo so you can try them out now.&lt;/p&gt;&lt;p&gt;Check out &lt;a href=&quot;https://github.com/zorfling/php-74-arrow-functions&quot;&gt;https://github.com/zorfling/php-74-arrow-functions&lt;/a&gt;&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtkb { font-weight: bold; }
  .solarized-dark .mtki { font-style: italic; }
  .solarized-dark .mtk3 { color: #657B83; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk7 { color: #268BD2; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk12 { color: #2AA198; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Build a GraphQL server with Laravel]]></title><description><![CDATA[One of the cool new things coming out from Facebook Open Source is GraphQL. What is GraphQL? GraphQL is a specification for communicating…]]></description><link>https://chriscolborne.com/laravel-graphql-server/</link><guid isPermaLink="false">https://chriscolborne.com/laravel-graphql-server/</guid><pubDate>Thu, 26 Jul 2018 21:24:32 GMT</pubDate><content:encoded>&lt;p&gt;One of the cool new things coming out from Facebook Open Source is GraphQL.&lt;/p&gt;&lt;h2&gt;What is GraphQL?&lt;/h2&gt;&lt;p&gt;GraphQL is a specification for communicating with APIs. You can think of GraphQL as an equivalent to REST, where GraphQL and REST are both just specifications for how to communicate with an API.&lt;/p&gt;&lt;h2&gt;Why is GraphQL awesome?&lt;/h2&gt;&lt;p&gt;GraphQL is awesome because it&lt;/p&gt;&lt;ul&gt;&lt;li&gt;has a single endpoint&lt;/li&gt;&lt;li&gt;allows for relational queries&lt;/li&gt;&lt;li&gt;eliminates over-requesting and under-requesting&lt;/li&gt;&lt;li&gt;can return all the data in one request&lt;/li&gt;&lt;li&gt;can mitigate the need for versioning as the client determines what it wants, not the server&lt;/li&gt;&lt;li&gt;can combine disparate data sources into a single API&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;How do we do it?&lt;/h2&gt;&lt;p&gt;To use GraphQL, we need two parts. First we need a GraphQL server, and then we need a GraphQL client. In this post we’ll build out a GraphQL server in Laravel, and then in a following post, we’ll build a client app which uses our new server to display some data.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:590px&quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/a21d8d1346039ca40b522d7686831192/0a47e/logos.png&quot; style=&quot;display:block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:44.5945945945946%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABzUlEQVQoz12SP0hbURTGv/uSooMWrEIQF9tokW76kmdNtTHvJfqS1D8pKFioFQcphdqhQxfxz+LgIkU6FboX0RjpJoJS6FYHB0dxcXNwMWKMuf2OL6nB4ceXc+H8ct69B5fYUNfYwhWywgRpkN9yXuB5wfcTxfYZlKJdKNnmPULVtZKURmj8MticoihPForI1V5gHRdqA7+bVzCRjBs6+gzaNi02pUhXRaJjVX+QsCBTrZHvFE4ye5lvmV/I7qXK1uwFVhEccfA33iNNaUqbmf2kpWq6RhIUuQg/kE8U2VfyidgyWb8hyxqnysz0+tJu8jUy034d65TGFyUnbDBfVQkdMkaeU5ALUDJLQW3h7i4n82oz8qfpK8ad0TY3mdwfcV0rm+jDtR2Ks7GetHNak1M9Kgs/k7g0fyM7lD0mYfKE9RI5OGr4Ycyb75EeTHXkBl6qcyeMsixDWTdzkfRQWlfyakuEU2SVoo/MsfJdzon0BtsPNE4QGe7HYSKCvLyq9wgBCh9KylSkg3WCGap8otxdG/OYjFfOitjmBuwjOuSod+4Azmzr/4vqu7V5Kmg75K0NGw3iK0taiV9ElSx4D+VJYh6363JvJ7UnV/8A8+ImsRfZCdAAAAAASUVORK5CYII=&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;GraphQL plus Laravel&quot; title=&quot;GraphQL plus Laravel&quot; src=&quot;/static/a21d8d1346039ca40b522d7686831192/fcda8/logos.png&quot; srcSet=&quot;/static/a21d8d1346039ca40b522d7686831192/12f09/logos.png 148w,/static/a21d8d1346039ca40b522d7686831192/e4a3f/logos.png 295w,/static/a21d8d1346039ca40b522d7686831192/fcda8/logos.png 590w,/static/a21d8d1346039ca40b522d7686831192/0a47e/logos.png 600w&quot; sizes=&quot;(max-width: 590px) 100vw, 590px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;h2&gt;Let’s go!&lt;/h2&gt;&lt;p&gt;We’ll be building upon Steve Luscher’s awesome zero-to-graphql &lt;a href=&quot;https://www.youtube.com/watch?v=UBGzsb2UkeY&quot;&gt;talk&lt;/a&gt; and &lt;a href=&quot;https://github.com/steveluscher/zero-to-graphql&quot;&gt;repository&lt;/a&gt;. In the talk he spun up a GraphQL endpoint in Django, Rails and Node inside 30 minutes.&lt;/p&gt;&lt;p&gt;It exposes a person model as follows:&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;Person&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;/** &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;@var&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;/** &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;@var&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;/** &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;@var&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;/** &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;@var&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;/** &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;@var&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;/** &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;@var&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;Person[]&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;friends&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It also provides two queries, &lt;code&gt;allPeople&lt;/code&gt; to list all the people, and &lt;code&gt;person&lt;/code&gt; to retrieve a particular Person by ID.&lt;/p&gt;&lt;p&gt;We’ll use Laravel and &lt;a href=&quot;https://github.com/Folkloreatelier/laravel-graphql&quot;&gt;Laravel GraphQL&lt;/a&gt; to create our very own GraphQL server with Laravel that meets this schema.&lt;/p&gt;&lt;h3&gt;Set up a new Laravel app&lt;/h3&gt;&lt;p&gt;First up we’ll use the Laravel CLI to create a new application.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;1&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ laravel new zero-graphql&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Add a database&lt;/h3&gt;&lt;p&gt;I’m using &lt;a href=&quot;http://laradock.io&quot;&gt;Laradock&lt;/a&gt; to serve and provide a MySQL database for our users, but you could just as easily use Homestead or a locally installed Mysql database with Valet.&lt;/p&gt;&lt;p&gt;Configuration of this step is beyond the scope of this post, but see the &lt;a href=&quot;https://github.com/zorfling/laravel-graphql-server&quot;&gt;repo&lt;/a&gt; and &lt;a href=&quot;http://laradock.io/getting-started/&quot;&gt;Laradock docs&lt;/a&gt; for a configured Laradock setup, or the docs for &lt;a href=&quot;https://laravel.com/docs/5.6/homestead&quot;&gt;Homestead&lt;/a&gt; or &lt;a href=&quot;https://laravel.com/docs/5.6/valet&quot;&gt;Valet&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Add Laravel GraphQL&lt;/h3&gt;&lt;p&gt;Next up we’ll add the Laravel GraphQL library to provide some GraphQL primitives, as well as the GraphiQL web based API client for testing the endpoint.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;2&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# Require the library&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ composer require folklore/graphql&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# publish the graphql config and graphiql route&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ artisan vendor:publish --provider=&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Folklore\GraphQL\ServiceProvider&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Add Person Type&lt;/h3&gt;&lt;p&gt;As GraphQL is a strongly typed definition, we need to define the types we’ll use, in our case the Person type. Thankfully the Laravel GraphQL library provides an artisan command to scaffold out our Person type.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;3&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ ./artisan make:graphql:type PersonType&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And then add our fields to the newly generated type file.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;4&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// app/GraphQL/Type/PersonType.php&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;type&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;nonNull&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;description&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;The id of the user&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;first_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;type&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;nonNull&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;description&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;The firstName of the user&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;last_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;type&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;nonNull&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;description&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;The lastName of the user&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;username&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;type&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;nonNull&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;description&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;The username of the user&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;email&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;type&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;nonNull&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;description&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;The email of user&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friends&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;type&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;GraphQL::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Person&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;description&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Person&lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;\&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;s friends&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Add People Data&lt;/h3&gt;&lt;p&gt;So we have something for our GraphQL API to return, let’s add some people to the database.
We’ll create our Person model and migrations and seeders for each of the People and Friendships tables. Again we can use artisan to scaffold out the files.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;5&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ ./artisan make:model Person -m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ ./artisan make:seeder PeopleTableSeeder&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ ./artisan make:seeder FriendshipsTableSeeder&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We’ll add our columns to our &lt;code&gt;people&lt;/code&gt; and our &lt;code&gt;friendships&lt;/code&gt; table and some seed data for each.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;6&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// database/migrations/2018_04_16_045416_create_people_table.php&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;up&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Schema::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;people&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;Blueprint&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;increments&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;first_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;last_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;username&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;email&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;timestamps&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;7&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// database/seeds/PeopleTableSeeder.php&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; Illuminate\Database\&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Seeder&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;PeopleTableSeeder&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk8&quot;&gt;Seeder&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;/**&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;     * Run the database seeds.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;     *&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;     * &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;@return&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;void&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;DB::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;people&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;first_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Kyle&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;last_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Reyes&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;username&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;kreyes&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;email&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;kyle.reyes@example.com&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;DB::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;people&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;first_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Emma&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;last_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Thomsen&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;username&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;ethomsen&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;email&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;emma.thomsen@example.com&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;DB::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;people&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;first_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Crispim&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;last_name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Ramos&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;username&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;cramos&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;email&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;crispim.ramos@example.com&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;8&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// database/migrations/2018_04_16_051549_create_friendships_table.php&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;up&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Schema::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friendships&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;Blueprint&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;integer&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;person_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;integer&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friend_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;timestamps&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;9&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// database/seeds/FriendshipsTableSeeder.php&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; Illuminate\Database\&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Seeder&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;FriendshipsTableSeeder&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk8&quot;&gt;Seeder&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;/**&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;     * Run the database seeds.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;     *&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;     * &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;@return&lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9 mtki&quot;&gt;void&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;DB::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friendships&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;person_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friend_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;DB::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friendships&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;person_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friend_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;DB::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friendships&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;person_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friend_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;DB::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friendships&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;person_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friend_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;DB::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friendships&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;person_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friend_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;DB::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friendships&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;person_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friend_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And finally our Person model&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;10&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;php&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// app/Person.php&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; Illuminate\Database\Eloquent\&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk8&quot;&gt;Model&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;friends&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;belongsToMany&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;App\Person&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friendships&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;person_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;friend_id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;GraphQL Queries&lt;/h3&gt;&lt;p&gt;Now we’re ready to add our GraphQL queries.&lt;/p&gt;&lt;h4&gt;All People Query&lt;/h4&gt;&lt;p&gt;The all people query allows us to list all people in the database.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;11&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# Query to return everyone&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ ./artisan make:graphql:query AllPeopleQuery&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Update the name to allPeople&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;12&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;protected&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;allPeople&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Update the type to a list of People&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;13&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;GraphQL::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Person&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And add our resolver&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;14&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Person::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;Person Query&lt;/h4&gt;&lt;p&gt;The person query allows us to retrieve a single person from the database by id.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;15&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# Query to return a person by ID&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ ./artisan make:graphql:query PersonQuery&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Update the name to person&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;16&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;protected&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;person&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Update the type to a Person&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;17&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;GraphQL::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Person&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And add our resolver&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;18&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// this allows us to query a particular id&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// it is passed to resolve() below&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;type&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;nonNull&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Type::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;())],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ];&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;])) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Person::&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;GraphiQL&lt;/h3&gt;&lt;p&gt;GraphiQL is a handy web based GraphQL client, baked in when we installed Laravel GraphQL. It’s similar to something like Postman which you might have used for testing REST APIs.&lt;/p&gt;&lt;p&gt;You can access it by going to http://localhost/graphiql.&lt;/p&gt;&lt;p&gt;Once you’re there, you can test out the queries we defined earlier.&lt;/p&gt;&lt;h4&gt;allPeople Query&lt;/h4&gt;&lt;p&gt;Get the username, first name and last name of all users, as well as their friends’ usernames.&lt;/p&gt;&lt;p&gt;Notice we can nest inside the query to return the username of each person’s friends as well. This is another of GraphQL’s benefits.&lt;/p&gt;&lt;h5&gt;Request&lt;/h5&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;graphql&quot; data-index=&quot;19&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;allPeople&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;username&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;first_name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;last_name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;friends&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;username&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h5&gt;Response&lt;/h5&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;json&quot; data-index=&quot;20&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;allPeople&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;kreyes&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;first_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Kyle&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;last_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Reyes&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;friends&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;ethomsen&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;cramos&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;ethomsen&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;first_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Emma&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;last_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Thomsen&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;friends&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;kreyes&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;cramos&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;cramos&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;first_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Crispim&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;last_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Ramos&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;friends&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;kreyes&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;ethomsen&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;Person Query&lt;/h4&gt;&lt;p&gt;Get the username of user id 1, along with the username, first name, last name and email of all his friends.&lt;/p&gt;&lt;h5&gt;Request&lt;/h5&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;graphql&quot; data-index=&quot;21&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(id: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;username&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;friends&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;username&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;first_name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;last_name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;email&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h5&gt;Response&lt;/h5&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;json&quot; data-index=&quot;22&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;person&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;kreyes&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;friends&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;ethomsen&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;first_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Emma&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;last_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Thomsen&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;email&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;emma.thomsen@example.com&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;cramos&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;first_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Crispim&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;last_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Ramos&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;&amp;quot;email&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;crispim.ramos@example.com&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Other cool GraphQL endpoints&lt;/h2&gt;&lt;p&gt;Here is a list of cool GraphQL endpoints to play around with and use for inspiration.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/APIs-guru/graphql-apis&quot;&gt;https://github.com/APIs-guru/graphql-apis&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Next Steps&lt;/h2&gt;&lt;p&gt;Check out the &lt;a href=&quot;https://github.com/zorfling/laravel-graphql-server&quot;&gt;Github repo&lt;/a&gt; to clone the finished code.&lt;/p&gt;&lt;p&gt;And stay tuned for an upcoming post where we’ll build a client app which uses our new server to display the data!&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtki { font-style: italic; }
  .solarized-dark .mtkb { font-weight: bold; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk4 { color: #CB4B16; }
  .solarized-dark .mtk3 { color: #657B83; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk7 { color: #268BD2; }
  .solarized-dark .mtk12 { color: #2AA198; }
  .solarized-dark .mtk8 { color: #6C71C4; }
  .solarized-dark .mtk6 { color: #D33682; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Starting something new]]></title><description><![CDATA[EDIT (2020-09-19): I've folded the posts from Modern JS for PHP Devs back into chriscolborne.com here. Over the last month or two, I've…]]></description><link>https://chriscolborne.com/starting-something-new/</link><guid isPermaLink="false">https://chriscolborne.com/starting-something-new/</guid><pubDate>Mon, 29 Jan 2018 10:26:00 GMT</pubDate><content:encoded>&lt;p&gt;EDIT (2020-09-19): I’ve folded the posts from Modern JS for PHP Devs back into chriscolborne.com here.&lt;/p&gt;&lt;p&gt;Over the last month or two, I’ve started something new. I’ve started a new blog over at &lt;a href=&quot;https://www.modernjsforphpdevs.com&quot;&gt;https://www.modernjsforphpdevs.com&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I started the blog because after 6 wonderful years at The University of Queensland, I’ll be moving on to new things at the end of March. &lt;/p&gt;&lt;p&gt;My team has traditionally used quite a “safe” stack of Symfony and Backbone.js, so to learn all the modern tools, methods and libraries, and to ensure my skills are up to date, I need to do it on my own time. So what better way than to blog about it?&lt;/p&gt;&lt;p&gt;So who’s it for? I’m writing for someone like me. Maybe they’re a PHP dev who doesn’t get to use the coolest, newest stuff at work, but is still keen to try new things. They want to ensure their skills are up to date, and future proof their web development career.&lt;/p&gt;&lt;p&gt;It’s early days yet, but I’ve already got a couple posts about &lt;a href=&quot;https://www.modernjsforphpdevs.com/symfony-webpack-encore/&quot;&gt;using webpack with Symfony (via Webpack Encore)&lt;/a&gt; to &lt;a href=&quot;https://www.modernjsforphpdevs.com/react-symfony-4-starter-repo/&quot;&gt;build and use React components within Twig&lt;/a&gt;, and a “reader question” about &lt;a href=&quot;https://www.modernjsforphpdevs.com/why-react-vue-not-jquery&quot;&gt;why it might be time to hang up the dollar sign and ditch jQuery&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I’ll probably cross post back here occasionally, but I’d love it if you drop over to &lt;a href=&quot;https://www.modernjsforphpdevs.com&quot;&gt;Modern JS for PHP Devs&lt;/a&gt; and have a read!&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Why React or Vue and not jQuery?]]></title><description><![CDATA[One of my colleagues has been playing devil's advocate and hitting me with variations of the following question for a week or two now. His…]]></description><link>https://chriscolborne.com/why-react-vue-not-jquery/</link><guid isPermaLink="false">https://chriscolborne.com/why-react-vue-not-jquery/</guid><pubDate>Sun, 28 Jan 2018 22:55:32 GMT</pubDate><content:encoded>&lt;p&gt;One of my colleagues has been playing devil’s advocate and hitting me with variations of the following question for a week or two now.&lt;/p&gt;&lt;p&gt;His question, “Chris, jQuery is so quick and easy to get going, why would I possibly use something like React or Vue that has such a steep setup curve? And it has so many plugins! And why wouldn’t I just keep using jQuery anyway? There’s nothing wrong with it!”&lt;/p&gt;&lt;p&gt;So there’s a couple of questions in that, so I’ll try here to break it down. I’ll start with the latter.&lt;/p&gt;&lt;h2&gt;Why shouldn’t I keep using jQuery?&lt;/h2&gt;&lt;p&gt;So the bottom line here is, because you probably don’t need it anymore. jQuery was born in an age of ES5, when it was truly difficult to maintain browser compatibility, when functional paradigms were the bastion of mad scientist types (I’m looking at you, Haskell devs!) and as JavaScript as a web language was growing from the dark old days of DHTML, where JavaScript was used for nothing more than image rollovers, to a burgeoning new age of web application.&lt;/p&gt;&lt;p&gt;If you really don’t believe that you don’t need it, check out the great list at &lt;a href=&quot;http://youmightnotneedjquery.com/&quot;&gt;You Might Not Need jQuery&lt;/a&gt;, and while you’re at it, reconsider underscore/lodash with &lt;a href=&quot;https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore&quot;&gt;You Don’t Need Lodash/Underscore&lt;/a&gt; and the accompanying eslint plugin.&lt;/p&gt;&lt;h2&gt;jQuery is so quick, how can React or Vue compete, and why bother?&lt;/h2&gt;&lt;p&gt;The other argument for jQuery is speed to implement. We’ve all seen &lt;a href=&quot;https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f&quot;&gt;How it feels to learn JavaScript in 2016&lt;/a&gt;, and yes, the more modern libraries need a build step. And yes, if you &lt;em&gt;just&lt;/em&gt; want to make a button click hide a div, one line of jQuery can get that out quick smart, no build required.&lt;/p&gt;&lt;p&gt;But with the advent of &lt;a href=&quot;https://github.com/reyronald/awesome-toolkits&quot;&gt;zero-config (#0CJS) toolkits&lt;/a&gt; such as &lt;a href=&quot;https://github.com/facebook/create-react-app&quot;&gt;Create React App&lt;/a&gt; and &lt;a href=&quot;https://github.com/vuejs/vue-cli&quot;&gt;vue-cli&lt;/a&gt;, a fully featured build process and install is one node command away, then you’re off to the races, with added bells and whistles such as hot module reload and the chance to use modern JavaScript features from ES6 and beyond.&lt;/p&gt;&lt;p&gt;And with tools such as &lt;a href=&quot;https://codesandbox.io&quot;&gt;CodeSandbox&lt;/a&gt; you can hack out a quick prototype quicker than you can say &lt;code&gt;&amp;lt;script src=&amp;quot;https://&lt;/code&gt;…&lt;/p&gt;&lt;p&gt;But really, it’s what comes next that is the reason to leave jQuery for React or Vue. How often have you &lt;em&gt;only&lt;/em&gt; made a single button click hide a div?&lt;/p&gt;&lt;p&gt;Does this look familiar?&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:590px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:76.35135135135135%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEeUlEQVQ4yx3SW0xTBwCH8fOyt8Us25It2ZYsy95N5suWKajMqiCKMRo1chMkjEGFtlJQBCoiMlkYIszJRRQZrFQschGQS7kVCz209HIoLdoKlF7O6eUUuWnP+c/59Hv8Xj5iWR9jdRmP+LxULOMxH2EYS6wvYD0aWNHHsA7yMLuki3nrIKPnZoeiVBb1QdZOxnjMkzF++/S+QPvkraBYux0s1LP+a8Z15qrW5yECpsgQ3AJwywIw5r3wUXs/uP4yCnAKAI8Am7Z9joqJMUu1gUKVwYJykkLtjBZ1pteofcWjcjEMmRUoMm6AqBztYeoME/hXN8D1kl380LSCfzbVzndqOvgHmi7unn4Y1WPKV7lqxlTmBIoXEH5qY/mFJZp3exk+GAzyS26an3at8ddJhidEKrdzwL6JxdcM7wtsIcC+RTD09oNmh49X2jYgUnmc+epVU+HUMkr1Pi60FsKm3401P40N1g+W8QJbb3Bb4wAhH9c6gHegaS/HMPT/gmWDWF5egmt1hcdWCMppoydz3GX8raYZqY3j3LXRJcgpNxSkHf02GiqjFQ/nnCjQrYGoGplbXKVpbK0FOcbtRMC7+r7owfYbFvz2Ok+/j9xRzfnEky6qcCaAOGkXJ+ygkD+5AvndONx4eAcl5DqujFhxWb0KQjrF2sopHvU6hnuiWcAg5cW4xYMJRwiK+SBfSYUhGfMGrmg8Fpl+Decqu7l0+WMUdbYg4/BOpBaLkD9rR0XuWRRX/g4i/elfizmTcmQMtXAXHtxGYlsZkluvI/VxHdJHWnmxRoG0J9VMvtppvjqxBJkhxB1sa4Zw4iXEKi9+7bAgraEb1TfO4GZjA4izjyKtif0HkFSzm5MId+Ny6U+4WvYzZOIfkXMrgo/v248zj/Z7JT2kqWDMAZl5mzvyoAniaTcKakuQeb0Ash47Cu61Q6R8AeK0PHohrTMOmoF0zjkowp8X9qDk1A/wjUuwOJjF57cn4kTrITqrUWEpmvVDRm1x0n4DRF06lA5PIW9IB0lDP0pfrOIatQki8b7ANtCZgqm2TG7DfAX3ZadQIYxGSJ8L68QdXvf8BgrroujMztn5EjNQSoErMgHZokvI/VuJkqc2pCvtkE4GcPP93IRKnjTvUYuhbsvgPDNS9OccQNf5SNBaKbqa8niWzINrNNub2lppzHr+EDkj/3Dx7VVISzoOcXY8Eu6KkTnUioTmCmQPt4Cw9GbofeQlvHyW9a4+dXe45OOPwvkEEW5K28PZlGlhZkaCwcYE+uz9CFNynwAnFZHvmvtOh2tyD4c7qs6EyxQnuFPKSC6l7xCX3P0LR5h60m2hWSl8GgnahJG4/d1nKP9yB5R5v8DcK8TF+Ch8/8XnmycbBK+SnsTicXcynP0XUbvrWwwXH0OILECj8hwSlLFI6Y0DMSU/L18Zy55bHs3WevR5c+U7vzGIv/rUsDItNvXUp5iiI3bNf/3JjrGjNXvbalpOGvzj4plnd5NnMglCq8iK0LnIXJNzQGj+o+m4+Vj9PvN/gsFn12ALvPEAAAAASUVORK5CYII=&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;Building software is often patches on top of patches on top of patches...&quot; title=&quot;Building software is often patches on top of patches on top of patches...&quot; src=&quot;/static/da410335886cb527710661b22a3e1e43/fcda8/building-software.png&quot; srcSet=&quot;/static/da410335886cb527710661b22a3e1e43/12f09/building-software.png 148w,/static/da410335886cb527710661b22a3e1e43/e4a3f/building-software.png 295w,/static/da410335886cb527710661b22a3e1e43/fcda8/building-software.png 590w,/static/da410335886cb527710661b22a3e1e43/efc66/building-software.png 885w,/static/da410335886cb527710661b22a3e1e43/2e694/building-software.png 1048w&quot; sizes=&quot;(max-width: 590px) 100vw, 590px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;
Image by &lt;a href=&quot;http://bonkersworld.net/building-software&quot;&gt;Manu Cornet&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The reason to use one of these new component based libraries is that it makes you design your app in a different way (or actually design it at all). You think in components, you have a defined structure and data model, with predictable and maintainable structure.&lt;/p&gt;&lt;h2&gt;But what about all the plugins? Won’t someone please think of the plugins?!&lt;/h2&gt;&lt;p&gt;Yes, jQuery has been around so long it’s basically got the “there’s &lt;del&gt;an app&lt;/del&gt; a plugin for that” covered.&lt;/p&gt;&lt;p&gt;But both Vue and React communities are growing so fast, and their component based systems are tailor made for plug and play functionality.&lt;/p&gt;&lt;p&gt;Next time you’re looking for a drop in feature, try these awesome lists for &lt;a href=&quot;https://github.com/brillout/awesome-react-components/blob/master/README.md&quot;&gt;React&lt;/a&gt; and &lt;a href=&quot;https://github.com/brillout/awesome-vue/blob/master/README.md&quot;&gt;Vue&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Still not enough? You could always build a wrapper component for your fave library. Check out this post over on Medium to find out &lt;a href=&quot;https://notes.devlabs.bg/how-to-use-jquery-libraries-in-the-react-ecosystem-7dfeb1aafde0&quot;&gt;How to Use jQuery Libraries in the React Ecosystem&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;So this is the end?&lt;/h2&gt;&lt;p&gt;jQuery is an amazing library that changed the JavaScript landscape. But maybe it’s time to hang up the dollar sign and use some pure JavaScript. Add a component based library and you’ll never think about your code the same way again.&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[React starter repo with Symfony 4 and Webpack Encore]]></title><description><![CDATA[In the  last post , we introduced Webpack Encore and why it makes for a quick start for modern JS with Symfony. In this post, we'll set up a…]]></description><link>https://chriscolborne.com/react-symfony-4-starter-repo/</link><guid isPermaLink="false">https://chriscolborne.com/react-symfony-4-starter-repo/</guid><pubDate>Sun, 14 Jan 2018 23:17:32 GMT</pubDate><content:encoded>&lt;p&gt;In the &lt;a href=&quot;/symfony-webpack-encore/&quot;&gt;last post&lt;/a&gt;, we introduced Webpack Encore and why it makes for a quick start for modern JS with Symfony.&lt;/p&gt;&lt;p&gt;In this post, we’ll set up a basic starter repo for a React frontend using Symfony and Webpack Encore.&lt;/p&gt;&lt;p&gt;As a bonus, as Symfony 4 was released at the end of last year, let’s use the latest and greatest and start with that.&lt;/p&gt;&lt;h2&gt;Set up a new Symfony 4 project&lt;/h2&gt;&lt;p&gt;I’ll assume that you’ve got a basic understanding of composer and Symfony, but if not, go check out the &lt;a href=&quot;http://symfony.com/doc/current/quick_tour/the_big_picture.html&quot;&gt;Symfony quick start&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Ready? Ok let’s go!&lt;/p&gt;&lt;p&gt;&lt;code&gt;$ composer create-project symfony/skeleton my-project&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Tip: you’ll need composer to be installed globally for this to work.&lt;/p&gt;&lt;p&gt;This will create a directory called &lt;code&gt;my-project&lt;/code&gt; in the current directory with a Symfony skeleton site, and use composer to install all the dependencies.&lt;/p&gt;&lt;p&gt;Next we’ll set up some basic dependencies for our site.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ composer require annotations twig asset&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ composer require server --dev&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Configure Webpack Encore to add React&lt;/h2&gt;&lt;p&gt;Webpack Encore is simply a node package, so we can install it using npm (or yarn). But since we’re using composer flex, let’s use it to bootstrap things.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;1&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# Create package.json, webpack.config.js and add node_modules to .gitignore&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ composer require encore&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# Add react deps&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ yarn add --dev react react-dom prop-types babel-preset-react&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# Actually install node package&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ yarn install&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And finally, we need to enable the React preset in our &lt;code&gt;webpack.config.js&lt;/code&gt;.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;2&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// webpack.config.js&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;…&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;Encore&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  …&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;enableReactPreset&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Set up a demo JSON API&lt;/h2&gt;&lt;p&gt;We’ll set up a basic JSON endpoint to display some dummy data. We’ll hard code it for this demo, but you could hit the database, or other APIs at this point.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;php&quot; data-index=&quot;3&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// src/Controller/DefaultController.php&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;/**&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; * @Route(&amp;#x27;/data&amp;#x27;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt; */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;dataAction&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;JsonResponse&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;([&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;author&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Chris Colborne&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;avatarUrl&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;http://1.gravatar.com/avatar/13dbc56733c2cc66fbc698cdb07fec12&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;title&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Bitter Predation&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;description&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Thirteen thin, round towers …&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;author&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Louanne Perez&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;avatarUrl&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;https://randomuser.me/api/portraits/thumb/women/18.jpg&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;title&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Strangers of the Ambitious&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;description&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;A huge gate with thick metal doors …&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;id&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;author&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Theodorus Dietvorst&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;avatarUrl&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;https://randomuser.me/api/portraits/thumb/men/49.jpg&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;title&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Outsiders of the Mysterious&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;description&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;Plain fields of a type of grass cover …&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Set up a React frontend which uses it&lt;/h2&gt;&lt;p&gt;Ok, finally we need to setup React to use our JSON endpoint.&lt;/p&gt;&lt;p&gt;First add a div with an id of root to &lt;code&gt;index.html.twig&lt;/code&gt;. This will be our react mount point.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;html&quot; data-index=&quot;4&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;&amp;lt;!-- templates/Default/index.html.twig --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;…&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; id=&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;root&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next we’ll create our react component, and fetch the data from our endpoint. We’ll use &lt;a href=&quot;http://www.material-ui.com&quot;&gt;Material UI&lt;/a&gt; for quick good looking components, but you could just as easily build your own.&lt;/p&gt;&lt;p&gt;We’ll include Material UI with yarn.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;5&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;yarn add material-ui&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And we’ll create an ItemCard component using Material UI …&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;6&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// assets/js/Components/ItemCard.js&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; { &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;Card&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CardHeader&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CardTitle&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;CardText&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;material-ui/Card&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;ItemCard&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; ({ author, avatarUrl, title, subtitle, style, children }) &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Card&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; style&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;CardHeader&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; title&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; avatar&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;avatarUrl&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;CardTitle&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; title&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; subtitle&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;subtitle&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;CardText&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;CardText&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;Card&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;ItemCard&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;… and an App component which lists a few cards based on our endpoint above.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;7&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// assets/js/app.js&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;ReactDOM&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;react-dom&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;MuiThemeProvider&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;material-ui/styles/MuiThemeProvider&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;ItemCard&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;./Components/ItemCard&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk4&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk8&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      entries: [],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;componentDidMount&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/data&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(response &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;())&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(entries &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;({&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      });&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;MuiThemeProvider&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; style&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;{ display: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;flex&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; }&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            ({ id, author, avatarUrl, title, description }) &lt;/span&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;ItemCard&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                key&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                author&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                title&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                avatarUrl&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;avatarUrl&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                style&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;{ flex: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, margin: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; }&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;ItemCard&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            )&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          )&lt;/span&gt;&lt;span class=&quot;mtk15&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;MuiThemeProvider&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    );&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;ReactDOM&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;root&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally we need to add our application JavaScript as an entrypoint to our &lt;code&gt;webpack.config.js&lt;/code&gt;.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;js&quot; data-index=&quot;8&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// webpack.config.js&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  …&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;addEntry&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;js/app&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;./assets/js/app.js&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We’ll then include the built JavaScript in our twig template and we’re done!&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;twig&quot; data-index=&quot;9&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;&amp;lt;!-- templates/Default/index.html.twig --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{% &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;base.html.twig&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{% &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; id=&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;root&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; type=&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; src=&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;quot;{{ asset(&amp;#x27;build/js/app.js&amp;#x27;) }}&amp;quot;&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;mtk3&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;{% &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;endblock&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To view the final product, we need to compile the assets using Webpack Encore.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;10&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ yarn run encore dev&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# yarn run encore dev --watch to automatically rebuild on every change&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And then use the Symfony WebServerBundle we installed above to start the server.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;11&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# This will start a server at http://127.0.0.1:8000.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;$ ./bin/console server:start &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# stop with server:stop&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The final result is three React cards that fill the available space on the page.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:590px&quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/48d987ee4a017fde43361ae0d5abd835/ae28e/final-result.png&quot; style=&quot;display:block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:43.24324324324324%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABWUlEQVQoz4VSaa+CQAzk//8yY6J44RE8SEA8uERQBNF5zDw38X16mzTNdrbTdrpW4O2Q5zniOELbtni/3+C5XC4oyxJpmiLLMrxeL2FEq7LAtctJOiyOYxRFoRy+sXaOrUtT1/KG8HA4iJBFns/nHywJfeRpgrYjqLs8g4swSTOcz2cR1B9SHpL5vi/sdDrhfr/jw4pr11EQBIijSJjJEyFH4sgc8Xa7CSTA2Ha7RRiGaJoG34djrteusO8mOIE1Go0wmUxkw+EQs9kMVVXJWJ0dsqgpzPGoGbGo6zD96EhPzJrP56A5joPFYoHNZqNqfMBijBFfrVbY7/fSlGR8b2w6nYpcI/PCJPrlcqmN8jCp3+/Dtm11TfLBYCBZqF+v11N8PB7LXNf9JWSCMc/zkCSJCDkWl3I8HrUQEj0eD2EsSlJ2RYwLpJbSkFoxSG/+2vd/NGIb+w/7ASJ+qdTzYD6JAAAAAElFTkSuQmCC&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;The final result is three Material Design cards with an author, title and content&quot; title=&quot;The final result is three Material Design cards with an author, title and content&quot; src=&quot;/static/48d987ee4a017fde43361ae0d5abd835/fcda8/final-result.png&quot; srcSet=&quot;/static/48d987ee4a017fde43361ae0d5abd835/12f09/final-result.png 148w,/static/48d987ee4a017fde43361ae0d5abd835/e4a3f/final-result.png 295w,/static/48d987ee4a017fde43361ae0d5abd835/fcda8/final-result.png 590w,/static/48d987ee4a017fde43361ae0d5abd835/efc66/final-result.png 885w,/static/48d987ee4a017fde43361ae0d5abd835/c83ae/final-result.png 1180w,/static/48d987ee4a017fde43361ae0d5abd835/ae28e/final-result.png 1598w&quot; sizes=&quot;(max-width: 590px) 100vw, 590px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Check out the &lt;a href=&quot;https://github.com/zorfling/react-symfony-4-starter&quot;&gt;Github repo&lt;/a&gt; to clone the finished starter repo.&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtkb { font-weight: bold; }
  .solarized-dark .mtki { font-style: italic; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk3 { color: #657B83; }
  .solarized-dark .mtk7 { color: #268BD2; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk4 { color: #CB4B16; }
  .solarized-dark .mtk12 { color: #2AA198; }
  .solarized-dark .mtk6 { color: #D33682; }
  .solarized-dark .mtk15 { color: #D30102; }
  .solarized-dark .mtk8 { color: #6C71C4; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Modern JS in Symfony with Webpack Encore]]></title><description><![CDATA[Symfony 2 introduced Assetic to provide asset management. Back in 2011, in the days of server rendered application, this pure PHP solution…]]></description><link>https://chriscolborne.com/symfony-webpack-encore/</link><guid isPermaLink="false">https://chriscolborne.com/symfony-webpack-encore/</guid><pubDate>Mon, 27 Nov 2017 22:22:32 GMT</pubDate><content:encoded>&lt;p&gt;Symfony 2 introduced Assetic to provide asset management. Back in 2011, in the days of server rendered application, this pure PHP solution was good choice, but in 2017, Single Page Apps (SPA) and other more heavily javascript driven websites are the norm.&lt;/p&gt;&lt;p&gt;Assetic didn’t quite handle this modern world of JavaScript, where WebPack is the tool du jour for packaging and transpiling javascript, and including static JS straight from the file system is becoming somewhat of a faux pas.&lt;/p&gt;&lt;p&gt;That’s why, in June this year, Symfony released &lt;a href=&quot;https://symfony.com/blog/introducing-webpack-encore-for-asset-management&quot;&gt;Webpack Encore&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Webpack Encore is an abstraction over webpack which simplifies the configuration and provides a number of common transformations for a modern frontend toolchain. It brings best of breed asset bundling to your Symfony applications.&lt;/p&gt;&lt;p&gt;It also works great with Symfony and Twig, with the JSON manifest strategy introduced in Symfony 3.3. With one line of code, you can introduce asset versioning, and even configure a CDN.&lt;/p&gt;&lt;p&gt;Here’s an example webpack Encore webpack.config.js and the webpack config it generates. Notice the Webpack Encore is 23 lines (including comments) vs 168 lines of pure webpack config. 😮&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;javascript&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// Webpack Encore - webpack.config.js&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1 mtkb&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;Encore&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;@symfony/webpack-encore&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk7&quot;&gt;Encore&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// the project directory where all compiled assets will be stored&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setOutputPath&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;web/build/&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// the public path used by the web server to access the previous directory&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;setPublicPath&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/build&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// will create web/build/app.js and web/build/app.css&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;addEntry&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;app&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;./assets/js/app.js&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// allow sass/scss files to be processed&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;enableSassLoader&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// allow legacy applications to use $/jQuery as a global variable&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;autoProvidejQuery&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;enableSourceMaps&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;Encore&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;isProduction&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;())&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// empty the outputPath dir before each build&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;cleanupOutputBeforeBuild&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// show OS notifications when builds finish/fail&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;enableBuildNotifications&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// create hashed filenames (e.g. app.abc123.css)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  .&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;enableVersioning&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// export the final configuration&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;Encore&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk7&quot;&gt;getWebpackConfig&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;javascript&quot; data-index=&quot;1&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;// Pure webpack - webpack.config.js&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  context: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/Users/modern-js/Code/php/encore-test&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  entry: { app: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;./assets/js/app.js&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  output: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    path: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/Users/modern-js/Code/php/encore-test/web/build&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    filename: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;[name].[chunkhash].js&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    publicPath: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/build/&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    pathinfo: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  module: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    rules: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        test: {},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        exclude: {},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        use: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            loader: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;babel-loader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            options: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;              cacheDirectory: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;              presets: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                  &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;env&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                  {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                    modules: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                    targets: { browsers: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;&amp;gt; 1%&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, uglify: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                    useBuiltIns: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                  },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;                ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;              ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;              plugins: [],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        test: {},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        use: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            loader:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/Users/modern-js/Code/php/encore-test/node_modules/extract-text-webpack-plugin/dist/loader.js&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            options: { omit: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, remove: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          { loader: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;style-loader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            loader: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;css-loader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            options: { minimize: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, sourceMap: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, importLoaders: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        test: {},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        loader: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;file-loader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        options: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          name: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;images/[name].[hash:8].[ext]&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          publicPath: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/build/&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        test: {},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        loader: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;file-loader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        options: { name: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;fonts/[name].[hash:8].[ext]&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, publicPath: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/build/&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        test: {},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        use: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            loader:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/Users/modern-js/Code/php/encore-test/node_modules/extract-text-webpack-plugin/dist/loader.js&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            options: { omit: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, remove: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          { loader: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;style-loader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            loader: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;css-loader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;            options: { minimize: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, sourceMap: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, importLoaders: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          { loader: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;resolve-url-loader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, options: { sourceMap: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          { loader: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;sass-loader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, options: { sourceMap: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  plugins: [&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      filename: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;[name].[contenthash].css&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      id: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      options: { allChunks: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    { entriesToDelete: [] },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      opts: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        basePath: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;build/&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        publicPath: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/build/&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        fileName: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;manifest.json&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        stripSrc: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        transformExtensions: {},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        writeToFileEmit: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        cache: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      options: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        debug: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        options: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          context: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/Users/modern-js/Code/php/encore-test&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;          output: { path: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/Users/modern-js/Code/php/encore-test/web/build&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        test: {},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      options: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        hashFunction: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;md5&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        hashDigest: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;base64&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        hashDigestLength: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    { algorithm: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;md5&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, digest: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;hex&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      definitions: { $: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;jquery&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, jQuery: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;jquery&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;window.jQuery&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;jquery&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      paths: [&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;**/*&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      options: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        root: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;/Users/modern-js/Code/php/encore-test/web/build&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        verbose: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        allowExternal: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        dry: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    { definitions: { &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;process.env&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;: { NODE_ENV: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;&amp;quot;production&amp;quot;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } } },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    { options: { sourceMap: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; } },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      options: { title: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;Webpack Encore&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      lastBuildSucceeded: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      isFirstBuild: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      compilationSuccessInfo: { messages: [] },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      shouldClearConsole: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      formatters: [&lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      transformers: [&lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      outputPath: &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;web/build&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      friendlyErrorsPlugin: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        compilationSuccessInfo: { messages: [] },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        shouldClearConsole: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        formatters: [&lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;        transformers: [&lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  ],&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  performance: { hints: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  stats: {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    hash: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    version: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    timings: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    assets: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    chunks: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    maxModules: &lt;/span&gt;&lt;span class=&quot;mtk6&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    modules: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    reasons: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    children: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    source: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    errors: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    errorDetails: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    warnings: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;    publicPath: &lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;  resolve: { extensions: [&lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;.js&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;.jsx&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;.vue&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;.ts&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;.tsx&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;], alias: {} },&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Stay tuned for an &lt;a href=&quot;/react-symfony-4-starter-repo/&quot;&gt;upcoming post&lt;/a&gt; where I’ll set up a simple starter repo for Symfony with a React frontend.&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtkb { font-weight: bold; }
  .solarized-dark .mtki { font-style: italic; }
  .solarized-dark .mtk3 { color: #657B83; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk7 { color: #268BD2; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk12 { color: #2AA198; }
  .solarized-dark .mtk5 { color: #B58900; }
  .solarized-dark .mtk6 { color: #D33682; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Git and Mercurial Cheat Sheet]]></title><description><![CDATA[Our team supports a large number of applications, ranging from legacy apps in SVN, to more recent apps in Mercurial, to our latest projects…]]></description><link>https://chriscolborne.com/git-and-mercurial-cheat-sheet/</link><guid isPermaLink="false">https://chriscolborne.com/git-and-mercurial-cheat-sheet/</guid><pubDate>Sun, 01 Feb 2015 12:23:44 GMT</pubDate><content:encoded>&lt;p&gt;Our team supports a large number of applications, ranging from legacy apps in SVN, to more recent apps in Mercurial, to our latest projects in Git.&lt;/p&gt;&lt;p&gt;Inspired by the excellent (but very thorough) &lt;a href=&quot;https://github.com/sympy/sympy/wiki/Git-hg-rosetta-stone&quot;&gt;Mercurial to Git Rosetta stone&lt;/a&gt;, here is a bare bones, back to basics, KISS mapping between Hg and Git of the most common operations I use on a day to day basis.&lt;/p&gt;&lt;h4&gt;Init&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg init&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Add Remote&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;edit paths in .hg/hgrc &lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git remote add origin git@github.com:&amp;lt;username&amp;gt;/&amp;lt;repo-name&amp;gt;.git&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Clone&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg clone &amp;lt;url&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git clone &amp;lt;url&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Pull&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg pull -u&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Push&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg push&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Diff&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg diff&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;br/&gt;OR&lt;br/&gt;&lt;code&gt;git diff HEAD&lt;/code&gt; (to diff both staged and unstaged)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg diff -r 20:21 ./src/filename&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git diff &amp;lt;hash&amp;gt;..&amp;lt;hash&amp;gt; -- ./src/filename&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;... coming ...&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git diff master...&amp;lt;hash&amp;gt;&lt;/code&gt; (to diff RHS with common ancestor)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;See incoming/outgoing commits&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg in&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git fetch &amp;amp;&amp;amp; git log master..FETCH_HEAD&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg out&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git fetch &amp;amp;&amp;amp; git log FETCH_HEAD..master&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Commit&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg ci -m&amp;quot;Commit message&amp;quot;&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git commit -am&amp;quot;Commit message&amp;quot;&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Interactively commit part of working copy&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg record&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git add --patch &amp;amp;&amp;amp; git commit&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Branches&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg branch &amp;lt;branch-name&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git checkout -b &amp;lt;branch-name&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg up &amp;lt;branch-name&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git checkout &amp;lt;branch-name&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg push --new-branch&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git push origin &amp;lt;branch-name&amp;gt; -u&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg branches&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git branch -a&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg commit --close-branch&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;# delete local branch&lt;br/&gt;&lt;code&gt;git branch -d &amp;lt;branch-name&amp;gt;&lt;/code&gt;&lt;br/&gt;then&lt;br/&gt;# delete remote branch (NB the colon)&lt;br/&gt;&lt;code&gt;git push origin :&amp;lt;branch-name&amp;gt;&lt;/code&gt; &lt;br/&gt;also&lt;br/&gt;# remove remote tracking branches that no longer exist&lt;br/&gt;&lt;code&gt;git fetch -p&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;# show commits from branch&lt;br/&gt;&lt;code&gt;hg log -b &amp;lt;branch-name&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git reflog show &amp;lt;branch-name&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Merge&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg merge &amp;lt;branch-name or commit number/hash&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git merge &amp;lt;branch-name or commit hash&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Shelve/stash&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg shelve&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg unshelve&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git stash pop&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Clear working copy&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg up -C&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git checkout -f&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Rollback&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg rollback&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git reset HEAD~&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h4&gt;Remove ignored files that are already committed&lt;/h4&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;hg forget &amp;quot;set:hgignore() and not ignored()&amp;quot;&lt;/code&gt;&lt;/td&gt;&lt;td width=&quot;50%&quot;&gt;&lt;code&gt;git ls-files --ignored --exclude-standard | xargs git rm --cached&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Markdown to Confluence with Ruby and SOAP]]></title><description><![CDATA[This post follows on from my previous post about the SharePoint to Markdown ripper. You can  go back and read it if you'd like . So once I'd…]]></description><link>https://chriscolborne.com/markdown-to-confluence-with-ruby-and-soap/</link><guid isPermaLink="false">https://chriscolborne.com/markdown-to-confluence-with-ruby-and-soap/</guid><pubDate>Sun, 18 Jan 2015 12:23:44 GMT</pubDate><content:encoded>&lt;p&gt;This post follows on from my previous post about the SharePoint to Markdown ripper. You can &lt;a href=&quot;/sharepoint-scraping-with-python-mechanize-and-beautiful-soup/&quot;&gt;go back and read it if you’d like&lt;/a&gt;.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;So once I’d extracted our SharePoint wiki as markdown, it was time to find a way to import that into Confluence.&lt;/p&gt;&lt;p&gt;I’d used the markdown editor of the Insert Markup function which worked great, but for ~300 separate pages, I needed a slightly more efficient method than copy paste into a text box.&lt;/p&gt;&lt;p&gt;My first thought was to try find a SOAP or REST API to perform the page creation. I presumed since the Insert Markup function could do it, there might be an API for it. However I wasn’t able to find anything to provide Markdown page creation. So I needed to find another answer.&lt;/p&gt;&lt;p&gt;I found a GitHub repo for a &lt;a href=&quot;https://github.com/LanyonM/markdown-to-confluence-uploader&quot;&gt;markdown to confluence uploader&lt;/a&gt; designed to import a single markdown file into an existing page using the Confluence SOAP api.&lt;/p&gt;&lt;p&gt;Obviously I needed something to iterate through a directory of files, and to create, rather than use an existing page, but it seemed like a good start.&lt;/p&gt;&lt;p&gt;So I &lt;a href=&quot;https://github.com/zorfling/markdown-to-confluence-uploader&quot;&gt;forked the repo&lt;/a&gt; and added an option to provide a parent page to house the newly created pages.&lt;/p&gt;&lt;p&gt;I then used awk and xargs to iterate through the files importing under a page I’d created for the legacy wiki.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;bash&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;ls output/ &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; awk &lt;/span&gt;&lt;span class=&quot;mtk12&quot;&gt;&amp;#x27;{ print &amp;quot;output/&amp;quot; $1 }&amp;#x27;&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; xargs -I {} ./md2confl.rb -s SS -c http://myconfluence.net -t1671258 --markdownFile {}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This imported my 300 legacy SharePoint pages into Confluence in a flash.&lt;/p&gt;&lt;p&gt;However, there were some conversion issues, so this is still a work in progress.&lt;/p&gt;&lt;p&gt;The script I forked uses the &lt;a href=&quot;https://github.com/jedi4ever/markdown2confluence&quot;&gt;markdown2confluence&lt;/a&gt; gem, which by it’s own admission is not a 100% conversion.&lt;/p&gt;&lt;p&gt;In fact there is an &lt;a href=&quot;https://github.com/jedi4ever/markdown2confluence/issues/3&quot;&gt;outstanding issue&lt;/a&gt; regarding the nested list problem that I faced on the gem’s GitHub page. I intend to fork and submit a pull request to solve this issue when I get a chance.&lt;/p&gt;&lt;p&gt;All in all, this gets me almost to the point of being able to move across to Confluence. I hope it might help someone else in the same boat.&lt;/p&gt;&lt;h2&gt;Get the source&lt;/h2&gt;&lt;p&gt;Fork or clone the markdown to confluence uploader on &lt;a href=&quot;https://github.com/zorfling/markdown-to-confluence-uploader&quot;&gt;GitHub&lt;/a&gt;. Issues and pull requests welcome!&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk12 { color: #2AA198; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Sharepoint Scraping with Python, Mechanize, and Beautiful Soup]]></title><description><![CDATA[Over the Christmas break, I decided to write a SharePoint scraper in Python. At work we have a SharePoint based wiki that is universally…]]></description><link>https://chriscolborne.com/sharepoint-scraping-with-python-mechanize-and-beautiful-soup/</link><guid isPermaLink="false">https://chriscolborne.com/sharepoint-scraping-with-python-mechanize-and-beautiful-soup/</guid><pubDate>Sun, 11 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Over the Christmas break, I decided to write a SharePoint scraper in Python.&lt;/p&gt;&lt;p&gt;At work we have a SharePoint based wiki that is universally disliked and thus is poorly used despite containing a lot of useful information. I’ve been trialling Atlassian Confluence as a replacement and it seems a much better solution. However we don’t want to run multiple wikis so I’ll need to copy the existing data across.&lt;/p&gt;&lt;p&gt;Gaining permission to use any APIs that SharePoint might expose over the Christmas break was obviously not going to happen, so I decided to use Python and Mechanize to scrape the wiki.&lt;/p&gt;&lt;h2&gt;Problem 1 - Authentication&lt;/h2&gt;&lt;p&gt;After some quick research, I found our SharePoint instance doesn’t accept basic authentication, but rather only uses the proprietary NTLM protocol.&lt;/p&gt;&lt;p&gt;I found a Python module, &lt;a href=&quot;https://code.google.com/p/python-ntlm/&quot;&gt;python-ntlm&lt;/a&gt;, which provided an authentication handler for NTLM.&lt;/p&gt;&lt;p&gt;Following some discussion on Stack Overflow &lt;a href=&quot;http://stackoverflow.com/a/6029776/269297&quot;&gt;here&lt;/a&gt;, I was able to hook the NTLM handler up to the Mechanize module.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;python&quot; data-index=&quot;0&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; mechanize&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk9&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; ntlm &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; HTTPNtlmAuthHandler&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;passman &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; mechanize.HTTPPasswordMgrWithDefaultRealm()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;passman.add_password(&lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;, url, user, password)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# create the NTLM authentication handler&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;auth_NTLM &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk3 mtki&quot;&gt;# create and install the opener&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;browser &lt;/span&gt;&lt;span class=&quot;mtk9&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt; mechanize.Browser()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;browser.add_handler(auth_NTLM)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;browser.open(url)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I ran into a couple of hurdles with this approach.&lt;/p&gt;&lt;p&gt;Firstly, Mechanize correctly follows the robots.txt. However, since this is a once off scrape off our own site, I was happy to &lt;a href=&quot;http://stackoverflow.com/questions/2846105/screen-scraping-getting-around-http-error-403-request-disallowed-by-robots-tx&quot;&gt;bypass the robots.txt&lt;/a&gt;.&lt;/p&gt;&lt;pre class=&quot;grvsc-container solarized-dark&quot; data-language=&quot;python&quot; data-index=&quot;1&quot;&gt;&lt;code class=&quot;grvsc-code&quot;&gt;&lt;span class=&quot;grvsc-line&quot;&gt;&lt;span class=&quot;grvsc-source&quot;&gt;&lt;span class=&quot;mtk1&quot;&gt;browser.set_handle_robots(&lt;/span&gt;&lt;span class=&quot;mtk5&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;mtk1&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Secondly, Mechanize seems to have a bug when using NTLM authentication. With a patch described &lt;a href=&quot;http://stackoverflow.com/a/14726708/269297&quot;&gt;here&lt;/a&gt;, I was able to get Mechanize up and running. A &lt;a href=&quot;https://github.com/jjlee/mechanize/issues/88&quot;&gt;pull request&lt;/a&gt; is open on GitHub, however it hasn’t been merged.&lt;/p&gt;&lt;h2&gt;Problem 2 - Traversing and filtering the tree&lt;/h2&gt;&lt;p&gt;Since SharePoint HTML is, well … not pretty, not to mention there’s a bunch of site chrome we don’t want to scrape, I needed to do some cleansing.&lt;/p&gt;&lt;p&gt;I used the module &lt;a href=&quot;http://www.crummy.com/software/BeautifulSoup/&quot;&gt;Beautiful Soup&lt;/a&gt; to filter the tree and clean up the code.&lt;/p&gt;&lt;p&gt;Beautiful Soup’s tagline reads as follows:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;You didn’t write that awful page. You’re just trying to get some data out of it. Beautiful Soup is here to help.
And that certainly fit my use case.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I filtered to within a particular div (the obviously named &lt;code&gt;ctl00_PlaceHolderMain_WikiField&lt;/code&gt; for those of you playing at home) that excluded all the extraneous SharePoint navigation stuff.&lt;/p&gt;&lt;p&gt;Beautiful Soup can use a number of &lt;a href=&quot;http://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser&quot;&gt;different parsers&lt;/a&gt;, depending on your usage.&lt;/p&gt;&lt;p&gt;I started off using the default Python &lt;code&gt;html.parser&lt;/code&gt;, however the SharePoint code was too dirty for it, and it fell down on a number of pages. So I changed to the much more permissive &lt;code&gt;html5lib&lt;/code&gt; and found all of my pages scraped correctly.&lt;/p&gt;&lt;p&gt;Once I’d filtered and scraped my pages, I had more or less well formed HTML of the page content only, which led to my final challenge.&lt;/p&gt;&lt;p&gt;I then recursively iterated through each of the links parsing local SharePoint links.&lt;/p&gt;&lt;h2&gt;Problem 3 - Converting to Markdown&lt;/h2&gt;&lt;p&gt;I decided early on that converting to Markdown would probably be a good idea. This would allow me to strip it back to basics, getting rid of the nasty font tags, inline styles, and other junk that had polluted the SharePoint pages.&lt;/p&gt;&lt;p&gt;This proved to be a pretty easy task. I used the &lt;a href=&quot;https://github.com/aaronsw/html2text&quot;&gt;html2markdown&lt;/a&gt; module.&lt;/p&gt;&lt;p&gt;I ran my newly well formed HTML through it and voila, Markdown!&lt;/p&gt;&lt;h2&gt;Get the source&lt;/h2&gt;&lt;p&gt;Fork or clone the sharepoint-ripper on &lt;a href=&quot;https://github.com/zorfling/sharepoint-ripper&quot;&gt;GitHub&lt;/a&gt;. Issues and pull requests welcome!&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;Stay tuned for my &lt;a href=&quot;/markdown-to-confluence-with-ruby-and-soap/&quot;&gt;next post&lt;/a&gt; where I import the exported Markdown into Confluence.&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
  .solarized-dark { background-color: #002B36; }
  .solarized-dark .mtki { font-style: italic; }
  .solarized-dark .mtk9 { color: #859900; }
  .solarized-dark .mtk1 { color: #93A1A1; }
  .solarized-dark .mtk5 { color: #B58900; }
  .solarized-dark .mtk3 { color: #657B83; }
  .solarized-dark .grvsc-line-highlighted::before {
    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));
    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));
  }
&lt;/style&gt;</content:encoded></item><item><title><![CDATA[Hello World!]]></title><description><![CDATA[Hi everyone, I'm Chris. I'm a Software Engineer in Brisbane, Australia. As 2015 begins, I've decided to start a blog showcasing some of my…]]></description><link>https://chriscolborne.com/hello-world/</link><guid isPermaLink="false">https://chriscolborne.com/hello-world/</guid><pubDate>Fri, 02 Jan 2015 08:01:37 GMT</pubDate><content:encoded>&lt;p&gt;Hi everyone, I’m Chris. I’m a Software Engineer in Brisbane, Australia.&lt;/p&gt;&lt;p&gt;As 2015 begins, I’ve decided to start a blog showcasing some of my work and hobbies here at ChrisColborne.com.&lt;/p&gt;&lt;p&gt;I’ll post a bunch of stuff, but mainly tech.&lt;/p&gt;&lt;style class=&quot;grvsc-styles&quot;&gt;
  .grvsc-container {
    overflow: auto;
    position: relative;
    -webkit-overflow-scrolling: touch;
    padding-top: 1rem;
    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));
    padding-bottom: 1rem;
    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));
    border-radius: 8px;
    border-radius: var(--grvsc-border-radius, 8px);
    font-feature-settings: normal;
    line-height: 1.4;
  }
  
  .grvsc-code {
    display: table;
  }
  
  .grvsc-line {
    display: table-row;
    box-sizing: border-box;
    width: 100%;
    position: relative;
  }
  
  .grvsc-line &amp;gt; * {
    position: relative;
  }
  
  .grvsc-gutter-pad {
    display: table-cell;
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  .grvsc-gutter {
    display: table-cell;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter::before {
    content: attr(data-content);
  }
  
  .grvsc-source {
    display: table-cell;
    padding-left: 1.5rem;
    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));
    padding-right: 1.5rem;
    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));
  }
  
  .grvsc-source:empty::after {
    content: &amp;#x27; &amp;#x27;;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
  }
  
  .grvsc-gutter + .grvsc-source {
    padding-left: 0.75rem;
    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);
  }
  
  /* Line transformer styles */
  
  .grvsc-has-line-highlighting &amp;gt; .grvsc-code &amp;gt; .grvsc-line::before {
    content: &amp;#x27; &amp;#x27;;
    position: absolute;
    width: 100%;
  }
  
  .grvsc-line-diff-add::before {
    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));
  }
  
  .grvsc-line-diff-del::before {
    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));
  }
  
  .grvsc-line-number {
    padding: 0 2px;
    text-align: right;
    opacity: 0.7;
  }
  
&lt;/style&gt;</content:encoded></item></channel></rss>