<?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: Ankeet Maini</title>
    <description>The latest articles on DEV Community by Ankeet Maini (@ankeetmaini).</description>
    <link>https://dev.to/ankeetmaini</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%2F164133%2F89e6e5c9-0386-4961-888f-de29013d44a5.jpg</url>
      <title>DEV Community: Ankeet Maini</title>
      <link>https://dev.to/ankeetmaini</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ankeetmaini"/>
    <language>en</language>
    <item>
      <title>Part 1 - Going deeper into MongoDB</title>
      <dc:creator>Ankeet Maini</dc:creator>
      <pubDate>Mon, 14 Dec 2020 04:51:09 +0000</pubDate>
      <link>https://dev.to/ankeetmaini/part-1-going-deeper-into-mongodb-2h59</link>
      <guid>https://dev.to/ankeetmaini/part-1-going-deeper-into-mongodb-2h59</guid>
      <description>&lt;p&gt;I've been using &lt;code&gt;MongoDB&lt;/code&gt; for quite some time on and off but I always resort to Google every time I've to use it. I now have a use-case where just the basics won't get me far and I'll have to understand the underlying tech to take advantage of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying it and installing
&lt;/h2&gt;

&lt;p&gt;Since I just want to try it out, using a Docker image makes perfect sense. No installation required and hence no clean-up too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container run &lt;span class="nt"&gt;--name&lt;/span&gt; mongo mongo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start the docker container (name &lt;code&gt;mongo&lt;/code&gt;) which will have the &lt;code&gt;MongoDB&lt;/code&gt; installed. To use the mongo shell I'll open another terminal instance and just &lt;code&gt;exec&lt;/code&gt; or ssh into the above container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; mongo /bin/bash
root@46abee94ab0c:/# mongo
MongoDB shell version v4.4.2
&lt;span class="c"&gt;# rest of the startup logs omitted for brevity&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Wow, we're in!&lt;/p&gt;

&lt;p&gt;Before we dive into the shell and try commands, lets take a brief look into whats and whys of &lt;code&gt;MongoDB&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  NoSQL database
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;MongoDB&lt;/code&gt; is a nosql database. That means that there're no tables, rows or foreign key relationships in quite the same manner they are in relational databases like &lt;code&gt;MySQL&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;It's a document store, which means you can store documents inside it directly. A &lt;code&gt;document&lt;/code&gt; doesn't mean a literal file here. It means a &lt;code&gt;JSON&lt;/code&gt; object.&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jonas Kahnwald"&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;Above is an example of a document.&lt;/p&gt;

&lt;p&gt;In a SQL database, data is stored in a &lt;code&gt;table&lt;/code&gt; and a table is made of &lt;code&gt;rows&lt;/code&gt;. Each row has a fixed number of columns.&lt;/p&gt;

&lt;p&gt;Similarly, in NoSQL database, the data is stored in &lt;code&gt;collections&lt;/code&gt;, where each collection is made of &lt;code&gt;documents&lt;/code&gt;. There's no restriction that each document should contain the same attributes or columns as in a relational database.&lt;/p&gt;

&lt;p&gt;So this can be done in a NoSQL DB like MongoDB&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jonas Kahnwald"&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;"favouriteFood"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Croissants"&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;Not that I'm recommending of doing this (having disjoint attribute names for every document) but you can do it.&lt;/p&gt;

&lt;p&gt;The benefit of this is in future if your data model changes, you can change the document structure without migrating the old data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://postimg.cc/0rtNZ69B"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DvQGtmwD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.postimg.cc/PrH8XZ9T/Untitled-2020-12-13-2113.png" alt="Untitled-2020-12-13-2113.png" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;showing co-relations between a SQL and a NoSQL database&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  mongo shell
&lt;/h2&gt;

&lt;p&gt;As shown above the shell of MongoDB isn't just like a regular database shell. It can even run JavaScript inside it.&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="o"&gt;&amp;gt;&lt;/span&gt; 0.1 + 0.2
0.30000000000000004
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;LOL, the best way to test JS&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;By default when you connect to a &lt;code&gt;Mongo Shell&lt;/code&gt; and don't specify a db name, it connects to &lt;code&gt;test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can check this by typing db and seeing the value.&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="o"&gt;&amp;gt;&lt;/span&gt; db
&lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can access all the collections, documents from the keyword &lt;code&gt;db&lt;/code&gt;. It holds the currently selected database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operations (CRUD)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  create
&lt;/h3&gt;

&lt;p&gt;Since the database is empty, I'll start by adding something to it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a collection (empty)&lt;/li&gt;
&lt;li&gt;add a document inside it using &lt;code&gt;insertOne&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;done!
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# create an empty collection - food&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.food
test.food

&lt;span class="c"&gt;# create a document inside the food collection&lt;/span&gt;
&lt;span class="c"&gt;# db.food makes sure the document is&lt;/span&gt;
&lt;span class="c"&gt;# added inside the `food` collection&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.food.insertOne&lt;span class="o"&gt;({&lt;/span&gt;name: &lt;span class="s1"&gt;'Croissant'&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"acknowledged"&lt;/span&gt; : &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"insertedId"&lt;/span&gt; : ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64dabed36a5727cf5a243"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;There's another method &lt;code&gt;insertMany&lt;/code&gt; which as you correctly guessed inserts multiple documents in one go.&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="o"&gt;&amp;gt;&lt;/span&gt; db.food.insertMany&lt;span class="o"&gt;([{&lt;/span&gt;name: &lt;span class="s2"&gt;"Samosa"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;name: &lt;span class="s2"&gt;"Jalebi"&lt;/span&gt;&lt;span class="o"&gt;}])&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"acknowledged"&lt;/span&gt; : &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"insertedIds"&lt;/span&gt; : &lt;span class="o"&gt;[&lt;/span&gt;
        ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64f09016e04b26b6fbfa9"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;,
        ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64f09016e04b26b6fbfaa"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  read
&lt;/h3&gt;

&lt;p&gt;There are two methods to read.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;findOne&lt;/li&gt;
&lt;li&gt;find (for finding all documents)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.food.findOne&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"_id"&lt;/span&gt; : ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64dabed36a5727cf5a243"&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;"Croissant"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.food.find&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"_id"&lt;/span&gt; : ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64dabed36a5727cf5a243"&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;"Croissant"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"_id"&lt;/span&gt; : ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64f09016e04b26b6fbfa9"&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;"Samosa"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"_id"&lt;/span&gt; : ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64f09016e04b26b6fbfaa"&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;"Jalebi"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can also pass a search criteria to find a particular document too.&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="o"&gt;&amp;gt;&lt;/span&gt; db.food.find&lt;span class="o"&gt;({&lt;/span&gt; name: &lt;span class="s2"&gt;"Samosa"&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"_id"&lt;/span&gt; : ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64f09016e04b26b6fbfa9"&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;"Samosa"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  update
&lt;/h3&gt;

&lt;p&gt;This will be covered in part 2, something for you to comeback and subscribe.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;genius skills for making you subscribe and bookmark :P&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  delete
&lt;/h3&gt;

&lt;p&gt;Again, there are two ways you can delete&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deleteOne&lt;/li&gt;
&lt;li&gt;deleteMany&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can pass a matching criteria and all the records will get deleted that fit the criteria with &lt;code&gt;deleteMany&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;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.food.deleteMany&lt;span class="o"&gt;({&lt;/span&gt;name: &lt;span class="s2"&gt;"Samosa"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"acknowledged"&lt;/span&gt; : &lt;span class="nb"&gt;true&lt;/span&gt;, &lt;span class="s2"&gt;"deletedCount"&lt;/span&gt; : 1 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't believe me?&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="o"&gt;&amp;gt;&lt;/span&gt; db.food.find&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"_id"&lt;/span&gt; : ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64dabed36a5727cf5a243"&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;"Croissant"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"_id"&lt;/span&gt; : ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"5fd64f09016e04b26b6fbfaa"&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;"Jalebi"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I told you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If you'd have noticed, I'm sure you'd have that a special attribute &lt;code&gt;_id&lt;/code&gt; gets added to each record. If you pass it yourself, it'll be honoured else Mongo will create one for you. No two records can have the same &lt;code&gt;_id&lt;/code&gt;. I think that was obvious and I could've saved those free extra keystrokes, but I'm nice :P&lt;/li&gt;
&lt;li&gt;Since all is JavaScript, you can just write the name of the function to see what it does
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.food.insertOne
&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;document, options&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    var opts &lt;span class="o"&gt;=&lt;/span&gt; Object.extend&lt;span class="o"&gt;({}&lt;/span&gt;, options &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    // Add _id ObjectId &lt;span class="k"&gt;if &lt;/span&gt;needed
    document &lt;span class="o"&gt;=&lt;/span&gt; this.addIdIfNeeded&lt;span class="o"&gt;(&lt;/span&gt;document&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    // Get the write concern
    var writeConcern &lt;span class="o"&gt;=&lt;/span&gt; this._createWriteConcern&lt;span class="o"&gt;(&lt;/span&gt;opts&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    // Result
    var result &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;acknowledged: &lt;span class="o"&gt;(&lt;/span&gt;writeConcern &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; writeConcern.w &lt;span class="o"&gt;==&lt;/span&gt; 0&lt;span class="o"&gt;)&lt;/span&gt; ? &lt;span class="nb"&gt;false&lt;/span&gt; : &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    // Use bulk operation API already &lt;span class="k"&gt;in &lt;/span&gt;the shell
    var bulk &lt;span class="o"&gt;=&lt;/span&gt; this.initializeOrderedBulkOp&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    bulk.insert&lt;span class="o"&gt;(&lt;/span&gt;document&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c"&gt;# removed rest for brevity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;OMG! I know right!&lt;/p&gt;
&lt;/blockquote&gt;

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

</description>
      <category>mongodb</category>
    </item>
    <item>
      <title>How I wrote and self-published my ebook!</title>
      <dc:creator>Ankeet Maini</dc:creator>
      <pubDate>Mon, 05 Oct 2020 04:58:42 +0000</pubDate>
      <link>https://dev.to/ankeetmaini/how-i-wrote-and-self-published-my-ebook-3455</link>
      <guid>https://dev.to/ankeetmaini/how-i-wrote-and-self-published-my-ebook-3455</guid>
      <description>&lt;p&gt;I recently wrote my first e-book &lt;a href="https://www.amazon.in/Building-JavaScript-Promises-steps-know-ebook/dp/B08H8TXPYG/ref=sr_1_2?dchild=1&amp;amp;keywords=js+promises&amp;amp;qid=1601798406&amp;amp;s=digital-text&amp;amp;sr=1-2"&gt;Building JavaScript A+ Promises in 10 steps&lt;/a&gt; and self-published it on both &lt;a href="https://gumroad.com/l/aplus"&gt;Gumroad&lt;/a&gt; and &lt;a href="https://www.amazon.in/Building-JavaScript-Promises-steps-know-ebook/dp/B08H8TXPYG/ref=sr_1_2?dchild=1&amp;amp;keywords=js+promises&amp;amp;qid=1601798406&amp;amp;s=digital-text&amp;amp;sr=1-2"&gt;Amazon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you asked me a month back that would I ever write a book?, I would have answered with a resounding &lt;strong&gt;NO&lt;/strong&gt;. As I thought writing and publishing a book would be so much work and you'd need editors/reviewers and publishing houses to back it!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JavaScript Promises&lt;/code&gt; have always been a fun topic for me and I'd always try and experiment with its gotchas and different ways you can use it to accomplish my use-cases. I also found out that though most people are comfortable in using it well but when it comes to understanding how it's working underneath it wasn't always clear.&lt;/p&gt;

&lt;p&gt;I initially planned on writing a blog on how to create Promises from scratch and what's A+ spec about. I had a fair bit of understanding; how they work internally but when I actually started implementing it, it was truly a humbling process :)&lt;/p&gt;

&lt;p&gt;I was unaware of so many edge-cases and then I started documenting the entire journey of fixing and building and repeat.&lt;/p&gt;

&lt;p&gt;I also did a tiny bit of market research where I wanted to see if building these Promises from scratch was covered but I only found books talking about the usage/patterns and a handful of blogs which taught to create Promises but not from the point of view of A+ spec. I wanted to write an in-depth guide on how they are done with a clean and simplistic implementation that'll stick in the reader's mind for days to come.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is how the book came to be!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How did I write?
&lt;/h2&gt;

&lt;p&gt;I wrote the book using plain markdown in a single file. I used top-level headings to demarcate chapters as it made sense to me at the time.&lt;/p&gt;

&lt;p&gt;It was super easy to use mark-down as I was used to writing a lot of it and there's very less syntax to know. Backticks for code snippets, &lt;code&gt;#&lt;/code&gt; for headings and &lt;code&gt;-&lt;/code&gt; for lists. That's all there's to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How did I get the book ready for publishing?
&lt;/h2&gt;

&lt;p&gt;I initially concentrated on finishing the manuscript and proof-reading it for flows and making sure I was covering all concepts in a clear and chronological way.&lt;/p&gt;

&lt;p&gt;Once I was satisfied with the content I turned to my &lt;code&gt;google-fu&lt;/code&gt; skills to see what all formats do I need to support. So there're three primary formats that you should take care of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pdf&lt;/li&gt;
&lt;li&gt;epub&lt;/li&gt;
&lt;li&gt;mobi (for Kindles)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used &lt;code&gt;pandoc&lt;/code&gt; to create the books from markdown with a little bit of customization.&lt;/p&gt;

&lt;h3&gt;
  
  
  pdf
&lt;/h3&gt;

&lt;p&gt;Using plain &lt;code&gt;pandoc&lt;/code&gt; wasn't giving me what I wanted. So I used the amazing &lt;a href="https://github.com/Wandmalfarbe/pandoc-latex-template"&gt;Eisvogel template&lt;/a&gt; to get a nice looking pdf book.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please read the setup instructions which are written in detail in the above Github link.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To make it work, I needed to add a bit of metadata at the top of my source manuscript markdown file. Note the triple dots at the end, they are intended.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
titlepage: true
titlepage-rule-height: 0
titlepage-background: "cover.png"
toc-own-page: true
listings-disable-line-numbers: true
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This created &lt;code&gt;table-of-contents&lt;/code&gt; into a separate page and added a cover pic which I self-designed on &lt;a href="https://www.canva.com"&gt;Canva&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There was one more issue; since my entire manuscript was just in one big markdown file and the individual chapters were demarcated by a top-level heading. Pandoc was generating the &lt;code&gt;pdf&lt;/code&gt; file where the chapters didn't start from a new page, they seemed to be rendered in continuous with the previous content.&lt;/p&gt;

&lt;p&gt;To fix this I had to add this line before each top level heading &lt;code&gt;\newpage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Top-level heading means the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\newpage
# This is a top level heading
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The command to generate the final &lt;code&gt;pdf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pandoc index.md -o "Building A+ Promises.pdf" --from markdown --template eisvogel --listings --pdf-engine=/Library/TeX/texbin/pdflatex --toc --toc-depth 2 -N
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  epub
&lt;/h3&gt;

&lt;p&gt;This is needed for ebook readers, I used my Mac's &lt;code&gt;Books.app&lt;/code&gt; to test.&lt;/p&gt;

&lt;p&gt;The procedure is almost same but a different way of configuration. The &lt;code&gt;metadata&lt;/code&gt; is removed from the top of the file and added separately in a &lt;code&gt;yaml&lt;/code&gt; file. I also removed the &lt;code&gt;\newpage&lt;/code&gt; tags as it was only for the pdf template.&lt;/p&gt;

&lt;p&gt;The command to build epub file that I used&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pandoc index.md -o "Building A+ Promises.epub" --from gfm --listings  --toc --toc-depth 2 -N  --metadata-file metadata.txt --css syles.css --epub-cover-image=cover.png

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



&lt;p&gt;You can pass a stylesheet to this to style some components. I used the following css file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;247&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;247&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;247&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;pre&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;247&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;247&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;247&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I only wanted to add a slight highlight to the code snippets which the plain &lt;code&gt;pandoc&lt;/code&gt; was not adding.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;metadata.txt&lt;/code&gt; looked like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;title:
- type: main
  text: Building JavaScript A+ Promises in 10 steps!
creator:
- role: author
  text: Ankeet Maini
identifier:
date: 2020-08-29
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  mobi
&lt;/h3&gt;

&lt;p&gt;This was the easiest to do. I logged into Amazon's Kindle Self Publishing portal. I uploaded the above generated &lt;code&gt;epub&lt;/code&gt; and it converted it to a compatible &lt;code&gt;mobi&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;That's all for this one, if you've read my book reviews would be amazing :)&lt;/p&gt;

&lt;p&gt;Please post it on Amazon listing or send me direct feedback and I'll be happy to hear.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://ankeetmaini.dev/how-I-wrote-and-published-my-ebook"&gt;https://ankeetmaini.dev/how-I-wrote-and-published-my-ebook&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>promises</category>
      <category>ebook</category>
      <category>selfpublishing</category>
    </item>
  </channel>
</rss>
