<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Brian Olore</title>
    <description>The latest articles on DEV Community by Brian Olore (@olore).</description>
    <link>https://dev.to/olore</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F327778%2F9cd4f469-6d7d-4f6e-9852-ae1e03215a43.jpg</url>
      <title>DEV Community: Brian Olore</title>
      <link>https://dev.to/olore</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olore"/>
    <language>en</language>
    <item>
      <title>Peeking at Slack with CDP</title>
      <dc:creator>Brian Olore</dc:creator>
      <pubDate>Sun, 11 Apr 2021 12:33:36 +0000</pubDate>
      <link>https://dev.to/olore/peeking-at-slack-with-cdp-3hal</link>
      <guid>https://dev.to/olore/peeking-at-slack-with-cdp-3hal</guid>
      <description>&lt;p&gt;CDP, or &lt;a href="https://chromedevtools.github.io/devtools-protocol/"&gt;Chrome DevTools Protocol&lt;/a&gt;, is pretty neat, check this out -&lt;/p&gt;

&lt;p&gt;Warning: OSX paths, your OS &lt;del&gt;may&lt;/del&gt; will vary&lt;/p&gt;

&lt;p&gt;From the Terminal, start Slack with&lt;br&gt;&lt;br&gt;
&lt;code&gt;/Applications/Slack.app/Contents/MacOS/Slack --remote-debugging-port=21212&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;From the Terminal, start Chrome with&lt;br&gt;&lt;br&gt;
&lt;code&gt;/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome http://localhost:21212 --remote-debugging-port 21212&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then click the link that shows the open channel and open DevTools, and switch to the Network tab.&lt;br&gt;&lt;br&gt;
Next, click on the network request that opens the websocket as shown here:&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9UmvVziE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brian.olore.net/wp/images/network-tab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9UmvVziE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brian.olore.net/wp/images/network-tab.png" alt="Find the 'websocket' request" width="880" height="729"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on any of the Messages and see the contents! &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jNf6QubM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brian.olore.net/wp/images/websocket-messages.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jNf6QubM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://brian.olore.net/wp/images/websocket-messages.png" alt="Click to see the contents of any Message" width="880" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: some are more interesting than others.&lt;/p&gt;

&lt;p&gt;This is the first time I opened Slack from the command line, it is also interesting to read the logs as you take various actions within Slack. I’m definitely curious about whatever &lt;code&gt;ublockworkaround.history&lt;/code&gt; is!&lt;/p&gt;

</description>
      <category>cdp</category>
      <category>chrome</category>
      <category>slack</category>
    </item>
    <item>
      <title>OpenAPI/Swagger – Tweaking your JSON output</title>
      <dc:creator>Brian Olore</dc:creator>
      <pubDate>Mon, 03 Aug 2020 13:37:11 +0000</pubDate>
      <link>https://dev.to/olore/openapi-swagger-tweaking-your-json-output-khn</link>
      <guid>https://dev.to/olore/openapi-swagger-tweaking-your-json-output-khn</guid>
      <description>&lt;p&gt;Cover Image by &lt;a href="https://pixabay.com/users/cwright1-2384423/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1326038"&gt;cwright1&lt;/a&gt; from &lt;a href="https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1326038"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week I got my first chance to use the &lt;a href="https://www.openapis.org/"&gt;OpenAPI&lt;/a&gt; spec, you might have heard it called &lt;a href="https://swagger.io/"&gt;Swagger&lt;/a&gt;. It’s a common way to define APIs. It’s great because it can autogenerate both client and server code, and even documentation on how to use the API that you create.&lt;/p&gt;

&lt;p&gt;There is plenty to read about OpenAPI/Swagger, but I want to focus on one particular part that I struggled a bit with and talk through how I reconciled it.&lt;/p&gt;

&lt;p&gt;Our application, like most these days, is expected to consume and produce JSON. This is no problem for OpenAPI/Swagger because it allows you to define &lt;a href="https://swagger.io/docs/specification/media-types/"&gt;Media Types&lt;/a&gt; as part of the definition. So you can easily return JSON, XML, or anything else.&lt;/p&gt;

&lt;p&gt;I needed to return a list of Groups. For this writing, I will simplify the Group such that it only has a “name” and a “description”. So, if you look at the example on the Swagger site you can see how to &lt;a href="https://swagger.io/docs/specification/data-models/data-types/#array"&gt;define an array&lt;/a&gt;. It looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type: array
items:
  type: object
  properties:
    id:
      type: integer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, for our list of Groups, we’ll tweak this to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type: array
items:
  type: object
  properties:
    name:
      type: string
    description:
      type: string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would produce JSON output that looks like the following :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[{
  "name": "MyName",
  "description": "Test description"
}, {
  "name": "Other Group",
  "description": "Test 123"
}]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not bad!&lt;/p&gt;

&lt;p&gt;But then I realized, I don’t want my JSON output to be a top-level Array. I always prefer to return Objects. This makes it easier to modify down the line if I need to add additional fields, like additional Objects/Arrays, etc. An example would be some metadata about the response, such as how long the request took, or how many total Groups there are.&lt;/p&gt;

&lt;p&gt;I had trouble finding any rules that say “Don’t return an Array”. The closest thing i could find was &lt;a href="https://restfulapi.net/introduction-to-json/"&gt;this REST site&lt;/a&gt; that shows Objects being returned. Since this is what I’ve grown accustomed to, &lt;strong&gt;and&lt;/strong&gt; because this is how &lt;a href="https://miragejs.com/"&gt;Mirage JS&lt;/a&gt; returns its data, I figured I was on a good path.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have any links or documentation that talks about Best Practices around JSON Arrays, please share in the comments below!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, what I really want my data to look like is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "groups": [{
    "name": "MyName",
    "description": "Test description"
  }, {
    "name": "Other Group",
    "description": "Test 123"
  }]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make this happen, we need to tweak our YAML a bit. We’ll introduce an Object that wraps the Array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type: object
properties:
  groups:
    type: array
    items:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you have it! The JSON that is returned is an Object with a “groups” Array ! Once I change my client code to use &lt;strong&gt;response.groups&lt;/strong&gt; instead of &lt;strong&gt;response&lt;/strong&gt; , everything works as expected.&lt;/p&gt;

&lt;p&gt;I hope this has been helpful. I’ve written my own JSON responses in various languages, not really thinking too much about it. I now see the benefit of OpenAPI/Swagger, as it provides a robust, language agnostic, way to describe and define your APIs. This is especially important in a large enterprise. I expect to be doing a lot more with it in the future. Thanks for stopping by!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://brian.olore.net/wp/2020/08/openapi-swagger-tweaking-your-json-output/"&gt;OpenAPI/Swagger – Tweaking your JSON output&lt;/a&gt; appeared first on &lt;a href="https://brian.olore.net"&gt;The Brian Olore Story&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>json</category>
      <category>miragejs</category>
      <category>openapi</category>
      <category>swagger</category>
    </item>
    <item>
      <title>Writing Code</title>
      <dc:creator>Brian Olore</dc:creator>
      <pubDate>Mon, 01 Jun 2020 01:55:04 +0000</pubDate>
      <link>https://dev.to/olore/writing-code-3l55</link>
      <guid>https://dev.to/olore/writing-code-3l55</guid>
      <description>&lt;p&gt;Tap, tap tap. I clack away on my keyboard.&lt;br&gt;
Red. Green. Refactor.  Sometimes it's that simple.&lt;br&gt;
But more often, it's not that easy.&lt;/p&gt;

&lt;p&gt;Giving up is not an option. I'm so close. I must push through.&lt;br&gt;
Try this, try that, nothing is working.&lt;/p&gt;

&lt;p&gt;Add some logging. Looks like what I expected.&lt;br&gt;
Breakpoints? Oh that would be nice, but I never set that up.&lt;br&gt;
Now's not the time, let's put in some more debug messages.&lt;/p&gt;

&lt;p&gt;More of the same, this isn't helping.&lt;br&gt;
Get up, walk away, drink some water.&lt;br&gt;
Wait! I think I know what it is, let's take another look.&lt;/p&gt;

&lt;p&gt;Yup that's it. How did I miss it for the last hour?&lt;br&gt;
All because I forgot to return from a map() function.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How do you say ~!@#$%</title>
      <dc:creator>Brian Olore</dc:creator>
      <pubDate>Mon, 27 Apr 2020 21:01:45 +0000</pubDate>
      <link>https://dev.to/olore/how-do-you-say-8jm</link>
      <guid>https://dev.to/olore/how-do-you-say-8jm</guid>
      <description>&lt;p&gt;I had a random thought the other day regarding the characters on the keyboard that us developers use every day. I realized that we probably have very different names and expectations of what each of them are used for, or even call them.&lt;/p&gt;

&lt;p&gt;So I did a quick survey of some non-developer friends and family and here's what I came up with:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Me&lt;/th&gt;
&lt;th&gt;Other&lt;/th&gt;
&lt;th&gt;Others I've heard&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;~&lt;/td&gt;
&lt;td&gt;Tilde&lt;/td&gt;
&lt;td&gt;Tildee, Approximately&lt;/td&gt;
&lt;td&gt;Squiggle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;!&lt;/td&gt;
&lt;td&gt;Exclamation&lt;/td&gt;
&lt;td&gt;Make a Point&lt;/td&gt;
&lt;td&gt;Not, Bang&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;At&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Kill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#&lt;/td&gt;
&lt;td&gt;Pound&lt;/td&gt;
&lt;td&gt;Number, Hashtag&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;td&gt;Dollar&lt;/td&gt;
&lt;td&gt;Money, "String" in Excel&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;%&lt;/td&gt;
&lt;td&gt;Percent&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Mod, Modulus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;^&lt;/td&gt;
&lt;td&gt;Carrot&lt;/td&gt;
&lt;td&gt;Accent&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;amp;&lt;/td&gt;
&lt;td&gt;Ampersand&lt;/td&gt;
&lt;td&gt;And&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;Asterisk&lt;/td&gt;
&lt;td&gt;Star, "Times" in Excel&lt;/td&gt;
&lt;td&gt;Splat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(&lt;/td&gt;
&lt;td&gt;Open Paren&lt;/td&gt;
&lt;td&gt;Left Paren, Quotation Mark&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;)&lt;/td&gt;
&lt;td&gt;Close Paren&lt;/td&gt;
&lt;td&gt;Right Paren, Other end of Question Mark&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;td&gt;Underscore&lt;/td&gt;
&lt;td&gt;Underline&lt;/td&gt;
&lt;td&gt;Lodash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;Plus&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I've combined references to "point", "mark" and "sign". They seem to be used interchangeably.&lt;/p&gt;

&lt;p&gt;Which did I miss? What do you call these characters, and what do you expect them to do? I'll update the table as you comment&lt;/p&gt;

</description>
      <category>keyboard</category>
    </item>
    <item>
      <title>Introducing jaycue – jq in your JS</title>
      <dc:creator>Brian Olore</dc:creator>
      <pubDate>Wed, 11 Mar 2020 16:09:42 +0000</pubDate>
      <link>https://dev.to/olore/introducing-jaycue-jq-in-your-js-1c1o</link>
      <guid>https://dev.to/olore/introducing-jaycue-jq-in-your-js-1c1o</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dnpc1ey6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/olore/jaycue/master/media/logo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dnpc1ey6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/olore/jaycue/master/media/logo.png" alt="jaycue logo" width="804" height="178"&gt;&lt;/a&gt;Shout out to my son for making the logo! Nice work Joseph!&lt;/p&gt;

&lt;p&gt;Previously, I wrote about &lt;a href="https://dev.to/olore/working-with-json-in-javascript-29l8"&gt;how useful lodash&lt;/a&gt; is when working with JSON in JavaScript. Then we took a look at how to deal with JSON from the command line using the &lt;a href="https://dev.to/olore/jq-the-json-cli-tool-2om0"&gt;power of jq.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It should come as no surprise where I’m headed here: &lt;br&gt;
  &lt;strong&gt;I want the power of jq filters in my JavaScript code&lt;/strong&gt;!&lt;/p&gt;
&lt;h2&gt;
  
  
  Off we go
&lt;/h2&gt;

&lt;p&gt;Instead of doing what I normally do: googling to see if it existed, then getting depressed that it wasn’t unique, I decided to just do it. I thought it would be a fun way to do a little test-driven development, which I kinda miss doing.&lt;/p&gt;

&lt;p&gt;I figured that if I could find a way to write a test and run it against my code, grab the output, run it against jq proper, then compare the results, it’d prove that my code was doing what it should.&lt;/p&gt;

&lt;p&gt;I’ve executed shell commands from Node.js before, so it seemed doable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`echo '{"foo": 123}' | jq ".foo"`&lt;/span&gt;
&lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool. That was easy enough. So, in an attempt to make it more generic for a utility method that I can use in the tests, I should be able to do something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`echo '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' | jq "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and pass any JSON string and any filter, then collect up the result, and compare!  &lt;/p&gt;

&lt;p&gt;My goal is to make a function that would allow me to perform an expectation like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myjq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check it out here: &lt;a href="https://github.com/olore/jaycue/blob/master/tests/test-helper.js#L22"&gt;https://github.com/olore/jaycue/blob/master/tests/test-helper.js#L22&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Now that we can test, let’s code!
&lt;/h2&gt;

&lt;p&gt;Once that was in place, it was a matter of choosing which types of filters I wanted to support first. From the documentation, there are A LOT. I decided to go after the ones I would use most often, and expand from there. In particular, there was a single use case I wanted to solve. But to get there, I had to start with the basics.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Basic&lt;/strong&gt; filters could be serviced by &lt;a href="https://www.npmjs.com/package/lodash.get"&gt;lodash.get&lt;/a&gt;. For instance, both &lt;code&gt;versionString&lt;/code&gt; and &lt;code&gt;.versionString&lt;/code&gt; will work with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;lodash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;versionString&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I would just need to chop off the leading period. Something like “name.firstName” would also work with &lt;a href="https://www.npmjs.com/package/lodash.get"&gt;lodash.get&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From there, I started down the list of &lt;a href="https://stedolan.github.io/jq/manual/#Basicfilters"&gt;Basic Filters&lt;/a&gt;. Adding in Array indexing and eventually Select filtering, which was the last piece of the puzzle for the use case I had in mind.   &lt;/p&gt;

&lt;p&gt;Here it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"applicants"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"identities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SSN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"987651234"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;We need to get the &lt;code&gt;number&lt;/code&gt; whose type is “SSN”, if it exists.&lt;br&gt;&lt;br&gt;
We had code that looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ssn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit.applicants[0].identities&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;accum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SSN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;accum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;accum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Whereas, a jq command like this would work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;test.json | jq &lt;span class="s1"&gt;'.applicants[0].identities[] | select(.type=="SSN") .number'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we had &lt;strong&gt;select&lt;/strong&gt; functionality, the above JavaScript code could be replaced with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ssn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.applicants[0].identities[] | select(.type=="SSN") .number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And just like that, we’re successful!&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Please go &lt;a href="https://www.npmjs.com/package/jaycue"&gt;install jaycue&lt;/a&gt; and let me know what you think:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;jaycue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checkout some more great JSON tools:&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/node-jq"&gt;node-jq&lt;/a&gt;&lt;br&gt;
&lt;a href="https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc"&gt;JSONView (Chrome)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/jsonovich/"&gt;JSONovich (Firefox)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A big shout-out to my 13yo son for making the jaycue logo! It was a true, family effort. Nice work Joseph!&lt;/p&gt;

&lt;p&gt;I hope you have found this useful. I’d love to hear about what features of jq you think should be added next. And as always, I’d love to have you contribute to the &lt;a href="https://github.com/olore/jaycue"&gt;jaycue project&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://brian.olore.net/wp/2020/03/introducing-jaycue-jq-in-your-js/"&gt;Introducing jaycue – jq in your JS&lt;/a&gt; appeared first on &lt;a href="https://brian.olore.net"&gt;The Brian Olore Story&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>work</category>
      <category>javascript</category>
      <category>jaycue</category>
      <category>jq</category>
    </item>
    <item>
      <title>jq: The JSON CLI tool</title>
      <dc:creator>Brian Olore</dc:creator>
      <pubDate>Fri, 07 Feb 2020 22:44:09 +0000</pubDate>
      <link>https://dev.to/olore/jq-the-json-cli-tool-2om0</link>
      <guid>https://dev.to/olore/jq-the-json-cli-tool-2om0</guid>
      <description>&lt;p&gt;In Part 1 of &lt;a href="https://dev.to/olore/working-with-json-in-javascript-29l8"&gt;Working with JSON&lt;/a&gt;, we looked at how &lt;a href="https://lodash.com"&gt;lodash&lt;/a&gt; makes manipulating JSON from JavaScript easy. Sometimes we’re working with chunks of JSON and it’s easier to deal with it from the shell. Scenarios like this include digging through log output and that (sometimes painful) time when you are first interacting with a new API.&lt;/p&gt;

&lt;p&gt;Working with JSON in the shell is quicker and easier than trying to create a temporary file in your project or IDE, then writing some JavaScript code to open that file, parse its contents and scan for whatever it is you are looking for. Those of you that are skilled with the &lt;a href="https://nodejs.org/"&gt;Node.js&lt;/a&gt; shell may disagree, but I’m determined to show you something you may not know and hopefully optimize your workflow too!&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello jq
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://stedolan.github.io/jq"&gt;jq&lt;/a&gt; is a CLI (command line interface) for working with JSON. It provides shell friendly features (piping, output redirection, etc) that make it feel as if it’s part of your operating system.   &lt;/p&gt;

&lt;p&gt;To get started, install &lt;code&gt;jq&lt;/code&gt; (on OSX)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or &lt;a href="https://stedolan.github.io/jq/download/"&gt;install it directly&lt;/a&gt; from the site&lt;/p&gt;

&lt;p&gt;Running the &lt;code&gt;jq&lt;/code&gt; command by itself will provide some usage info, but not a ton. You’re going to want to head to the &lt;a href="https://stedolan.github.io/jq/manual/"&gt;online manual&lt;/a&gt;, or the man page (&lt;code&gt;man jq&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s see what &lt;code&gt;jq&lt;/code&gt; can do!
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;jq&lt;/code&gt; is normally invoked by “piping” JSON data to it (using the &lt;code&gt;|&lt;/code&gt; operator). This can be as simple as an echo command. Here we’ll use the &lt;a href="https://stedolan.github.io/jq/manual/#Basicfilters"&gt;simplest filter&lt;/a&gt; &lt;code&gt;.&lt;/code&gt;, “which copies jq’s input to its output”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;echo&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{"name": "Brian"}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;jq&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Brian&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, jq will pretty print and colorize its output. Neat!&lt;/p&gt;

&lt;p&gt;Because it works with pipes, you can also use commands like &lt;code&gt;curl&lt;/code&gt; to get an API response, then pass it through &lt;code&gt;jq&lt;/code&gt; like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://swapi.co/api/people/1/ | jq &lt;span class="s1"&gt;'.'&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Luke Skywalker"&lt;/span&gt;,
  &lt;span class="s2"&gt;"height"&lt;/span&gt;: &lt;span class="s2"&gt;"172"&lt;/span&gt;,
  &lt;span class="s2"&gt;"mass"&lt;/span&gt;: &lt;span class="s2"&gt;"77"&lt;/span&gt;,
  &lt;span class="s2"&gt;"hair_color"&lt;/span&gt;: &lt;span class="s2"&gt;"blond"&lt;/span&gt;,
  &lt;span class="s2"&gt;"skin_color"&lt;/span&gt;: &lt;span class="s2"&gt;"fair"&lt;/span&gt;,
  &lt;span class="s2"&gt;"eye_color"&lt;/span&gt;: &lt;span class="s2"&gt;"blue"&lt;/span&gt;,
  &lt;span class="s2"&gt;"birth_year"&lt;/span&gt;: &lt;span class="s2"&gt;"19BBY"&lt;/span&gt;,
  &lt;span class="s2"&gt;"gender"&lt;/span&gt;: &lt;span class="s2"&gt;"male"&lt;/span&gt;,
  &lt;span class="s2"&gt;"homeworld"&lt;/span&gt;: &lt;span class="s2"&gt;"https://swapi.co/api/planets/1/"&lt;/span&gt;,
  &lt;span class="s2"&gt;"films"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"https://swapi.co/api/films/2/"&lt;/span&gt;,
    &lt;span class="s2"&gt;"https://swapi.co/api/films/6/"&lt;/span&gt;,
    &lt;span class="s2"&gt;"https://swapi.co/api/films/3/"&lt;/span&gt;,
    &lt;span class="s2"&gt;"https://swapi.co/api/films/1/"&lt;/span&gt;,
    &lt;span class="s2"&gt;"https://swapi.co/api/films/7/"&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"species"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"https://swapi.co/api/species/1/"&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"vehicles"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"https://swapi.co/api/vehicles/14/"&lt;/span&gt;,
    &lt;span class="s2"&gt;"https://swapi.co/api/vehicles/30/"&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"starships"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"https://swapi.co/api/starships/12/"&lt;/span&gt;,
    &lt;span class="s2"&gt;"https://swapi.co/api/starships/22/"&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"created"&lt;/span&gt;: &lt;span class="s2"&gt;"2014-12-09T13:50:51.644000Z"&lt;/span&gt;,
  &lt;span class="s2"&gt;"edited"&lt;/span&gt;: &lt;span class="s2"&gt;"2014-12-20T21:17:56.891000Z"&lt;/span&gt;,
  &lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://swapi.co/api/people/1/"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;As you can see this can be very useful when you need a quick sanity check of an API response structure, or if you forget if the key name is &lt;code&gt;eyeColor&lt;/code&gt; or &lt;code&gt;eye_color&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;jq&lt;/code&gt; does more than pretty formatting! It let’s you slice &amp;amp; dice the JSON in many ways. For instance, let’s ask &lt;code&gt;jq&lt;/code&gt; to return &lt;strong&gt;Luke’s&lt;/strong&gt; &lt;code&gt;eye_color&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://swapi.co/api/people/1/ | jq &lt;span class="s1"&gt;'.eye_color'&lt;/span&gt;
&lt;span class="s2"&gt;"blue"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool!&lt;/p&gt;

&lt;p&gt;Thankfully, similar to &lt;a href="https://lodash.com/docs/4.17.15#get"&gt;lodash.get&lt;/a&gt;, if we ask for a path that doesn’t exist, it doesn’t die a horrible death&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://swapi.co/api/people/ | jq &lt;span class="s1"&gt;'.does.not.exist'&lt;/span&gt;
null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let’s get more advanced
&lt;/h2&gt;

&lt;p&gt;What if we wanted to get the &lt;code&gt;eye_color&lt;/code&gt; &lt;strong&gt;of all the people&lt;/strong&gt; (on the first page of results)? Again, &lt;code&gt;jq&lt;/code&gt; provides a syntax similar to &lt;a href="https://lodash.com/docs/4.17.15#get"&gt;lodash.get&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://swapi.co/api/people/ | jq &lt;span class="s1"&gt;'.results[].eye_color'&lt;/span&gt;
&lt;span class="s2"&gt;"blue"&lt;/span&gt;
&lt;span class="s2"&gt;"yellow"&lt;/span&gt;
&lt;span class="s2"&gt;"red"&lt;/span&gt;
&lt;span class="s2"&gt;"yellow"&lt;/span&gt;
&lt;span class="s2"&gt;"brown"&lt;/span&gt;
&lt;span class="s2"&gt;"blue"&lt;/span&gt;
&lt;span class="s2"&gt;"blue"&lt;/span&gt;
&lt;span class="s2"&gt;"red"&lt;/span&gt;
&lt;span class="s2"&gt;"brown"&lt;/span&gt;
&lt;span class="s2"&gt;"blue-gray"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK, let’s see if we can make it work a little harder. Let’s get the &lt;strong&gt;&lt;code&gt;name&lt;/code&gt; of all the people&lt;/strong&gt; (on the first page of results) &lt;strong&gt;that have and &lt;code&gt;eye_color&lt;/code&gt; of blue&lt;/strong&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://swapi.co/api/people/ | jq &lt;span class="s1"&gt;'.results[] | select(.eye_color == "blue") .name'&lt;/span&gt;
&lt;span class="s2"&gt;"Luke Skywalker"&lt;/span&gt;
&lt;span class="s2"&gt;"Owen Lars"&lt;/span&gt;
&lt;span class="s2"&gt;"Beru Whitesun lars"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sweet! This is where the power of &lt;code&gt;jq&lt;/code&gt; really shines. There are many more powerful &lt;a href="https://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions"&gt;filters, operators and functions&lt;/a&gt; I suggest you explore. Hopefully I was able to whet your appetite as this is just the tip of the iceberg of things you can do with &lt;code&gt;jq&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  One more
&lt;/h2&gt;

&lt;p&gt;One last quick tip – this is the one I use for making sense of my JSON log messages all the time. If you are in OSX, you have the ability to access the clipboard from the shell using &lt;a href="http://osxdaily.com/2007/03/05/manipulating-the-clipboard-from-the-command-line/"&gt;pbcopy and pbpaste&lt;/a&gt;. So when I am working with JSON logs, from an application like Splunk, I copy the relevant JSON structure to the clipboard, then run it through &lt;code&gt;jq&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pbpaste | jq &lt;span class="s1"&gt;'.'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pretty printing alone is super useful. On top of that, you have all the great filtering commands to coerce an intimidating log message into a more approachable piece of data!&lt;/p&gt;

&lt;p&gt;Special thanks to &lt;a href="https://swapi.co/"&gt;https://swapi.co/&lt;/a&gt; for providing a fun API to play with!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://brian.olore.net/wp/2020/02/jq-the-json-cli-tool/"&gt;jq: The JSON CLI tool&lt;/a&gt; appeared first on &lt;a href="https://brian.olore.net"&gt;The Brian Olore Story&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>json</category>
      <category>jq</category>
      <category>cli</category>
      <category>shell</category>
    </item>
    <item>
      <title>Working with JSON in JavaScript</title>
      <dc:creator>Brian Olore</dc:creator>
      <pubDate>Wed, 29 Jan 2020 14:14:54 +0000</pubDate>
      <link>https://dev.to/olore/working-with-json-in-javascript-29l8</link>
      <guid>https://dev.to/olore/working-with-json-in-javascript-29l8</guid>
      <description>&lt;p&gt;As software developers, we spend a lot of time parsing JSON, like, &lt;strong&gt;A LOT&lt;/strong&gt;. There are many tools and libraries available to make our development lives easier. This is the first of a 3 part series where I’ll dig a bit into tools and libraries that I use every day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enter lodash&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lodash.com/"&gt;lodash&lt;/a&gt; is a phenomenal JavaScript library that provides incredibly useful functions, most of which should exist in the standard library. So what can it do for JSON? Let’s take a look at the &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;has&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;First up, &lt;a href="https://lodash.com/docs#get"&gt;lodash.get&lt;/a&gt; is the standard for picking through JSON data, or, in fact, any JavaScript object. It allows for easy and safe traversal of nested objects and arrays. &lt;code&gt;get&lt;/code&gt; is “safe”, meaning you won’t get the dreaded &lt;code&gt;Cannot read property 'whatever' of undefined&lt;/code&gt; that can occur when some nested properties are missing. In this case, &lt;code&gt;get&lt;/code&gt; will simply return &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s look at some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The Brian Olore Story&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;articles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;First Post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;published&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tags&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;new&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Why you should TDD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;published&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tags&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tdd&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// simple path traversal&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; 'The Brian Olore Story'&lt;/span&gt;

&lt;span class="c1"&gt;// traverse into arrays&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.articles[1].tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; ["tdd", "dev"]&lt;/span&gt;

&lt;span class="c1"&gt;// path doesn't exist&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.name.rating&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; undefined&lt;/span&gt;

&lt;span class="c1"&gt;// provide a 3rd parameter to be returned if any part of the path is undefined&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.rating&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// =&amp;gt; 100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s take a look at &lt;a href="https://lodash.com/docs#set"&gt;lodash.set&lt;/a&gt;. &lt;code&gt;set&lt;/code&gt; works the same way as &lt;code&gt;get&lt;/code&gt;, but will modify the object passed in. The 3rd parameter is a value to insert/update into the given object. Similar to &lt;code&gt;get&lt;/code&gt;, it’s “safe”, meaning: if a portion of the path doesn’t exist, it will be created. Remember: &lt;code&gt;set&lt;/code&gt; mutates the object passed in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// change the blog name&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My Story&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// set the rating (that didn't previously exist)&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.rating&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// create a whole new path&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.followers.count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, while slightly less used and often overlooked, &lt;a href="https://lodash.com/docs#has"&gt;lodash.has&lt;/a&gt; returns a boolean if the path provided exists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// has a name?&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;// has a rating? (that doesn't exist)&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.rating&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; false&lt;/span&gt;

&lt;span class="c1"&gt;// has a deeply nested value (that doesn't exist)&lt;/span&gt;
&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog.followers[0].name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another great thing about lodash is that you can choose to bring in all lodash functions, or just individual functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// all lodash functions (npm install lodash)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_get&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash.get&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// just the get function (npm install lodash.get)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What tools do you use to traverse the gobs of JSON data we deal with every day?&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://brian.olore.net/wp/2020/01/working-with-json-in-javascript/"&gt;Working with JSON in JavaScript&lt;/a&gt; appeared first on &lt;a href="https://brian.olore.net"&gt;The Brian Olore Story&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>json</category>
      <category>javascript</category>
      <category>lodash</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
