<?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: Enoch Chejieh</title>
    <description>The latest articles on DEV Community by Enoch Chejieh (@ecj222).</description>
    <link>https://dev.to/ecj222</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%2F401143%2F0ee01d25-c18d-4368-9bbd-69c0ee509535.jpeg</url>
      <title>DEV Community: Enoch Chejieh</title>
      <link>https://dev.to/ecj222</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ecj222"/>
    <language>en</language>
    <item>
      <title>How to build a Live Chat in your Web Application using Robin Part 2</title>
      <dc:creator>Enoch Chejieh</dc:creator>
      <pubDate>Fri, 12 Aug 2022 10:13:18 +0000</pubDate>
      <link>https://dev.to/ecj222/how-to-build-a-live-chat-in-your-web-application-using-robin-part-2-1o68</link>
      <guid>https://dev.to/ecj222/how-to-build-a-live-chat-in-your-web-application-using-robin-part-2-1o68</guid>
      <description>&lt;p&gt;In the last part, you looked at how you can set up Robin using its Javascript SDK while building a web applications customer service live chat feature. In this part, you will be looking at how you can set up Robin's Vue SDK to quickly set up a customer support client for CryptoDegen to respond to their user messages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3VlC0IgG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cvr2vy9aef6b6p9jhjxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3VlC0IgG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cvr2vy9aef6b6p9jhjxn.png" alt="CryptoDegen Support" width="880" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along with this tutorial, you should have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Knowledge of Vue.JS&lt;/li&gt;
&lt;li&gt;Robin API key&lt;/li&gt;
&lt;li&gt;A backend server to retrieve data from a database (You can use any of your choice)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you haven't gotten your Robin API key already, you can get your Robin API key from your &lt;a href="https://dashboard.robinapp.co/signup"&gt;Robin Account&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Registering Robin Vue SDK
&lt;/h2&gt;

&lt;p&gt;Before proceeding, you first need to install the Robin Vue SDK. Copy and paste the following code into your terminal.&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 robin-vue --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, in your main entry file, you will need to register the Robin Vue SDK in your Vue instance. In this tutorial, it's &lt;code&gt;src/main.ts&lt;/code&gt;. Copy and paste the following code:&lt;br&gt;
&lt;/p&gt;

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

import RobinChat from 'robin-vue'

Vue.use(RobinChat)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, import Robin's global styles. Add the following line of code to your &lt;code&gt;src/main.ts&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

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

import 'robin-vue/dist/style.css'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  RobinChat Component
&lt;/h2&gt;

&lt;p&gt;Before setting up your RobinChat component, Create a view component called &lt;code&gt;src/views/Login.vue&lt;/code&gt;. This is how the support team for CryptoDegen would gain access to the Robin platform to respond to user messages.&lt;br&gt;
&lt;/p&gt;

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

&amp;lt;template&amp;gt;
  &amp;lt;div class="signin-ctn section" id="app"&amp;gt;
    &amp;lt;div class="inner"&amp;gt;
      &amp;lt;div class="auth-box"&amp;gt;
        &amp;lt;!-- image --&amp;gt;
        &amp;lt;span&amp;gt;Distributing finance for everyone&amp;lt;/span&amp;gt;
        &amp;lt;form @submit.prevent&amp;gt;
          &amp;lt;div class="form-group" :class="{ error: !emailValidate }"&amp;gt;
            &amp;lt;input
              v-model="email"
              type="email"
              placeholder="email@company.com"
            /&amp;gt;
            &amp;lt;label&amp;gt;Your Email&amp;lt;/label&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div class="form-group"&amp;gt;
            &amp;lt;div class="password-field"&amp;gt;
              &amp;lt;input
                v-model="password"
                :type="obscure ? 'password' : 'text'"
                placeholder="********"
              /&amp;gt;
              &amp;lt;i class="material-symbols-outlined" @click="obscure = !obscure"&amp;gt;
                {{ obscure ? 'visibility_off' : 'visibility' }}
              &amp;lt;/i&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;label&amp;gt;Password&amp;lt;/label&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;button v-if="!isLoading" class="primary-btn" @click="signIn()"&amp;gt;
            Login
          &amp;lt;/button&amp;gt;
          &amp;lt;button v-else class="primary-btn" disabled&amp;gt;
            &amp;lt;div class="spinner2"&amp;gt;&amp;lt;/div&amp;gt;
          &amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

export default Vue.extend({
  name: 'Login',
  data() {
    return {
      email: '' as string,
      password: '',
      obscure: true,
      isLoading: false,
    }
  },
  computed: {
    emailValidate() {
      // eslint-disable-next-line
      return /^(([^&amp;lt;&amp;gt;()[\]\\.,;:\s@\"]+(\.[^&amp;lt;&amp;gt;()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
        this.email
      )
    },
  },
  methods: {
  },
})
&amp;lt;/script&amp;gt;

&amp;lt;style scoped&amp;gt;
h1 {
  font-weight: 500;
  font-size: clamp(0.3rem, 7vw, 2rem);
}
span {
  display: block;
  font-size: clamp(0.3rem, 7vw, 1rem);
  color: #8d9091;
  margin: 0.625rem 0 1.375rem;
}
label {
  font-size: clamp(0.3rem, 5vw, 1rem);
}
.section {
  display: flex;
  justify-content: center;
  width: 100%;
}
.section &amp;gt; .inner {
  width: 90%;
}
.signin-ctn.section {
  min-height: 100vh;
  align-items: center;
}
.signin-ctn &amp;gt; .inner {
  max-width: 600px;
}
.auth-box {
  text-align: center;
  padding: 10% 15%;
  height: auto;
  min-height: 650px;
  padding-bottom: 5%;
}
.auth-box img {
  border-radius: 11px;
  margin-bottom: 1rem;
}
.form-group {
  margin-top: 1.5rem;
  position: relative;
  text-align: left;
  display: flex;
  flex-direction: column-reverse;
}
.form-group label {
  font-size: 1rem;
  display: block;
  line-height: 32px;
  transition: 0.3s;
}
.form-group input {
  display: block;
  background: #f5f7fc;
  border-radius: 4px;
  transition: 0.3s;
  width: 100%;
  height: 55px;
  padding: 0 1.5rem;
  font-size: 1rem;
  -webkit-transition: 0.3s;
  -moz-transition: 0.3s;
  -ms-transition: 0.3s;
  -o-transition: 0.3s;
}
.form-group input::placeholder {
  color: #9999bc;
}
.form-group .password-field {
  padding-right: 1.5rem;
  display: flex;
  align-items: center;
  background: #f5f7fc;
  border-radius: 4px;
  width: 100%;
  transition: 0.3s;
  -webkit-transition: 0.3s;
  -moz-transition: 0.3s;
  -ms-transition: 0.3s;
  -o-transition: 0.3s;
}
.form-group .password-field input {
  border: none;
  transition: 0s;
  -webkit-transition: 0s;
  -moz-transition: 0s;
  -ms-transition: 0s;
  -o-transition: 0s;
}
.form-group .icon {
  position: absolute;
  right: 16px;
  top: 50%;
}
.flex-ctn.link {
  width: max-content;
  margin-left: auto;
  margin-top: 0.5rem;
  font-size: 0.925rem;
}
.flex-ctn.link div {
  font-size: 1rem;
  color: #f66b03;
  cursor: pointer;
  font-weight: 400;
  line-height: 24px;
}
.header {
  margin: 10% auto 0 auto;
}
form {
  margin-top: 10%;
}
.primary-btn {
  margin-top: 2rem;
}
@media screen and (max-width: 1450px) {
  .section &amp;gt; .inner {
    width: 90%;
  }
}
@media screen and (max-height: 900px) {
  .auth-box {
    padding: 5% 15%;
    min-height: 560px;
  }
  .header {
    margin-top: 5%;
    font-size: 1.3rem;
  }
  .primary-btn {
    margin-left: auto;
    margin-right: auto;
  }
}
@media screen and (max-width: 600px) {
  .auth-box {
    padding: 5% 8%;
    height: auto;
    min-height: auto;
  }
  .primary-btn {
    min-width: auto;
    width: 100%;
    font-size: 0.9rem;
    height: 45px;
  }
  .flex-ctn.link {
    margin-top: 15%;
    font-size: 0.775rem;
  }
  .section &amp;gt; .inner {
    width: 95%;
  }
}
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tutorial mocks the user authentication process from the client side same as in the part 1 of this series.&lt;/p&gt;

&lt;p&gt;Next, Create a function called &lt;code&gt;signIn()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
async signIn() {
  this.isLoading = true
  const promise: Promise&amp;lt;ObjectType&amp;gt; = new Promise((resolve, reject) =&amp;gt; {
    setTimeout(() =&amp;gt; {
      if (
        this.email == 'cryptodegensuppor@gmail.com' &amp;amp;&amp;amp;
        this.password == 'JetpaySupport'
      ) {
        resolve({ status: 'success', data: { 
           _id: '983388d4d769496eb4bc0e42a6c0593a',
          email: 'cryptodegensuppor@gmail.com',
          username: 'Support',
          user_token: 'SxPzdCcGZeyNUGPUZRNIiFXH'
        }})
      } else {
        reject({ status: 'error', error: 'Invalid email or password' })
      }
    }, 2000)
  })
  const response = await promise as ObjectType
  if (response.status === 'success') {
    this.$router.push('/chat')
    localStorage.setItem('data', JSON.stringify(response.data))
  } else {
    console.log(response)
  }
  this.isLoading = false
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, to initialize the RobinChat component, create a view component &lt;code&gt;src/views/Chat.vue&lt;/code&gt; and paste the following 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;
&amp;lt;template&amp;gt;
  &amp;lt;div class="chat"&amp;gt;
    &amp;lt;RobinChat
      logo="https://iili.io/wUVjdG.png"
      api-key="NT-XmIzEmWUlsrQYypZOFRlogDFvQUsaEuxMfZf"
      :users="users"
      :user-token="userToken"
      :keys="keys"
      :user-name="userName"
      channel="private_chat"
      :features="[]"
    &amp;gt;
    &amp;lt;/RobinChat&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script lang="ts"&amp;gt;
import Vue from 'vue'

type ObjectType = Record&amp;lt;string, any&amp;gt;

export default Vue.extend({
  name: 'Chat',
  data() {
    return {
      userName: '',
      userToken: '',
      users: [] as Array&amp;lt;ObjectType&amp;gt;,
      keys: {
        userToken: 'robin_user_token',
        profileImage: 'profile_photo',
        userName: 'username',
      },
    }
  },
  created() {
    if (localStorage.getItem('data')) {
      const data = JSON.parse(localStorage.getItem('data') || '{}')
      this.userToken = data.user_token
      this.userName = data.user_name
    }

    this.getUsers()
  },
  methods: {
    async getUsers() {
      const promise: Promise&amp;lt;Array&amp;lt;ObjectType&amp;gt;&amp;gt; = new Promise((resolve) =&amp;gt; {
        setTimeout(() =&amp;gt; {
          const users = [
            {
              _id: '983388d4d769496eb4bc0e42a6c0593a',
              email: 'cryptodegensupport@gmail.com',
              username: 'CryptoDegen Support',
              robin_user_token: 'SxPzdCcGZeyNUGPUZRNIiFXH',
              profile_photo: '',
            },
            {
              _id: 'b990738c18584abfbad077ad90712b56',
              email: 'enoch11@gmail.com',
              username: 'Enoch Chejieh',
              robin_user_token: 'SHkPHNIYqwQIvyaYFaovLlHa',
              profile_photo: '',
            },
          ]
          resolve(users)
        }, 1000)
      })
      const response = await promise
      this.users = [...response]
    },
  },
})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Robin Vue SDK provides extra options like features which allows you to specify which Robin feature you would like to use on the platform, such as &lt;code&gt;create-chat&lt;/code&gt;, &lt;code&gt;forward-messages&lt;/code&gt;, delete-messages, &lt;code&gt;archive-chat&lt;/code&gt;, &lt;code&gt;reply-messages&lt;/code&gt;, &lt;code&gt;voice-recorder&lt;/code&gt;, &lt;code&gt;message-reactions.view&lt;/code&gt; and &lt;code&gt;message-reaction.delete&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UNdbXHSB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05bnkbc80upp0t3tf39g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UNdbXHSB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05bnkbc80upp0t3tf39g.png" alt="robin-vue User Interface" width="880" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;So quick recap. In this part you’ve learned how to use the Robin Vue SDK in your Vue application.&lt;/p&gt;

&lt;p&gt;In-app live chat communication just got a lot easier with no extra configurations needed using Robin’s official SDKs is as easy as plug-in-play.&lt;/p&gt;

&lt;p&gt;You can get the source code in this &lt;a href="https://github.com/ECJ222/cryptodegen-support"&gt;repository&lt;/a&gt; and view the &lt;a href="//cryptodegen-support.vercel.app"&gt;demo&lt;/a&gt; in action.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this short series, I can’t wait to see what you build!&lt;/p&gt;

</description>
      <category>vue</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to build a Live Chat in your Web Application using Robin Part 1</title>
      <dc:creator>Enoch Chejieh</dc:creator>
      <pubDate>Fri, 12 Aug 2022 09:34:00 +0000</pubDate>
      <link>https://dev.to/ecj222/how-to-build-a-live-chat-in-your-web-application-using-robin-part-1-2m4f</link>
      <guid>https://dev.to/ecj222/how-to-build-a-live-chat-in-your-web-application-using-robin-part-1-2m4f</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3m1cfn4ppwaxpycoju9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3m1cfn4ppwaxpycoju9.jpg" alt="Happy People"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article is part of a two-part series on “How to build a Live Chat in your Web Application using Robin”. &lt;/p&gt;

&lt;p&gt;Now let’s get started.&lt;/p&gt;

&lt;p&gt;Instant gratification and fast-paced decision-making have become the main driving factors that draw user's attention to any modern web application. Live chat is one of those features which offers this to users, A user just needs to type a question, and in a few minutes, they have gotten a response.&lt;/p&gt;

&lt;p&gt;Over 70% of B2C and B2B companies use live chat services as part of their customer strategy, and research tells us it delivers the highest customer satisfaction levels.&lt;/p&gt;

&lt;p&gt;In this two-part series, I will show you how you can integrate Robin into your web application using Robin's Javascript and Vue SDK. Robin is a chat messaging solution that allows users and developers to leverage its chat API and SDK for building in-app messaging without worrying about implementing complex features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along with this tutorial, you should have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any frontend framework of your choice&lt;/li&gt;
&lt;li&gt;Robin API key&lt;/li&gt;
&lt;li&gt;A backend server to retrieve data from a database (You can use any of your choice)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For demonstration purposes, the demo application used in this article was built with Next.JS, but you can follow along using any frontend framework of your choice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zlo62qcruhczozjy00p.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zlo62qcruhczozjy00p.png" alt="CryptoDegen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CryptoDegen is a decentralized analytical tool which allows users to keep track of their digital assets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can get your Robin API key from your &lt;a href="https://dashboard.robinapp.co/signup" rel="noopener noreferrer"&gt;Robin Account&lt;/a&gt;. This will give you the authorization to access Robin features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initializing Robin Javascript SDK
&lt;/h2&gt;

&lt;p&gt;To initialize Robin Javascript SDK, you first need to install the SDK into your frontend application.&lt;/p&gt;

&lt;p&gt;To install, simply copy and paste the following code into your terminal:&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 robin.io-js --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before you initialize Robin, head over to your Robin account to get your API key, It's recommended you store it in a secure location like in your environment variables, for example.&lt;/p&gt;

&lt;p&gt;Once you've stored your API key, you can proceed on to initializing Robin in your application.&lt;/p&gt;

&lt;p&gt;Create a new page called &lt;code&gt;src/pages/index.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

import { useState, useEffect } from 'react'
import Message from '../components/Message'
import { Robin } from 'robin.io-js'

const Home: NextPage = () =&amp;gt; {
    const [isLoggedIn, setIsLoggedIn] = useState(false)
    const [userData, setUserData] = useState({} as ObjectType)
    const apiKey = 'NT-XmIzEmWUlsrQYypZOFRlogDFvQUsaEuxMfZf'
    const channel = 'private_chat'
    const [robin, setRobin] = useState(null as Robin | null)

    const initiateRobin: () =&amp;gt; void = () =&amp;gt; {
    const robinInstance = new Robin(apiKey, true)
    setRobin(robinInstance)
    }

    return ( 
      &amp;lt;Message isLoggedIn={isLoggedIn} robin={robin} channel={channel} userData={userData} /&amp;gt;
    )
}

export default Home
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Place the initiateRobin function in a &lt;code&gt;useEffect()&lt;/code&gt; hook to ensure Robin is initiated as soon as the Dom has loaded.&lt;br&gt;
&lt;/p&gt;

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

useEffect(() =&amp;gt; {
   initiateRobin()
 }, [])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a Robin user token
&lt;/h2&gt;

&lt;p&gt;This tutorial mocks the user login process from the frontend to simulate what it would be like to authenticate a real user or create a new one and then assign a Robin user token to that user from a backend server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FxKJE4ZX.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FxKJE4ZX.gif" alt="Creating a Robin user token on CryptoDegen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a method called &lt;code&gt;createUserToken()&lt;/code&gt; this is where you would create the robin user token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const createUserToken: (data: ObjectType) =&amp;gt; Promise&amp;lt;string&amp;gt; = async (data: ObjectType) =&amp;gt; {
    const response: ObjectType = await robin?.createUserToken({
      meta_data: {
        ...data
      },
    });

    return response.data.user_token
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create a method called &lt;code&gt;mockUserLogin()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

const mockUserLogin: () =&amp;gt; Promise&amp;lt;void&amp;gt; = async () =&amp;gt; {
    const userPromise: Promise&amp;lt;ObjectType&amp;gt; = new Promise((resolve, _reject): ObjectType =&amp;gt; {
      return setTimeout(async () =&amp;gt; {
        const data: ObjectType = {
          first_name: 'Enoch',
          last_name: 'Chejieh',
          username: 'Enoch Chejieh',
          email: 'enoch11@gmail.com'
        } as ObjectType

        data.user_token = await createUserToken(data)

        resolve({ data })
      }, 100)
    })

    const response: ObjectType = await userPromise

    setUserData({ ...userData, ...response.data })

    setIsLoggedIn(true)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create a function called &lt;code&gt;mockUserSignup()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

const mockUserSignup: () =&amp;gt; Promise&amp;lt;void&amp;gt; = async () =&amp;gt; {
  const userPromise: Promise&amp;lt;ObjectType&amp;gt; = new Promise((resolve, _reject): ObjectType =&amp;gt; {
    return setTimeout(async () =&amp;gt; {
      const data = {
        first_name: 'Enoch',
        last_name: 'Chejieh',
        username: 'Enoch Chejieh',
        email: 'enoch11@gmail.com'
      } as ObjectType

      data.user_token = await createUserToken(data)

      resolve({ data })
    }, 100)
  })

  const response : ObjectType = await userPromise

  setUserData({ ...userData, ...response.data })

  setIsLoggedIn(true)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create a function called &lt;code&gt;mockUserLogout()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

const mockUserLogout = () =&amp;gt; {
  setIsLoggedIn(false)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would need to create these functions to simulate the user authentication processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling events
&lt;/h2&gt;

&lt;p&gt;Robin dispatches a variety of events you can listen to such as &lt;code&gt;user.connect&lt;/code&gt;, &lt;code&gt;user.disconnect&lt;/code&gt;, &lt;code&gt;new.conversation&lt;/code&gt;, &lt;code&gt;message.forward&lt;/code&gt;, &lt;code&gt;message.reaction&lt;/code&gt;, &lt;code&gt;message.remove.reaction&lt;/code&gt;, &lt;code&gt;remove.group.participant&lt;/code&gt;, &lt;code&gt;read.reciept&lt;/code&gt;, and &lt;code&gt;group.icon.update&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before you can listen to a dispatched event, we need to establish a connection to Robin's WebSocket.&lt;/p&gt;

&lt;p&gt;Create a component called &lt;code&gt;src/components/message.tsx&lt;/code&gt;, copy and paste the following code:&lt;br&gt;
&lt;/p&gt;

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

import { useState, useEffect, useRef } from 'react'
import { Robin } from 'robin.io-js'

type ObjectType = Record&amp;lt;string, any&amp;gt;

interface PropTypes { isLoggedIn: boolean, robin: Robin | null, channel: string, userData: ObjectType }

const Message: React.FC&amp;lt;PropTypes&amp;gt; = ({ isLoggedIn, robin, channel, userData }) =&amp;gt; {
    const message: any = useRef(null)
    const [isMessagerOpen, setIsMessagerOpen] = useState(false)
    const [connection, setConnection] = useState(null as any)

    const connect: () =&amp;gt; void = () =&amp;gt; {
      const connectionInstance = robin?.connect(userData?.user_token)

      setConnection(connectionInstance)

      const WebSocket: WebSocket | undefined = connection

       window.onbeforeunload = function () {
         WebSocket?.close()
       }
   }

   return (...)
}

export default Message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;connect()&lt;/code&gt; method is what you use to establish a connection to Robin's WebSocket.&lt;br&gt;
Once we have established your WebSocket connection. &lt;/p&gt;

&lt;p&gt;Next, you need to handle events. Copy and paste the following code in your &lt;code&gt;src/components/message.tsx&lt;/code&gt; Component:&lt;br&gt;
&lt;/p&gt;

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

useEffect(() =&amp;gt; {
     if (isLoggedIn) {

       if (connection) {
         connection.onopen = () =&amp;gt; {
           robin?.subscribe(channel, connection as WebSocket)
         }

          connection.onmessage = (event: any) =&amp;gt; {
          const message = JSON.parse(event.data)

          if (!message.is_event) {
             if (message.conversation_id === conversation._id) {
               setConversationMessages((messages) =&amp;gt; [...messages, message])
              }
           } else {
             handleRobinEvents(message)
           }
           }

         connection.onclosed = () =&amp;gt; {
           connect()
         }
       } else {
         connect()
       }
    }

}, [isLoggedIn, connection, conversation])

const handleRobinEvents: (message: ObjectType) =&amp;gt; void = (message: ObjectType) =&amp;gt; {
    switch (message.name) {
      case 'user.connect':
        // Event dispatched when WebSocket connection is established.
        break
      case 'user.disconnect':
        // Event dispatched when the WebSocket connection has been disconnected.
        break
      case 'new.conversation':
        // Event dispatched when a new conversation is created.
        break
      case 'message.forward':
        // Event dispatched when a message is forwarded.
        break
      case 'message.reaction':
        // Event dispatch when message reaction has been added.
        break
      case 'message.remove.reaction':
        // Event dispatched when a message reaction has been removed.
        break
      case 'remove.group.participant':
        // Event dispatched when a group participant has been removed.
        break
      case 'read.reciept':
        // Event dispatched when a message has been read.
        break
      case 'group.icon.update':
        // Event dispatched when a group icon has been updated.
        break
      default:
        break
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Robin method &lt;code&gt;subscribe()&lt;/code&gt; is used for subscribing your Robin connection to a channel name. You need to do this to send messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a conversation
&lt;/h2&gt;

&lt;p&gt;Once you have established a connection with Robin's WebSocket, you can now proceed to create a conversation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fbupvmcr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fbupvmcr.gif" alt="Creating a conversation on CryptoDegen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a function called &lt;code&gt;createConversation()&lt;/code&gt; in your &lt;code&gt;src/components/message.tsx&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

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

const createConversation: () =&amp;gt; Promise&amp;lt;void&amp;gt; = async () =&amp;gt; {
    setIsMessagesLoading(true)

    const response = await robin?.createConversation({
      sender_name: userData.username,
      sender_token: userData.user_token,
      receiver_token: receiverToken,
      receiver_name: receiverName
    })

    if (response &amp;amp;&amp;amp; !response.error) {
      setConversation({ ...conversation, ...response.data })
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Robin method &lt;code&gt;createConversation()&lt;/code&gt; takes in an object as a parameter which must contain a &lt;code&gt;sender_name&lt;/code&gt;, &lt;code&gt;sender_token&lt;/code&gt;, &lt;code&gt;receiver_token&lt;/code&gt;, and  &lt;code&gt;receiver_name&lt;/code&gt; key and value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting conversation messages
&lt;/h2&gt;

&lt;p&gt;To handle retrieving messages from a conversation, create a function called &lt;code&gt;getMessages()&lt;/code&gt; in your &lt;code&gt;src/components/message.tsx&lt;/code&gt; Component:&lt;br&gt;
&lt;/p&gt;

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

const getMessages: () =&amp;gt; Promise&amp;lt;void&amp;gt; = async () =&amp;gt; {
    setIsMessagesLoading(true)
    const response = await robin?.getConversationMessages(conversation._id, userData.user_token)
    if (response &amp;amp;&amp;amp; !response.error) {
      setIsMessagesLoading(false)
      if (response.data) setConversationMessages((messages) =&amp;gt; [...messages, ...response.data])
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function is called as soon as the &lt;code&gt;src/components/message.tsx&lt;/code&gt; Component is mounted on the Dom and retrieves the messages from the given &lt;code&gt;conversation_id&lt;/code&gt; provided.&lt;/p&gt;

&lt;p&gt;The Robin method &lt;code&gt;getConversationMessages()&lt;/code&gt; takes in two parameters the &lt;code&gt;conversation_id&lt;/code&gt; and &lt;code&gt;user_token&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending a message to a conversation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FFOUdBIO.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FFOUdBIO.gif" alt="Sending a message to a conversation on CryptoDegen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, handling sending messages, you need to create a function called sendMessage in your &lt;code&gt;src/components/message.tsx&lt;/code&gt; Component:&lt;br&gt;
&lt;/p&gt;

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


const sendMessage: () =&amp;gt; Promise&amp;lt;void&amp;gt; = async () =&amp;gt; {
    const messageObject: ObjectType = {
      msg: message.current.value,
      sender_token: userData.user_token,
      receiver_token: receiverToken,
      timestamp: new Date()
    }

    await robin?.sendMessageToConversation(
      {
        ...messageObject
      },
      connection,
      channel,
      conversation._id,
      userData.user_token,
      userData.username
    )

    message.current.value = ''
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Robin method &lt;code&gt;sendMessageToConversation&lt;/code&gt; takes in couple of parameters, which includes &lt;code&gt;message_object&lt;/code&gt;, &lt;code&gt;connection&lt;/code&gt;, &lt;code&gt;channel&lt;/code&gt;, &lt;code&gt;connection_id&lt;/code&gt;, &lt;code&gt;user_token&lt;/code&gt;, and &lt;code&gt;username&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending a message with an attachment to a conversation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FviG7h9j.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FviG7h9j.gif" alt="Sending a message with an attachment to a conversation on CryptoDegen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, handling sending message attachments, you would need to create a function called &lt;code&gt;sendMessageAttachment()&lt;/code&gt; in your &lt;code&gt;src/components/message.tsx&lt;/code&gt; Component:&lt;br&gt;
&lt;/p&gt;

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

const sendMessageAttachment: (file: File) =&amp;gt; void = async (file: File) =&amp;gt; {
    await robin?.sendMessageAttachment(userData.user_token, conversation._id, file, userData.username, '')

    message.current.value = ''
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Robin method sendMessageAttachment takes in a few parameters, which include &lt;code&gt;user_token&lt;/code&gt;, &lt;code&gt;conversation_id&lt;/code&gt;, &lt;code&gt;username&lt;/code&gt;, and &lt;code&gt;message&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;In this part, you’ve learned how to initialize Robin, create conversations, user tokens, get messages, send messages and more.&lt;/p&gt;

&lt;p&gt;Robin was instrumental in creating this Live Chat feature on the CryptoDegen application used in this article, as it is integrated easily and helps with customer support.&lt;/p&gt;

&lt;p&gt;Robin also provides other APIs which the Javascript SDK utilizes. To view more, check them &lt;a href="https://robin-io-js-doc-csgdc.ondigitalocean.app/classes/Robin.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Robin has a variety of SDK for different frameworks and languages such as Javascript, Vue, Flutter, Go and Python to support the developer’s various needs.&lt;/p&gt;

&lt;p&gt;You can get the source code &lt;a href="https://github.com/ECJ222/cryptodegen" rel="noopener noreferrer"&gt;in this repository&lt;/a&gt; and view the &lt;a href="//cryptodegen.vercel.app"&gt;demo&lt;/a&gt; in action.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/ecj222/how-to-build-a-live-chat-in-your-web-application-using-robin-part-2-1o68"&gt;next part&lt;/a&gt;, we’ll look at how we can utilize Robin’s Vue SDK to interact with the user messages from the customer's support end. &lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>react</category>
      <category>nextjs</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to build a blockchain from scratch in Rust</title>
      <dc:creator>Enoch Chejieh</dc:creator>
      <pubDate>Mon, 03 Jan 2022 08:59:25 +0000</pubDate>
      <link>https://dev.to/ecj222/how-to-build-a-blockchain-from-scratch-in-rust-46</link>
      <guid>https://dev.to/ecj222/how-to-build-a-blockchain-from-scratch-in-rust-46</guid>
      <description>&lt;p&gt;2021 was a huge year for cryptocurrencies, NFT's, and decentralized applications (DAPPs), and 2022 will be even bigger. Blockchain is the underlying technology behind all these technologies.&lt;/p&gt;

&lt;p&gt;Blockchain technology has the potential to change nearly every aspect of our lives from the Finance industry, Travel &amp;amp; mobility, Infrastructures, Healthcare, Public sector, Retail, Agriculture &amp;amp; mining, Education, Communication, Entertainment, and more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every smart person that I admire in the world, and those I semi-fear, is focused on this concept of crypto for a reason. They understand that this is the driving force of the fourth industrial revolution: steam engine, electricity, then the microchip — blockchain and crypto is the fourth. &lt;br&gt;
— Brock Pierce&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhvm40wp4py0kvpecxrxu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhvm40wp4py0kvpecxrxu.jpg" alt="Blockchain" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a blockchain?
&lt;/h3&gt;

&lt;p&gt;A blockchain is a decentralized ledger of transactions across a peer-to-peer network, you can also think of a blockchain like a decentralized database that is immutable. A blockchain can be broken down fundamentally into several components e.g Node, Transaction, Block, Chain and The consensus protocol (proof of work, proof of stake, proof of history).&lt;/p&gt;

&lt;p&gt;If you are anything like me, you learn by building. Now the reason I’m writing this article is to give you a basic overview of how blockchains work by building a blockchain with Rust.&lt;/p&gt;

&lt;p&gt;Sounds good? Let’s get to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;Let us start by creating a new Rust project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo +nightly new blockchain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change to the directory you just created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd blockchain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s add the necessary packages we need to build a blockchain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dependencies]
chrono = "0.4"
serde = { version = "1.0.106", features = ["derive"] }
serde_json = "1.0"
sha2 = "0.10.0"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create folder called models, that’s where you will keep most of your blockchain logic. In that folder create two (2) files called &lt;code&gt;blockchain.rs&lt;/code&gt; and &lt;code&gt;block.rs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Import the following packages in both of the files and save them:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;blockchain.rs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use chrono::prelude::*;
// Internal module
use super::block::Block;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;block.rs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use super::blockchain::Blockchain;
use chrono::prelude::*;
use sha2::{Sha256, Digest};
use serde::{Deserialize, Serialize};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you noticed we imported use &lt;code&gt;super::block::Block;&lt;/code&gt; in our &lt;code&gt;blockchain.rs&lt;/code&gt; file, we are just importing the struct located in our &lt;code&gt;block.rs&lt;/code&gt; file here, don’t worry I will explain that a bit later.&lt;/p&gt;

&lt;p&gt;After we have imported the necessary packages let’s create a type in our &lt;code&gt;blockchain.rs&lt;/code&gt; file called &lt;code&gt;Blocks&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Blocks = Vec&amp;lt;Block&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s create a &lt;code&gt;Blockchain&lt;/code&gt; type in &lt;code&gt;blockchain.rs&lt;/code&gt; and an empty implementation for our &lt;code&gt;Blockchain&lt;/code&gt; type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// `Blockchain` A struct that represents the blockchain.
#[derive(Debug)]
pub struct Blockchain {
  // The first block to be added to the chain.
  pub genesis_block: Block,
  // The storage for blocks.
  pub chain: Blocks,
  // Minimum amount of work required to validate a block.
  pub difficulty: usize
}
impl Blockchain {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s create a &lt;code&gt;Block&lt;/code&gt; type in &lt;code&gt;block.rs&lt;/code&gt; and an empty implementation for our &lt;code&gt;Block&lt;/code&gt; type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// `Block`, A struct that represents a block in a Blockchain.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Block {
   // The index in which the current block is stored.
   pub index: u64,
   // The time the current block is created.
   pub timestamp: u64,

   // The block's proof of work.
   pub proof_of_work: u64,
   // The previous block hash.
   pub previous_hash: String,
   // The current block hash.
   pub hash: String
}
impl Block {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating the genesis block:
&lt;/h3&gt;

&lt;p&gt;The genesis block is the first block created in a blockchain. Let’s create a function that creates a genesis block for our blockchain and returns a new instance of the &lt;code&gt;Blockchain&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;Add the following code in our &lt;code&gt;Blockchain&lt;/code&gt; implementation in &lt;code&gt;blockchain.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;impl Blockchain {
   pub fn new(difficulty: usize) -&amp;gt; Self {
     // First block in the chain.
     let mut genesis_block = Block {
        index: 0,
        timestamp: Utc::now().timestamp_millis() as u64,
        proof_of_work: u64::default(),
        previous_hash: String::default(),
        hash: String::default()
     };
     // Create chain starting from the genesis chain.
     let mut chain = Vec::new();
     chain.push(genesis_block.clone());
     // Create a blockchain Instance.
     let blockchain = Blockchain {
        genesis_block,
        chain,
        difficulty
     };
     blockchain
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Created our &lt;code&gt;genesis_block&lt;/code&gt; instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Added the &lt;code&gt;genesis_block&lt;/code&gt; we created to the chain in our &lt;code&gt;Blockchain&lt;/code&gt; type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Returned an instance of the &lt;code&gt;Blockchain&lt;/code&gt; type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the &lt;code&gt;genesis_block&lt;/code&gt; instance we created, notice how we set our previous_hash key to an empty string value (&lt;code&gt;String::default()&lt;/code&gt;) that’s because there would be no previous block since the genesis block is the first block in the blockchain.&lt;/p&gt;

&lt;p&gt;Also notice we made the hash of our &lt;code&gt;genesis_block&lt;/code&gt; to be an empty string (“”) that’s because we haven’t calculated the hash value for our genesis block yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generating the hash of a block
&lt;/h3&gt;

&lt;p&gt;A hash is generated with the help of cryptography and current information present in the block.&lt;/p&gt;

&lt;p&gt;Let’s create a function in our block implementation in the &lt;code&gt;block.rs&lt;/code&gt; file we created called &lt;code&gt;calculate_hash()&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Calculate block hash.
pub fn calculate_hash(&amp;amp;self) -&amp;gt; String {
  let mut block_data = self.clone();
  block_data.hash = String::default();
  let serialized_block_data = serde_json::to_string(&amp;amp;block_data).unwrap();
  // Calculate and return SHA-256 hash value.
  let mut hasher = Sha256::new();
  hasher.update(serialized_block_data);
  let result = hasher.finalize();
  format!("{:x}", result)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Converted the block’s data to JSON format.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hashed the block’s data with the SHA256 algorithm.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Returned the hashing result in base16.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Creating a new block
&lt;/h3&gt;

&lt;p&gt;Great!, we have implemented functionalities for creating our genesis block and calculating the block hashes of our blocks.&lt;/p&gt;

&lt;p&gt;Now let’s add the functionality for adding new blocks to the blockchain, in our blockchain.rs file add this function to the &lt;code&gt;Blockchain&lt;/code&gt; type implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn add_block(&amp;amp;mut self, nonce: String) {
  let new_block = Block::new(
    self.chain.len() as u64,
    nonce,
    self.chain[&amp;amp;self.chain.len() - 1].previous_hash.clone()
  );
  new_block.mine(self.clone());
  self.chain.push(new_block.clone());
  println!("New block added to chain -&amp;gt; {:?}", new_block);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Created an &lt;code&gt;add_block&lt;/code&gt; function that takes in an argument called &amp;amp;mut self (instance of the &lt;code&gt;Blockchain&lt;/code&gt; type).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created our instance of the &lt;code&gt;Block&lt;/code&gt; type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mined a block hash using the &lt;code&gt;Block&lt;/code&gt; type’s mine function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Added the new block to the chain of blocks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, in our &lt;code&gt;block.rs&lt;/code&gt; file add the following code in the &lt;code&gt;Block&lt;/code&gt; type implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Create a new block. The hash will be calculated and set automatically.
pub fn new (
 index: u64,
 previous_hash: String,
) -&amp;gt; Self {
   // Current block to be created.
   let mut block = Block {
      index: 0,
      timestamp: Utc::now().timestamp_millis() as u64,
      proof_of_work: u64::default(),
      previous_hash: String::default(),
      hash: String::default(),
   };
   block
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Created a function called &lt;code&gt;new()&lt;/code&gt; that takes in three arguments index and previous_hash.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created our instance of the &lt;code&gt;Block&lt;/code&gt; type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generated a block hash for our block.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Returned an instance of the &lt;code&gt;Block&lt;/code&gt; type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mining new block
&lt;/h3&gt;

&lt;p&gt;We have successfully implemented functionality for creating a new block.&lt;/p&gt;

&lt;p&gt;Let's implement functionality for mining new blocks. The process of mining new blocks involves generating a SHA256 hash that starts with a desired number of 0s which would be the mining difficulty miners have to solve to mine a new block.&lt;/p&gt;

&lt;p&gt;Let's create a function in our &lt;code&gt;block.rs&lt;/code&gt; file inside our &lt;code&gt;Block&lt;/code&gt; type implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Mine block hash.
pub fn mine (&amp;amp;mut self, blockchain: Blockchain) {
  loop {
    if !self.hash.starts_with(&amp;amp;"0".repeat(blockchain.difficulty)) {
      self.proof_of_work += 1;
      self.hash = self.generate_block_hash();
    } else {
       break
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great job, we are done with implementing our blockchain, now let’s test it out.&lt;/p&gt;

&lt;p&gt;Let’s create a file called &lt;code&gt;mod.rs&lt;/code&gt; in our models folder and save the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub mod block;
pub mod blockchain;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All we are doing here is making the files we created earlier &lt;code&gt;blockchain.rs&lt;/code&gt; and &lt;code&gt;block.rs&lt;/code&gt; publicly accessible in our main.rs file.&lt;/p&gt;

&lt;p&gt;Now let’s paste the following code in our &lt;code&gt;main.rs&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mod models;
fn main() {
   let difficulty = 1;
   let mut blockchain = models::blockchain::Blockchain::new(difficulty);
   models::blockchain::Blockchain::add_block(&amp;amp;mut blockchain);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to initiate a transaction run &lt;code&gt;cargo +nightly run&lt;/code&gt; in your terminal.&lt;/p&gt;

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

&lt;p&gt;In this tutorial you’ve learned how to create a simple blockchain from scratch with Rust.&lt;/p&gt;

&lt;p&gt;I hope you’ve enjoyed reading this article, you can get the full source code of this Rust blockchain &lt;a href="https://github.com/ECJ222/Rust-blockchain" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any comments, please feel free to drop them below.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>blockchain</category>
      <category>web3</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What exactly is IPFS?</title>
      <dc:creator>Enoch Chejieh</dc:creator>
      <pubDate>Fri, 12 Nov 2021 17:37:02 +0000</pubDate>
      <link>https://dev.to/ecj222/what-exactly-is-ipfs-3a8c</link>
      <guid>https://dev.to/ecj222/what-exactly-is-ipfs-3a8c</guid>
      <description>&lt;p&gt;InterPlanetary File System (IPFS) is a term used to describe a peer-to-peer (p2p) distributed file-sharing system for storing and accessing data.&lt;/p&gt;

&lt;p&gt;IPFS is one of a few projects that are part of the Protocol Labs Organization, which was also founded by Benet. Inter-Planetary Linked Data (IPLD) and Filecoin are two Protocol Labs projects that are closely related to IPFS. The IPLD data model is a data model for distributed data structures such as blockchains. This model makes it simple to store and access blockchain data via IPFS. Users who store data on IPFS will be rewarded with Filecoin.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does IPFS work?
&lt;/h3&gt;

&lt;p&gt;Let's imagine you just uploaded some content to IPFS. That content will then be split up into small pieces of data, the data is then given a certain unique fingerprint called a cryptographic hash.&lt;/p&gt;

&lt;p&gt;When multiple people upload the same content to IPFS, it will only be created once and that makes the network very efficient.&lt;/p&gt;

&lt;p&gt;Also when you need to look up content to view or download on IPFS you don't need to remember the hash assigned to that content, every content on IPFS can be found using Inter-Planetary Naming System (IPNS), a human-readable decentralized naming system for IPFS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use IPFS?
&lt;/h3&gt;

&lt;p&gt;The internet as it is today is built on technologies like Hypertext Transfer Protocol (HTTP), Domain Name System (DNS), and the way it works is by looking up IP addresses and forwarding the content from the IP address, This is called location-based addressing.&lt;/p&gt;

&lt;p&gt;When a user searches for a website, let's say &lt;a href="http://amazon.com"&gt;amazon.com&lt;/a&gt; for instance the user is trusting that whatever is located at that server to be the content that they want and that could be a problem because theirs nothing stopping the content from changing without the user doing anything about it.&lt;/p&gt;

&lt;p&gt;Another problem is that when there's only one source of content it creates constriction and centralization. On the contrary, IPFS uses content-based addressing. So when a user is requesting a piece of data it retrieves the content and not the location of that content which is more efficient. This really makes the web a lot more robust and protected.&lt;/p&gt;

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

&lt;p&gt;Software developers are currently moving to decentralized data networks as a way to build new models around data ownership and to develop a better internet.&lt;/p&gt;

&lt;p&gt;This article is just an introduction to IPFS, there's still a lot to know about this wonderful technology. If you want to know more you can check out their &lt;a href="https://ipfs.io/"&gt;website&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Error Handling in Rust</title>
      <dc:creator>Enoch Chejieh</dc:creator>
      <pubDate>Sun, 24 Oct 2021 08:08:18 +0000</pubDate>
      <link>https://dev.to/ecj222/error-handling-in-rust-7pp</link>
      <guid>https://dev.to/ecj222/error-handling-in-rust-7pp</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In this article, we're going to take a look at Error handling in Rust and how it improves the performance of Rust web applications.&lt;/p&gt;

&lt;p&gt;Error handling is an important part of software development because it improves the way we think about software as we build and it allows us to intercept errors/failures.&lt;/p&gt;

&lt;p&gt;When we build software, we tend to run into bugs or errors in our code and when we do, we are greeted with great error messages which help us identify problems efficiently. This, in turn, boosts our productivity and can lead to a better developer experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Major Difference between Error Handling in Rust and Other Programming Languages
&lt;/h3&gt;

&lt;p&gt;Compared to other programming languages that handle errors by throwing exceptions, Rust handles errors by returning actual errors. While throwing exceptions is very useful for the identification of error types and error reporting, it's not very explicit, which means it would be easy to miss areas of code that should have exception handling. Rust, on the other hand, returns errors explicitly.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Rust Handles Errors
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Result Type
&lt;/h4&gt;

&lt;p&gt;The result type &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; is an enum that has two possible states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;T&lt;/code&gt; can be any type and &lt;code&gt;E&lt;/code&gt; can be any error. The two states &lt;code&gt;Ok(T)&lt;/code&gt; represent success and holds a value, and &lt;code&gt;Err(E)&lt;/code&gt; represent error and holds a specific error value.&lt;/p&gt;

&lt;p&gt;We use the result type when operations might go wrong. An operation is expected to succeed, but there might be cases where it fails.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;num&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ParseIntError&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;convert_string_to_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;ParseIntError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 200&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&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;Here's what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When &lt;code&gt;convert_string_to_integer&lt;/code&gt; is called, this function converts a string to an integer value based on the string parameter passed in the function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With the &lt;code&gt;match number_str.parse()&lt;/code&gt; we are required to handle the two possible states. When we pass a string containing only numbers, the operation succeeds then we assign the converted value to the &lt;code&gt;number&lt;/code&gt; variable, or we return from the function by returning the error when the operation fails.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Panic
&lt;/h3&gt;

&lt;p&gt;In Rust, When you encounter an unrecoverable error they can be handled by &lt;code&gt;panic!&lt;/code&gt;. &lt;code&gt;panic!&lt;/code&gt; allows you to stop your program in execution when you encounter this kind of error and also provides useful feedback. &lt;/p&gt;

&lt;p&gt;Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;num&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ParseIntError&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;convert_string_to_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;ParseIntEror&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid digit found in string"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 200&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&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;When we encounter an error in this function &lt;code&gt;panic!('Invalid digit found in string')&lt;/code&gt; will be invoked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unwrap
&lt;/h3&gt;

&lt;p&gt;There might be some situations that you are very confident about the code you have written and you feel positive that your code won't encounter errors and you want to opt-out of error handling.&lt;/p&gt;

&lt;p&gt;In that case you can simply use the &lt;code&gt;unwrap()&lt;/code&gt; method, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;convert_string_to_integer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;convert_string_to_integer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Expect
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;expect()&lt;/code&gt; method is similar to the &lt;code&gt;unwrap()&lt;/code&gt; but unlike &lt;code&gt;unwrap()&lt;/code&gt;, The &lt;code&gt;expect()&lt;/code&gt; method allows you to set an error message. This makes debugging a lot easier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;convert_string_to_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"o100"&lt;/span&gt; 
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid digit in string"&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 output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;thread &lt;span class="s1"&gt;'main'&lt;/span&gt; panicked at &lt;span class="s1"&gt;'Invalid digit in string: ParseIntError { kind: InvalidDigit }'&lt;/span&gt;, src/main.rs:11:20
note: run with &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;RUST_BACKTRACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1&lt;span class="sb"&gt;`&lt;/span&gt; environment variable to display a backtrace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Question Mark Operator (?)
&lt;/h3&gt;

&lt;p&gt;The (?) operator makes the propagation of errors much easier and it's equivalent to the match expression. It eliminates a lot of verbosities when implementing functions and it can only be applied for &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; and &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; types, unlike the match expression, it unpacks the Result if Ok and returns the error if it's not.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;num&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ParseIntError&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;convert_string_to_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ParseIntError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number_str&lt;/span&gt;&lt;span class="nf"&gt;.parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;convert_string_to_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Ok(200)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how our code looks much more simpler and easier to read.&lt;/p&gt;

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

&lt;p&gt;Error handling is about good communication. Rust has made a strong emphasis on making error handling a good experience for developers.&lt;/p&gt;

&lt;p&gt;There is of course more methods used in Rust for error handling, but the ones covered in this article should get you started, this is also my first technical rust article and I look forward to writing more, please if you have any questions or comments please feel free to ask them in the comment section.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
