<?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: Doyin Olarewaju 🇳🇬🇨🇦</title>
    <description>The latest articles on DEV Community by Doyin Olarewaju 🇳🇬🇨🇦 (@gate3).</description>
    <link>https://dev.to/gate3</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%2F87702%2Fc94b7733-eb66-43ea-b752-cf8a452d815c.jpg</url>
      <title>DEV Community: Doyin Olarewaju 🇳🇬🇨🇦</title>
      <link>https://dev.to/gate3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gate3"/>
    <language>en</language>
    <item>
      <title>Working with WalletConnect from mobile Dapps (Part 1)</title>
      <dc:creator>Doyin Olarewaju 🇳🇬🇨🇦</dc:creator>
      <pubDate>Tue, 19 Jul 2022 10:24:54 +0000</pubDate>
      <link>https://dev.to/gate3/working-with-walletconnect-from-mobile-dapps-part-1-1njb</link>
      <guid>https://dev.to/gate3/working-with-walletconnect-from-mobile-dapps-part-1-1njb</guid>
      <description>

&lt;p&gt;Wallets are an essential part of the blockchain. They function as a way of storing our web3 assets, as a form of identity, for authentication among others. When building a Dapp knowing how to work with wallets is crucial since it is a big part of the user experience. One area that has not been covered as much is working with wallets when building mobile Dapps and in since our main goal at Weedle is promoting mobile first Dapp development, this seems like a great topic to write about.&lt;/p&gt;

&lt;p&gt;The aim of this tutorial is to cover everything you need to know to effectively add the ability to use wallets to your mobile Dapps. The tutorial will be distributed into parts, with each part taking some more advanced topics than the last.&lt;/p&gt;

&lt;h2&gt;
  
  
  First Some Dependencies
&lt;/h2&gt;

&lt;p&gt;I'm assuming you already have your app ready, if you don't head over to this article to learn how to setup a react native app that is web3 compatible.&lt;/p&gt;

&lt;p&gt;The walletconnect documentation for react native can be found here. According to the docs we need three dependencies, you can go ahead and copy the code below to install them&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add @walletconnect/react-native-dapp react-native-svg @react-native-async-storage/async-storage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;However there is a small issue with this, the types in the async storage library (@react-native-async-storage/async-storage) specified are incompatible with walletconnect. In fact using it directly with a typescript setup will show you an error saying the type is incompatible with walletconnect.&lt;br&gt;
There are a couple of solutions:&lt;/p&gt;
&lt;h3&gt;
  
  
  Option 1
&lt;/h3&gt;

&lt;p&gt;One option (long and difficult way) would be to get the types walletconnect expects and write an adapter that maps to those types. If you want to go via this route, you can find the file with walletconnect typings in a seperate utils github repo here. You can basically create a file and put the types inside it, then use it as the type for your adapter.&lt;/p&gt;
&lt;h3&gt;
  
  
  Option 2(My preferred option)
&lt;/h3&gt;

&lt;p&gt;Is fast and dirty. Basically examining the keyvaluestorage functions from walletconnect you will see that they are not only making use of a very small set of functions from the async storage library. To get the correct types we can use the types referred to in option 1 and just cast it to the asyncStorage props from walletconnect provider.&lt;/p&gt;

&lt;p&gt;I prefer this method since walletconnect isn't using any significant number of functions from the library, so mapping all functions just because a few are being used doesn't make sense to me. This can be seen as a temporary measure at least till this issue has been fixed by the WalletConnect team.&lt;/p&gt;
&lt;h2&gt;
  
  
  Integrate WalletConnect with our App
&lt;/h2&gt;

&lt;p&gt;According to the docs we have two ways of using WalletConnect. We can either use it as a provider or as a Higher order component; lets stick with the provider method. The provider takes a couple of props, but only two of them are compulsory, there are default values provided for the other props which is sufficient for our use case.&lt;/p&gt;

&lt;p&gt;Say our app currently 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;&amp;lt;View style={styles.mainContainer}&amp;gt;
  &amp;lt;MainApp /&amp;gt;
&amp;lt;/View&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To enable wallectconnect, we can just need to wrap the app in its provider like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;WalletConnectProvider
  redirectUrl={`wmw://app`} // Explained below
  storageOptions={{
    asyncStorage: AsyncStorage as unknown as IAsyncStorage,
  }}&amp;gt;
  &amp;lt;View style={styles.mainContainer}&amp;gt;
    &amp;lt;MainApp /&amp;gt;
  &amp;lt;/View&amp;gt;
&amp;lt;/WalletConnectProvider&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The value in the storageOptions was explained earlier, as for the redirectUrl this is a deep link url that walletconnect redirects to after validation. More on that here. My preferred method of handling the redirect url would be to redirect to a view where I can verify if the user has been authenticated or not, preferrably back to the current page where the user tried to login using their wallet.&lt;/p&gt;

&lt;p&gt;Now that we have wrapped our app with the walletconnect provider, lets look at how we can authenticate using walletconnect. To explain this, lets say inside MainApp we have two components, Auth and Dashboard. We want to only show dashboard after authenticating the user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Auth.tsx
import React, {useState} from 'react'
import WalletConnectProvider, { useWalletConnect } from '@walletconnect/react-native-dapp';
...

const Auth = () =&amp;gt; {
  const [isConnected, setIsConnected] = useState&amp;lt;boolean&amp;gt;(false);
  const connector = useWalletConnect(); // Wallet connect hook
  ...

  // Note: for example purposes only, do better and split your components into files properly
  return (
    &amp;lt;View&amp;gt;
    {
      !isConnected ? 
        &amp;lt;View&amp;gt; 
          &amp;lt;Button title='Login' onPress={authenticateUser} /&amp;gt;
        &amp;lt;/View&amp;gt; :
        &amp;lt;Dashboard /&amp;gt;
    }
    &amp;lt;/View&amp;gt;
  )
}

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

&lt;/div&gt;



&lt;p&gt;In the code above, we are doing a couple of things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;useWalletConnect - This hook provides a connector object for us which contains all the functions that we need to use walletconnect.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;isConnected - A state variable we can use to determine if the user has been authenticated or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We are also using a simple button to handle calling a auth function authenticateUser which we will define next.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Auth.tsx

// Our login function looks like this

const authenticateUser = async () =&amp;gt; {
  if (connector.connected) {
    setIsConnected(true)
  }else{
    const session = await connector.connect();
    // The session object will contain details about the chain you are connected to and also an accounts array
    setIsConnected(true)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are first checking if we have already authenticated with the wallet, if that isn't the case then we call .connect to take us through the authentication process with our wallet. What the process looks like is that walletconnect checks for all wallets on our device and displays them in a bottom sheet component, we can then select the specific wallet we want to use (e.g. Metamask, Trust wallet etc). An intent is then created which takes us to the selected wallet for approval, once we approve we are directed back the redirectUrl we provided to walletconnect.&lt;/p&gt;

&lt;p&gt;The authenticate call returns a ISessionStatus type which contains details about the network we are connected to like chainId and also an accounts array which contains our wallet address from the connected wallet.&lt;/p&gt;

&lt;p&gt;The connector object can be retrieved from the useWalletConnect hook at anytime and in any component inside our app. The object contains all we need like our accounts and network information, so we don't really need to store what we get from calling &lt;code&gt;.connect&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling Errors
&lt;/h2&gt;

&lt;p&gt;Awesome, we are almost done but we need to handle some errors, like if the user rejects the auth request. This can be done by wrapping our call to .connect in a simple try catch block 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;// Auth.tsx

// Our login function looks like this

const authenticateUser = async () =&amp;gt; {
  try{
    if (connector.connected) {
      setIsConnected(true)
    }else{
      const session = await connector.connect();
      // The session object will contain details about the chain you are connected to and also an accounts array
      setIsConnected(true)
    }
  }catch(e){
    // handle error here
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Logout Functionality
&lt;/h2&gt;

&lt;p&gt;Say on our lovely dashboard we have a logout button which allows the user disconnect from their wallet from our app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Dasboard.tsx

const Dashboard = async () =&amp;gt; {
  ...

  const logUserOut = async () =&amp;gt; {
    await connector.killSession();
  }

  return (
    &amp;lt;View&amp;gt;
      &amp;lt;Button title='Logout' onPress={logUserOut} /&amp;gt;
      ...
    &amp;lt;/View&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Awesome stuff, we have been able to build a dapp that can authenticate using walletconnect. You should explore the other options from the walletconnect docs like reducing the number of wallets available for auth among others.&lt;br&gt;
Although this is a pretty good starting point but there are several other things we need to do to have a stable and working dapp.&lt;/p&gt;

&lt;p&gt;If you enjoyed this articale or it has been helpful to you in any way. Follow us here and on twitter to get notified when the follow up articles gets published. Cheers&lt;/p&gt;




&lt;p&gt;At weedle labs, we are working on a mobile first web3 infrastructure. The aim is to simplify developing web3 Dapps on mobile and help you reach a much wider audience than what the web can offer. We are open source and are actively looking for contributors to join us in active development. Give us a shout on twitter @weedle_app or &lt;a href="mailto:tech@joinweedle.com"&gt;tech@joinweedle.com&lt;/a&gt;.&lt;br&gt;
If you also wish to know when we launch and get more details, you can check &lt;a href="https://joinweedle.com"&gt;https://joinweedle.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>dapps</category>
      <category>walletconnect</category>
      <category>reactnative</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Tutorial: Setting up a Web3 react native Dapp</title>
      <dc:creator>Doyin Olarewaju 🇳🇬🇨🇦</dc:creator>
      <pubDate>Thu, 07 Jul 2022 00:30:39 +0000</pubDate>
      <link>https://dev.to/gate3/tutorial-setting-up-a-web3-react-native-dapp-96</link>
      <guid>https://dev.to/gate3/tutorial-setting-up-a-web3-react-native-dapp-96</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatomicwallet.io%2Fimages%2Fblog%2Fuploads%2F2019%2F09%2Fdapps-image-twitter.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatomicwallet.io%2Fimages%2Fblog%2Fuploads%2F2019%2F09%2Fdapps-image-twitter.png" alt="Decentralized applications"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Web Dapps are all the rage and there hasn't been as much focus on mobile as it should be. This is with good reason though, since the libraries and cryptographic primitives required for creating a Dapp are not directly compatible with mobile, it can be difficult setting up a mobile app that is Web3 ready. The purpose of this tutorial is to walk you through setting up a react native app that is web3 compatible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;p&gt;If you are lazy (like me), you can just grab a ready made app from &lt;a href="https://github.com/weedle-app/weedle-expo-bare-workflow" rel="noopener noreferrer"&gt;here&lt;/a&gt; and call it a day. But if you wish to learn how to setup yourself you can continue reading.&lt;/p&gt;

&lt;h2&gt;
  
  
  The long version
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setup a react native app
&lt;/h3&gt;

&lt;p&gt;To start the process we need a react native app that has native abilities. You can use either use the expo bare workflow for this or the CRNA (create react native app).&lt;/p&gt;

&lt;p&gt;For the CRNA option:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;npx create-react-native-app my-app&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the expo option: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;npx expo init&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select the last template option (bare minimal)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installing dependencies
&lt;/h3&gt;

&lt;p&gt;To make our app web3 compatible, the first dependency we need is &lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add node-libs-react-native&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;OR&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i node-libs-react-native&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The purpose of this dependency is to get some of the nodejs modules we need to interact with the blockchain into react native. Some of these dependencies are cryptography libraries that will normally not work in react native, but using this package we can make them work in RN.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup App for web3 compatibility
&lt;/h3&gt;

&lt;p&gt;Once its installed, the next thing we need to do is use the library in our metro bundler config. We need to add this module under the &lt;code&gt;extraNodeModules&lt;/code&gt; key, basically what that would be telling metro is that if I request a module and you can't find it in my primary node_modules, check the modules I included in the extraNodeModules. This will help metro find the Nodejs modules we need from the package. The new metro config will look something like this &lt;/p&gt;

&lt;p&gt;For expo&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getDefaultConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&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;expo/metro-config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getDefaultConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;defaultConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extraNodeModules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&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;node-libs-react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defaultConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you prefer you can also use a &lt;strong&gt;rn-cli.config.js&lt;/strong&gt; file (You can create one if it isn't present)&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;extraNodeModules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&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;node-libs-react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;extraNodeModules&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;The final step is to import a file from &lt;code&gt;node-libs-react-native&lt;/code&gt; into the entry point of your app. We need to import &lt;/p&gt;

&lt;p&gt;&lt;code&gt;import 'node-libs-react-native/globals.js';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In expo, this will be the index.js file. This needs to be the very first line in the file. The import brings in all the required modules like the crypto module into our app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web3 Client
&lt;/h3&gt;

&lt;p&gt;Our app is almost ready, but its not completely web3 ready without a web3 client. Two of the most popular ones are Web3.js and ethers.js. For this tutorial we will be going with ethers. &lt;/p&gt;

&lt;p&gt;We need two dependencies&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add ethers @ethersproject/shims&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once installed we need to import the shims package in thesame file where we placed &lt;code&gt;node-libs-react-native/globals.js.&lt;/code&gt; With that, our app is now fully web3 compatible. &lt;/p&gt;

&lt;p&gt;To test out if it works, we can try generating a wallet using ethersjs. In our App.jsx or App.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ethers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRandom&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;walletObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;mnemonic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mnemonic&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all went well, in your console you should see a wallet object and a mnemonic. Just like that you have a web3 compatible react native app.&lt;/p&gt;




&lt;p&gt;At weedle labs, we are working on a mobile first web3 infrastructure. The aim is to simplify developing web3 Dapps on mobile and help you reach a much wider audience than what the web can offer. We are open source and are actively looking for contributors to join us in active development. Give us a shout on twitter @weedle_app or &lt;a href="mailto:tech@joinweedle.com"&gt;tech@joinweedle.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you also wish to know when we launch and get more details, you can check &lt;a href="https://joinweedle.com" rel="noopener noreferrer"&gt;https://joinweedle.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>reactnative</category>
      <category>web3</category>
      <category>dapps</category>
    </item>
    <item>
      <title>How to use a Private git repo as an npm module</title>
      <dc:creator>Doyin Olarewaju 🇳🇬🇨🇦</dc:creator>
      <pubDate>Fri, 06 Dec 2019 02:54:07 +0000</pubDate>
      <link>https://dev.to/gate3/how-to-use-a-private-git-repo-as-an-npm-module-2cl9</link>
      <guid>https://dev.to/gate3/how-to-use-a-private-git-repo-as-an-npm-module-2cl9</guid>
      <description>&lt;p&gt;There are several reasons why you might wish to use a private git repo as an npm module, but of the top of my head, the topmost would be you wish to share some highly confidential business logic code and for some reason, you can't use a private npm registry.&lt;/p&gt;

&lt;p&gt;Well, you are in luck, here is how you go about it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setup the repo
&lt;/h1&gt;

&lt;p&gt;For this article, I will use bitbucket as an example since GitHub is fairly easy. So set up a new project using bitbucket or a git provider of your choice.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setup your project
&lt;/h1&gt;

&lt;p&gt;To start you need a project that contains a minimum of a package.json file. Without the file, the project won't be recognized as a valid package and npm install won't work. You can set that up quickly using the npm command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command above will take you through the steps of setting up a new project. Enter all the information as you wish including the repo URL.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: After setting up the project, you should add &lt;strong&gt;private: true&lt;/strong&gt; to the package.json file to ensure the project does not get published by mistake.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now write your code and push your project to the git repo. &lt;/p&gt;

&lt;h1&gt;
  
  
  Making use of the package
&lt;/h1&gt;

&lt;p&gt;If this were a public repo, you would be done already. But unfortunately it isn't and other steps follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  SSH
&lt;/h2&gt;

&lt;p&gt;There are other authentication methods for authenticating against your git provider to access the repo. You could use HTTP and include your username and password in the URL, or generate a key that can also be used as part of the URL. Both methods are pretty unsafe, as you will be exposing your credentials out in the open.&lt;/p&gt;

&lt;p&gt;The most secure method is, therefore, to authenticate using SSH. Generating an SSH key is out of scope here, but you can take a look at this tutorial&lt;/p&gt;

&lt;p&gt;&lt;a href="https://confluence.atlassian.com/bitbucket/set-up-an-ssh-key-728138079.html#SetupanSSHkey-ssh2"&gt;https://confluence.atlassian.com/bitbucket/set-up-an-ssh-key-728138079.html#SetupanSSHkey-ssh2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After generating the ssh key, save using a name you can remember in a location you can remember. I advise you do not create the key using a password, but it's totally up to you. &lt;/p&gt;

&lt;p&gt;Setup an ssh config file in your ssh directory. The filename is just config, the content should look like this&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
Host bitbucket.org&lt;br&gt;
  Preferredauthentications publickey&lt;br&gt;
  IdentityFile ~/.ssh/bitbucket&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Fetch the public key and save to bitbucket as a new ssh key. It is also advisable you use a name that sets the key apart so you know its purpose, In my case, I set up different keys for my different environments. So I used keyname-environment e.g. Payment-server-staging.&lt;/p&gt;

&lt;h1&gt;
  
  
  Install the repo as a module
&lt;/h1&gt;

&lt;p&gt;Get the ssh URL of the repo that you set up earlier. It usually is in this form&lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:git@bitbucket.org"&gt;git@bitbucket.org&lt;/a&gt;:acmeinc/foo-bar.git&lt;/p&gt;

&lt;p&gt;Install using &lt;code&gt;npm i git@bitbucket.org:acmeinc/foo-bar.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the SSH setup went well and you added the key successfully to bitbucket, the installation should go smoothly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Using with Docker
&lt;/h2&gt;

&lt;p&gt;In my use case, I needed to use this repo in a container. There are several ways to also accomplish this, but I needed a way that would not copy the key as part of docker layers.&lt;/p&gt;

&lt;p&gt;Modify your Dockerfile this way:&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
FROM node:10-alpine&lt;/p&gt;

&lt;p&gt;ARG SSH_KEY&lt;/p&gt;

&lt;p&gt;RUN apk add git OpenSSH-client&lt;/p&gt;

&lt;p&gt;COPY package.json package-lock.json ./&lt;/p&gt;

&lt;p&gt;RUN mkdir -p -m 0600 ~/.ssh &amp;amp;&amp;amp; ssh-keyscan bitbucket.org &amp;gt;&amp;gt; ~/.ssh/known_hosts&lt;/p&gt;

&lt;p&gt;RUN ssh-agent sh -c 'echo $SSH_KEY | base64 -d | ssh-add - ; npm install'&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;The Dockerfile above tells docker to expect a base64 string at build time and read it in a variable called SSH_KEY which we use on the last line of the Dockerfile.&lt;/p&gt;

&lt;p&gt;To get a base64 version of your key, you can convert it manually or use the following command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;key=$(echo ~/.ssh/bitbucket | base64)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The above command will copy it key to a variable $key as base64, you can now run your Dockerfile, but the command for running it changes a little&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build --build-arg SSH_KEY=$key -t private-git .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Updating
&lt;/h1&gt;

&lt;p&gt;This is a part that is a bit tricky, updating gave me problems when I first started using this approach. To upgrade its best you create a tag for the repo using a version number, preferably semantic versioning. &lt;/p&gt;

&lt;p&gt;Once the tag has been created, you can add the tag name like so&lt;/p&gt;

&lt;p&gt;"some-app": "git+ssh://&lt;a href="mailto:git@bitbucket.org"&gt;git@bitbucket.org&lt;/a&gt;:acmeinc/foo-bar.git#TAG_NAME"&lt;/p&gt;

&lt;p&gt;This will install the version from the tag number. This is also a very good practice as you can fall back to older versions.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;So that's it, a bit lengthy but worth it in my opinion. Go ahead and write your function, share with colleagues or across projects. Cheers&lt;/p&gt;

</description>
      <category>npm</category>
      <category>git</category>
      <category>repo</category>
      <category>docker</category>
    </item>
    <item>
      <title>Sending Realtime Events To The Client From Node child process</title>
      <dc:creator>Doyin Olarewaju 🇳🇬🇨🇦</dc:creator>
      <pubDate>Fri, 13 Sep 2019 16:10:29 +0000</pubDate>
      <link>https://dev.to/gate3/sending-realtime-events-to-the-client-from-node-child-process-2kid</link>
      <guid>https://dev.to/gate3/sending-realtime-events-to-the-client-from-node-child-process-2kid</guid>
      <description>&lt;p&gt;So I recently had to add a new feature to an existing app. The new feature did some data heavy stuff like processing large documents of which the content was to be saved into a database.&lt;/p&gt;

&lt;p&gt;Naturally, I queued the data from the file and consumed the queue in a forked child process then saved the info to the database in the child process. To send a progress report on the status of the processing, I decided to use socketio to fire events to the client. This approach presented me with several problems because for one the processing was fast and the socketio instance didn't capture most of the events another problem was how to use the same socketio Instance between parent and child.&lt;/p&gt;

&lt;p&gt;The approach I later settled for was to use Redis Pub/Sub to fire events from the child processes, listen on the main process and send said events to the client. The approach works, scales well and gives a really good performance.&lt;/p&gt;

&lt;h1&gt;
  
  
  Now for Some code
&lt;/h1&gt;

&lt;p&gt;I will assume you have an existing nodejs app and the data has been queued already. We need to install the following&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redis Nodejs Client (I use &lt;a href="https://www.npmjs.com/package/redis"&gt;https://www.npmjs.com/package/redis&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;SocketIo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both can be installed using npm. &lt;code&gt;npm i -S socket.io redis&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  RabbitMqHelper
&lt;/h1&gt;

&lt;p&gt;Though this is out of scope for this article, I wrote a RabbitMq Helper which I use in my apps.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  The Child Process
&lt;/h1&gt;

&lt;p&gt;The feature required processing different queues that had different types of information but they both required the same underlying action; Saving into the database. So, I wrote a base child process and the specifics of each child process extended this&lt;/p&gt;

&lt;h2&gt;
  
  
  Base Worker
&lt;/h2&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  User Worker
&lt;/h2&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  The Main Process
&lt;/h1&gt;

&lt;p&gt;The main or parent process will fork the child processes anytime it starts. Starting a few child processes isn’t very difficult, but imagine having several child processes, it can be stressful getting the path to each and running them one after the other. So for that, I like to use a glob to find all child processes.&lt;/p&gt;

&lt;p&gt;For that, I will use a npm module called &lt;code&gt;glob&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i -S glob&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The code for the main process looks like this.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And that is it. Please leave your comments and opinions. Enjoy!&lt;/p&gt;

</description>
      <category>rabbitmq</category>
      <category>redis</category>
      <category>node</category>
      <category>socketio</category>
    </item>
    <item>
      <title>Setting up your React Workflow with Create React App, EsLint, Flow, Jest &amp; Enzyme</title>
      <dc:creator>Doyin Olarewaju 🇳🇬🇨🇦</dc:creator>
      <pubDate>Sun, 11 Nov 2018 06:20:25 +0000</pubDate>
      <link>https://dev.to/gate3/setting-up-your-react-workflow-with-create-react-app-eslint-flow-jest--enzyme-2n2o</link>
      <guid>https://dev.to/gate3/setting-up-your-react-workflow-with-create-react-app-eslint-flow-jest--enzyme-2n2o</guid>
      <description>&lt;p&gt;React is awesome, It gives you the power to create truly amazing apps that are performant and fast. But that's not all there is to building an app, is it? Having built multiple large apps based on React, I have discovered that the workflow is as important as the output. With a great workflow, maintenance will be easy, errors will be less and debugging will be a cinch. &lt;/p&gt;

&lt;p&gt;So how can we get the best out of this amazing library? By using tools to optimize our workflow of course. The tools in question are Flow (For static typing), EsLint (For adhering to good coding patterns), Jest and Enzyme (For Testing).&lt;/p&gt;

&lt;h1&gt;
  
  
  Flow
&lt;/h1&gt;

&lt;p&gt;Javascript is a dynamically typed language and so is React (goes without saying). This dynamism though convenient introduces a lot of problems with error detection and hence debugging. Statically typed languages evaluates data types at compile time, in most cases you even see the errors in your code editor before running them while dynamically typed languages on the other hand only evaluates at runtime, which means you detect type errors after the program has tried to run. &lt;/p&gt;

&lt;p&gt;Take a look at the code snippet below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const myObj = 2;
    // A lenghty stretch of code later... 
    myObj(); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code snippet above will result in an error, specifically "TypeError: myObj is not a function". If this were a statically typed language, you would detected this bug earlier and fixed it before even running. Though this is an oversimplified version of what could happen, this small issue can sometimes cost you a lot of time. For example, if this piece of code would not run until later on in the program, it could easily sneak past the developer's initial test and cause issues later.&lt;/p&gt;

&lt;p&gt;To solve this issue we make use of static type checkers, in this case Flow (&lt;a href="https://flow.org/en/" rel="noopener noreferrer"&gt;https://flow.org/en/&lt;/a&gt;). Flow is a static type checker for Javascript which means it checks your types at compile time just like other statically typed languages. &lt;/p&gt;

&lt;p&gt;Incorporating Flow into your workflow can be tedious at first and it actually has a bit of a learning curve, but trust me the benefits far outweigh the extra effort. &lt;/p&gt;

&lt;p&gt;Applying flow to the code snippet above&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// @flow
const myObj = 2;
// A lenghty stretch of code later... 
myObj(); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flow will catch this error and display the information in your code editor or it can also catch the error when you run the flow command in your cli. Here's a sample of what flow will output in your editor &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmsp8vp79rzaa2bs9mcpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmsp8vp79rzaa2bs9mcpa.png" width="800" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, flow tells you its not a function and even gives you further information on what type it is. Using flow will help &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You code faster and with confidence (Since you don't need to run your code before seeing these type bugs).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understand your code even better&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Work better in teams (Interpretation is way easier and your code base is easier to understand).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Intellisense is better&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  esLint
&lt;/h1&gt;

&lt;p&gt;The importance of Linting cannot be stressed enough. Linting is a code analysis tool and is part of the white box testing process. While unit tests will test your output and general program behaviour, Linting analyses the internal structure of your code. &lt;/p&gt;

&lt;p&gt;What is Linting ? Linting is the process of checking your code for logical and stylistic errors. Linters make sure you adhere to a coding standard, provides consistency and shows you possible logical errors. A linter is a program that performs this analyses on your code by going through it. Using a Linter in a team can make the codebase look like it was written by just one person. &lt;/p&gt;

&lt;p&gt;There are several Linters out there but my most preferred is esLint because of the robust set of rules it has and also because it's very flexible and easily configurable. You can even write your own rules that your codebase must adhere to. &lt;/p&gt;

&lt;h1&gt;
  
  
  Jest and Enzyme
&lt;/h1&gt;

&lt;p&gt;Writing unit tests for your app is an extremely important exercise and luckily we have Jest and Enzyme to make this process really easy (Thank you facebook, Thank you airbnb). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fhumorside.com%2Fwp-content%2Fuploads%2F2017%2F12%2Fthank-you-meme-02-1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fhumorside.com%2Fwp-content%2Fuploads%2F2017%2F12%2Fthank-you-meme-02-1.jpg" width="" height=""&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Despite the importance of unit testing in React apps, I have seen a lot of people not bother with this which I must say is a mistake. Jest and Enzyme provide awesome testing tools such as Shallow rendering (Rendering only the component without its children for testing), Snapshot testing (Rendered output of your component stored on file and compared against to ensure your component doesn't change) and code coverage out of the box. &lt;/p&gt;

&lt;p&gt;Testing a React component can be as simple as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('render &amp;lt;ComponentX /&amp;gt; without errors', () =&amp;gt; {
    const wrapper = shallow(&amp;lt;ComponentX /&amp;gt;);
    expect(wrapper).toMatchSnapshot();
});

// or with a function spy

it('call function on button click', () =&amp;gt; {
    const funcToCall = jest.fn();
    const wrapper = shallow(&amp;lt;ComponentX callFunc={funcToCall}/&amp;gt;);
    const btn = wrapper.find('button');
    btn.simulate('click');
    expect(funcToCall).toHaveBeenCalled();
});

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

&lt;/div&gt;



&lt;p&gt;Of course the test could become more complex depending on what you wish to test, but you get the general idea. Jest is the test framework itself that has a task runner, assertion framework and good mocking support. Enzyme on the other hand is a library that provides an easier interface to write unit tests. &lt;/p&gt;

&lt;h1&gt;
  
  
  All together now
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0m39wfgfy8ec0brwd3wn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0m39wfgfy8ec0brwd3wn.jpg" alt="Image: The Oregon Symphony led by Carlos Kalmar Oregon Symphony" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create React App
&lt;/h2&gt;

&lt;p&gt;For this article I will make use of &lt;a href="https://github.com/facebook/create-react-app" rel="noopener noreferrer"&gt; CRA (Create React App) &lt;/a&gt;, the easiest way to start a React app. Grab yourself a copy by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app &amp;lt;your app name &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the folder  through your cli to install the rest of the tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flow
&lt;/h2&gt;

&lt;p&gt;Flow configuration comes with your CRA, but you need to install flow-bin into your workspace in order to use it  (Read more about &lt;a href="https://github.com/facebook/flow#installing-flow-per-project" rel="noopener noreferrer"&gt;Flow bin&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;To install Flow follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;em&gt;npm install --D flow-bin&lt;/em&gt; to install flow-bin.&lt;/li&gt;
&lt;li&gt;Run &lt;em&gt;./node_modules/.bin/flow init&lt;/em&gt; to create a new .flowconfig file&lt;/li&gt;
&lt;li&gt;Add "flow": "flow" to the scripts section of your package.json.&lt;/li&gt;
&lt;li&gt;Run &lt;em&gt;./node_modules/.bin/flow&lt;/em&gt; to see if it works. You should get a No Errors response. Note: To make things easier, you should install flow globally by running &lt;em&gt;npm i -g flow-bin&lt;/em&gt;. Once that is done you don't need &lt;em&gt;./node_modules/.bin/flow&lt;/em&gt; any longer, you can just run "flow" from your cli.&lt;/li&gt;
&lt;li&gt;The No errors! message comes up because you have not started flow typing any files. To see flow in action add // &lt;a class="mentioned-user" href="https://dev.to/flow"&gt;@flow&lt;/a&gt; at the top of any of your js or jsx files and run flow again. You will get messages detailing the errors and the file they exist in.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  esLint
&lt;/h2&gt;

&lt;p&gt;To get started with esLint do the following&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;em&gt;npm i -D eslint&lt;/em&gt; to install esLint.&lt;/li&gt;
&lt;li&gt;Once the installation is done, run the following command &lt;em&gt;./node_modules/.bin/eslint --init&lt;/em&gt;. (NB: Again you can install eslint globally by running &lt;em&gt;npm i -g eslint&lt;/em&gt;). The init command will ask you about the linting rules you wish to use. Would you like to create yours or would you like to use a popular coding style&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flpfjsmrjl6mlfervnj50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flpfjsmrjl6mlfervnj50.png" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A popular choice and the one I usually use is the airbnb style. You also get questions about if you use React (Obviously) and which configuration file type would you like to use (JSON, Javascript or YAML), I mostly use javascript. Then finally you will be asked to install eslint's dependencies, install them to finalise.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once done with the config an eslintrc.js will be generated for you (the file extension will depend on config file type you chose). You need to copy the following command into the .eslintrc.js file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// original file
module.exports = {
    "extends": "airbnb"
};

// change to this 
module.exports = {
    "extends": ["airbnb", "plugin:flowtype/recommended"],
    "env": {
        "jest": true
    },
    "parser": "babel-eslint",
    "plugins": [
        "flowtype"
    ],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are almost done, just one more step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jest and Enzyme
&lt;/h2&gt;

&lt;p&gt;Again the good people behind CRA included Jest as a default test runner (&lt;a href="https://facebook.github.io/create-react-app/docs/running-tests" rel="noopener noreferrer"&gt;Read more&lt;/a&gt;), but it doesn't come with enzyme installed. To install enzyme run the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev enzyme enzyme-adapter-react-16 enzyme-to-json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then update your jest config in package.json by adding&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"jest": {
    "snapshotSerializers": [
      "enzyme-to-json/serializer"
    ]
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we need to create configurations for enzyme to work with react 16. Create a file called setupTests.js in the src folder, so that we ./src/setupTests.js exists. CRA will find this file by itself, but if you are not making use of CRA, update your jest config in package.json by adding &lt;em&gt;"setupFiles": ["./src/setupTests.js"]&lt;/em&gt; to it. Add the following command to setupTests.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are all set. If everything went well, you should already see eslint making corrections to your code with red underline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample program
&lt;/h2&gt;

&lt;p&gt;Let's write a simple program that will be flow typed and unit tested.&lt;/p&gt;

&lt;p&gt;Say I have these components&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.jsx

import React, { Component } from 'react';
import './App.css';
import MyButton from './components/MyButton';


class App extends Component {
  constructor() {
    super();
    this.state = {
      count: 1,
    };
    this.countFunc = this.countFunc.bind(this);
  }

  countFunc() {
    this.setState({
      count,
    });
  }

  render() {
    const { count } = this.state;
    return (
      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;{count + 1}&amp;lt;/h1&amp;gt;
        &amp;lt;MyButton name="Click Me" countFunc={this.countFunc} /&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;And...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//MyButton.jsx
import React from 'react';

const MyButton = ({ name, countFunc }) =&amp;gt; (
  &amp;lt;button type="button" onClick={() =&amp;gt; countFunc(2)}&amp;gt;{name}&amp;lt;/button&amp;gt;
);

export default MyButton;

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

&lt;/div&gt;



&lt;p&gt;As it is, they are both just regular functions with no flow typing. The button is passing a number back to the App component but if for some reason that changes the program breaks or loosing meaning (logical error).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// @flow

import React, { Component } from 'react';
import './App.css';
import MyButton from './components/MyButton';

type State = {
  count: number,
}

type Props = {}

class App extends Component&amp;lt;Props, State&amp;gt; {
  constructor() {
    super();
    this.state = {
      count: 1,
    };
    this.countFunc = this.countFunc.bind(this);
  }

  countFunc: (count: number)=&amp;gt;void

  countFunc(count: number) {
    this.setState({
      count,
    });
  }

  render() {
    const { count } = this.state;
    return (
      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;{count + 1}&amp;lt;/h1&amp;gt;
        &amp;lt;MyButton name="Click Me" countFunc={this.countFunc} /&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;And ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// @flow
import React from 'react';

type Props = {
    name: string,
    countFunc: (count: number) =&amp;gt; void
};

const MyButton = ({ name, countFunc }: Props) =&amp;gt; (
  &amp;lt;button type="button" onClick={() =&amp;gt; countFunc(2)}&amp;gt;{name}&amp;lt;/button&amp;gt;
);

export default MyButton;

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

&lt;/div&gt;



&lt;p&gt;This is way more readable and we are sure to get a warning if the type changes.&lt;/p&gt;

&lt;p&gt;Now for the tests&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Very simple test to check if App Renders
import React from 'react';
import { shallow } from 'enzyme';
import App from './App';

describe('&amp;lt;MyButton /&amp;gt;', () =&amp;gt; {
  it('renders without crashing', () =&amp;gt; {
    const wrapper = shallow(&amp;lt;App /&amp;gt;);
    expect(wrapper.length).toEqual(1);
  });
});

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

&lt;/div&gt;



&lt;p&gt;And ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { shallow } from 'enzyme';
import MyButton from './MyButton';

describe('&amp;lt;MyButton /&amp;gt;', () =&amp;gt; {
  it('Should render without crashing', () =&amp;gt; {
    const wrapper = shallow(&amp;lt;MyButton /&amp;gt;);
    expect(wrapper.length).toEqual(1);
  });
  it('Should render without crashing', () =&amp;gt; {
    const mockCountFunc = jest.fn();
    const wrapper = shallow(&amp;lt;MyButton countFunc={mockCountFunc} /&amp;gt;);
    const btn = wrapper.find('button');
    btn.simulate('click');
    expect(mockCountFunc).toHaveBeenCalled();
  });
});

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

&lt;/div&gt;



&lt;p&gt;The above test for MyButton just tests if MyButton renders successfully and also tests if when the button is clicked it will call the countFunc prop being passed to it.&lt;/p&gt;

&lt;p&gt;You can find the complete code here &lt;a href="https://github.com/gate3/React-WorkFlow" rel="noopener noreferrer"&gt;Code Sample&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;If like me you make use of Vscode, there is an extra step to take to ensure everything works smoothly. You need to make eslint allow you define flow types. If you have setup this project on your own, you might have come across an error stating only .ts files can define types (or something like that). To make this error disappear, open your settings (on Mac that will be clicking the code menu and going to preferences settings and switching to workspace settings). Open the workspace settings and add this setting&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"javascript.validate.enable":false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you are set.&lt;/p&gt;

&lt;p&gt;Lastly, the whole process might be a lot to take in and can be overwhelming, but you will get used to it. As a general rule of thumb, I follow this pattern. I write my tests fail and let them fail, I write my Flow types next and then I write my component. Then I adjust the component to fit the previous two.&lt;/p&gt;

&lt;p&gt;Happy coding and leave your comments. :-)&lt;/p&gt;

</description>
      <category>react</category>
      <category>flow</category>
      <category>jest</category>
      <category>enzyme</category>
    </item>
    <item>
      <title>How to setup CouchDb on Azure: A step by step guide</title>
      <dc:creator>Doyin Olarewaju 🇳🇬🇨🇦</dc:creator>
      <pubDate>Tue, 25 Sep 2018 10:38:18 +0000</pubDate>
      <link>https://dev.to/gate3/how-to-setup-couchdb-on-azure-a-step-by-step-guide-4o3p</link>
      <guid>https://dev.to/gate3/how-to-setup-couchdb-on-azure-a-step-by-step-guide-4o3p</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wCaKqHnx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7oizyztedtjmsav7a0wf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wCaKqHnx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7oizyztedtjmsav7a0wf.jpg" alt="Main Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over the past month I have been involved in a project that requires offline first capabilities. I worked on automatic synchronization in the past and it was a real pain to do because everything was so manual and annoying. I basically had to write the code that made all the moving parts work, from persisting the data locally, listening for network presence and then moving the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter &lt;a href="https://pouchdb.com"&gt;PouchDb&lt;/a&gt; and &lt;a href="http://couchdb.apache.org/"&gt;CouchDb&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Since then I learnt about the pouch and couch db combo and life has become much easier. Pouchdb helps with the offline storage part and has a seamless, fast and reliable relationship with couchdb. All you need do is connect both databases using your preferred replication, then save to pouchdb the rest happens automagically. &lt;/p&gt;

&lt;p&gt;So lets get started..&lt;/p&gt;

&lt;h2&gt;
  
  
  What do you need
&lt;/h2&gt;

&lt;p&gt;You need the following:&lt;br&gt;
    * Active Microsoft azure subscription&lt;br&gt;
    * Some knowledge of SSH&lt;br&gt;
    * Some knowledge of how couchdb works&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Couchdb
&lt;/h2&gt;

&lt;p&gt;As you might already know Microsoft azure is a platform as a service (PaaS). It can provide you a dedicated environment consisting of basically almost anything you need to host, hmmm, basically anything you want (Is it just me or does that statement sound strange, anyways moving on). One of those environments is a Virtual Machine (VM). &lt;/p&gt;

&lt;p&gt;To use Couchdb you need a VM, but never fear, &lt;a href="https://bitnami.com"&gt;Bitnami&lt;/a&gt; as usual is a lifesaver. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 (Go to the marketplace)
&lt;/h3&gt;

&lt;p&gt;Go to the new &lt;a href="https://manage.windowsazure.com"&gt;azure portal&lt;/a&gt; and login if not already logged in. On the dashboard find marketplace. If you can't find it on the dashboard, click all services by the side then look for marketplace and click on it. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rI9y0YbG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.filestackcontent.com/6J6JLgAKTEWlCQs0UVfP" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rI9y0YbG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.filestackcontent.com/6J6JLgAKTEWlCQs0UVfP" alt="Screen Shot 2018-09-24 at 8.48.42 AM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 (Search for Couchdb)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NnzeyB4Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.filestackcontent.com/oLWF1lflTm6bW6uyIHUv" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NnzeyB4Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.filestackcontent.com/oLWF1lflTm6bW6uyIHUv" alt="Screen Shot 2018-09-24 at 8.49.49 AM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just type "Couchdb" or more directly "CouchDB Certified by Bitnami" you should be get the marketplace app as shown in the image and select it on the next screen you should see some explanation about what couchbase is, Scroll to the bottom and click the create button below. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 (Configure your VM instance)
&lt;/h3&gt;

&lt;p&gt;The next screen displays some configuration options for your Virtual Machine. If you are familiar with Azure already most of the options should be pretty obvious. Options like resource group, region and availability set. They all have the information icon beside them which you can hover and get information about the field, but I will explain the fields that are mission critical (wink :-), wanted to say that for a while now).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rN7PFJsr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.filestackcontent.com/P7vLQVQPRXCNljJXp2K7" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rN7PFJsr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.filestackcontent.com/P7vLQVQPRXCNljJXp2K7" alt="Screen Shot 2018-09-24 at 8.57.10 AM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Virtual machine name&lt;/strong&gt;&lt;br&gt;
This is a name to recognize your virtual machine by and also the hostname. Use a good and explanatory name here, not too long but explanatory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Availability Options&lt;/strong&gt;&lt;br&gt;
This is important but not an absolute must have since your app won't fail if there is no server. But I decided to talk about it (Hmm... feeling like MGK, he sucks though :-( ), because its important for some apps. Take for example, if your business logic states that you must absolutely backup every X period. Then there would be an issue if your server is down wouldn't there.&lt;/p&gt;

&lt;p&gt;Availability options just ensures that your server doesn't go down by providing a mirror or replicated server somewhere else that will kick in whenever your real server goes down for some reason. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Image&lt;/strong&gt;&lt;br&gt;
Leave this option alone as is except you changed your mind about deploying couchdb of course.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Size&lt;/strong&gt;&lt;br&gt;
Another option you should probably leave as is. The default option should be standard A1 v2. Which is a standard setup for most purposes. I'd advice you let it be and scale up as needed with time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Administrator Account&lt;/strong&gt;&lt;br&gt;
This is absolutely crucial. The administrator is the username and password you will use in logging into your virtual machine. As for me, i used a username and password combination for now, basically because I won't be the only one accessing the vm and I didn't wish to ship SSH keys to everyone that required access. But i intend to change this eventually when we are more certain about who gets the keys to the kingdom. &lt;/p&gt;

&lt;p&gt;Once all fields are filled you can go ahead and click review and create. Except you absolutely know what you are doing, do not mess with the other tabs. Once you click preview and create, it loads for a while as it creates the VM, just grab your favourite drink and watch an episode of Rick and Morty while it does its thing. &lt;/p&gt;

&lt;p&gt;It should be done now, congratulations you have a new born VM with couchbase installed. The options might seem confusing at first but work with me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Couchdb
&lt;/h2&gt;

&lt;p&gt;Bitnami provides an official &lt;a href="https://docs.bitnami.com/azure/infrastructure/couchdb/"&gt;documentation&lt;/a&gt; here. Just an FYI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obtain server credentials (For those that signed up using password)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Method 1: Boot Diagnostics method
&lt;/h4&gt;

&lt;p&gt;By default your username is admin, but you also need to obtain your password. To do that, visit the dashboard of the virtual machine you just created and search for &lt;strong&gt;Boot Diagnostics&lt;/strong&gt;. Select the option and you are presented with another menu that contains Screenshot and Serial log. &lt;/p&gt;

&lt;p&gt;The first menu Item, screenshot, gives you are screenshot of the current system display in cli while the second contains the log file for your system. Get ready, you are about to dig through some logs. I advice you download the logs to your computer and go through it locally. What you are looking for are the words "Setting bitnami application password to". &lt;/p&gt;

&lt;p&gt;You can see this youtube video for more info &lt;br&gt;
@&lt;a href="https://youtu.be/SB6ZDws0m3E"&gt;Youtube for bitnami&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NB: This method will only work the first time you create the VM. Otherwise the password would have been overwritten by new log.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Method 2: SSH
&lt;/h4&gt;

&lt;p&gt;You can also obtain the credentials by connecting to your VM using SSH. To obtain your credentials for azure SSH you can follow the steps here&lt;br&gt;
&lt;a href="https://docs.bitnami.com/azure/faq/get-started/connect-ssh/"&gt;How to obtain SSH credentials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once you are logged into SSH, execute the following command &lt;strong&gt;cat ./bitnami_credentials&lt;/strong&gt;. If no content is displayed in the file above run the following command &lt;strong&gt;sudo cat /opt/bitnami/var/data/bitnami_credentials/credentials&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If you made use of SSH keys you will have to login using different methods. Visit the link specified above for more information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect to Fauxton
&lt;/h3&gt;

&lt;p&gt;Fauxton is the web interface that makes working with couchdb very easy. If you don't know about it or haven't used it before, please do, it makes your life very easy. But to work with Fauxton, you need port 5984, but that port is blocked by default for security reasons. &lt;/p&gt;

&lt;p&gt;I will describe two methods one that is secure but limits access to one computer at a time by using tunelling and the other gives public access but with password protection of course. If you wish to expose the port publicly make sure you know what you are doing and that you absolutely have to. By absolutely have to, I mean the only reason you should even be considering it is because you wish to provide access to other members of your team/company.&lt;/p&gt;

&lt;h4&gt;
  
  
  Method 1 (SSH Tunelling)
&lt;/h4&gt;

&lt;p&gt;By default Couchdb listens to local interface only, so an SSH tunnel is needed to access it. An SSH tunnel needs a port for both ends, a source port and a destination port. For the purpose of making this connection you need to use 5984 for both ends of the tunnel.&lt;/p&gt;

&lt;p&gt;To connect use the following on MAC&lt;/p&gt;

&lt;p&gt;ssh -N -L 5984:127.0.0.1:5984 USERNAME@SERVER-IP&lt;/p&gt;

&lt;p&gt;Where username is the VM username you set when creating the VM and server IP can be found on your dashboard. You will be prompted for your password, enter it and a connection should be established.&lt;/p&gt;

&lt;p&gt;There is a caveat however, ensure your local couchdb instance is not currently running, else you will get an error about not being able to bind to the port or something of the sorts. It took me a while to figure this one out, because i kept trying to login with the credentials of my remote couchdb, you can guess that it didn't work. I eventually had to kill the process using port 5984 before it worked. &lt;/p&gt;

&lt;p&gt;Another caveat is that once its connected you don't get a message about connecting successfully. So what you need to do is visit fauxton's url. It will be thesame url as your local couchdb instance since you tunnelled using your localhost. &lt;strong&gt;&lt;a href="http://127.0.0.1:5984/_utils/"&gt;http://127.0.0.1:5984/_utils/&lt;/a&gt;&lt;/strong&gt;. You should see the interface now. Login and enjoy.&lt;/p&gt;

&lt;h4&gt;
  
  
  Method 2 (Public access)
&lt;/h4&gt;

&lt;p&gt;To unlock the port you need to allow the port 5984 through your firewall. To do this you need to add an inbound rule, luckily this is pretty easy to do. Just search for Networking from the sidemenu and click the inbound rules button when the blade comes up. By default the settings for new inbound rules will be set to advanced, change it to basic and you should see the screen below &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CxhNT0WH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.filestackcontent.com/J5tB1RnJSmHzS7skAYi8" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CxhNT0WH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.filestackcontent.com/J5tB1RnJSmHzS7skAYi8" alt="Screen Shot 2018-09-25 at 9.08.32 AM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the service dropdown and pick couchdb from the options. You can change the name if you wish to something more easy to remember. Then save, it takes a little time. &lt;/p&gt;

&lt;p&gt;Once the inbound rule has been added, connect to your VM using SSH then run the following command &lt;strong&gt;vim /opt/bitnami/couchdb/etc/local.ini&lt;/strong&gt;. The command will open the file in the path using vim, you need to enter INSERT mode before you can edit, so press "i" on your keyboard. Scroll down and look for &lt;/p&gt;

&lt;p&gt;[chttpd]&lt;br&gt;
port = 5984&lt;br&gt;
bind_address = 0.0.0.0&lt;br&gt;
...&lt;/p&gt;

&lt;p&gt;[httpd]&lt;br&gt;
bind_address = 0.0.0.0&lt;br&gt;
...&lt;/p&gt;

&lt;p&gt;In my own case i only found the first one. Change 0.0.0.0 to 127.0.0.1. Save the file by exiting INSERT mode, so press esc key. Then press :wq and press enter to save. Open the file again to confirm the rules have been saved. Then restart your couchdb instance &lt;strong&gt;sudo /opt/bitnami/ctlscript.sh restart couchdb&lt;/strong&gt;. Your Fauxton instance is now ready. &lt;/p&gt;

&lt;p&gt;To connect to it use &lt;strong&gt;[Your VM public Ip]:5984/_utils/&lt;/strong&gt;. You should see your fauxton instance now.&lt;/p&gt;

&lt;p&gt;I hope you are successful in making this work, if not leave me a message and we can debug together. Please watchout for the next article on how to connect the instance we just created to pouchdb and perform data sync.&lt;/p&gt;

</description>
      <category>couchdb</category>
      <category>vm</category>
      <category>azure</category>
      <category>bitnami</category>
    </item>
    <item>
      <title>Extending Javascript array with an event handler</title>
      <dc:creator>Doyin Olarewaju 🇳🇬🇨🇦</dc:creator>
      <pubDate>Fri, 27 Jul 2018 21:38:30 +0000</pubDate>
      <link>https://dev.to/gate3/extending-javascript-array-with-an-event-handler-1ce2</link>
      <guid>https://dev.to/gate3/extending-javascript-array-with-an-event-handler-1ce2</guid>
      <description>&lt;p&gt;I recently had to write a classifier algorithm that classified an array of items based on certain attributes. It was a pretty complicated dataset with an even more complicated set of constraints, but for the sake of this article i will keep it a simple.&lt;/p&gt;

&lt;p&gt;Say we have the following dataset&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    [
        {id:1, age:32},
        {id:2, age:4},
        {id:3, age:20},
        {id:4, age:30}
    ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, say we wish to find the oldest age and the sum of all ages. This can easily be done using a loop and some variables, but for the sake of this article I will use an event listener attached to the traditional javascript array to pull this off.&lt;/p&gt;

&lt;h1&gt;
  
  
  First Let's extend the array object
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const MyArray = function (){
        // this events object will be explained shortly
        this.events = {}
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, simply I just created a function and called it my array then gave it an events object(or hashtable) that will hold all our events and callbacks in this form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    {eventName:callback_function}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's continue with creating the extended array&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    MyArray.prototype = []

    MyArray.prototype.on = function (event, callback){
        this.events[event] = callback
    }    

    MyArray.prototype.push = function(args){
        Array.prototype.push.call(this, args)
        const eventName = 'push'
        if(this.events[eventName]){
            this.events[eventName](args)
        }
    }

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

&lt;/div&gt;



&lt;p&gt;In the snippet above we let our function inherit the properties of the array object using prototype inheritance.&lt;/p&gt;

&lt;p&gt;The second block implements our event listener function. We call the function on, so we can do things like on('filter') etc. All this function does is take in the event (or event name) and a callback to execute once that event occurs. The function stores the event name as the key and the callback as the value in our events hashtable.&lt;/p&gt;

&lt;p&gt;Lastly we make our own push method to put new items into our object. The next line uses the push method of the parent Array object, but by using call, we call push in the context of the current object. This works because our object has inherited from Array. That's all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing our new object
&lt;/h2&gt;

&lt;p&gt;So let's test this and see how it will work using the stated example data above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Arr = new MyArray()
let sum = 0;
let oldest = 0;
Arr.on('push', function (e){
    sum += e.age
    oldest = (e.age &amp;gt; oldest ? e.age:oldest)
})

for (let data of dataSet){
    Arr.push(data)
}

console.log(sum, oldest)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
  </channel>
</rss>
