<?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>Forem: Idorenyin Obong</title>
    <description>The latest articles on Forem by Idorenyin Obong (@kingidee).</description>
    <link>https://forem.com/kingidee</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%2F37325%2F52624fd2-c2be-45ab-819e-3f8b2b64d724.jpeg</url>
      <title>Forem: Idorenyin Obong</title>
      <link>https://forem.com/kingidee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kingidee"/>
    <language>en</language>
    <item>
      <title>Build an anonymous chat app with React &amp; React bootstrap</title>
      <dc:creator>Idorenyin Obong</dc:creator>
      <pubDate>Thu, 27 Jun 2019 06:59:05 +0000</pubDate>
      <link>https://forem.com/kingidee/build-an-anonymous-chat-app-with-react-react-bootstrap-4h1c</link>
      <guid>https://forem.com/kingidee/build-an-anonymous-chat-app-with-react-react-bootstrap-4h1c</guid>
      <description>&lt;p&gt;This article was first published on &lt;a href="https://www.cometchat.com/tutorials/build-an-anonymous-chat-app-with-react-react-bootstrap/" rel="noopener noreferrer"&gt;CometChat's tutorial page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To follow this article effectively, it is expected that you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prior knowledge of React. You can use this &lt;a href="https://reactjs.org/tutorial/tutorial.html" rel="noopener noreferrer"&gt;resource&lt;/a&gt; to get up to speed with it.&lt;/li&gt;
&lt;li&gt;Node.js and NPM installed on your machine.&lt;/li&gt;
&lt;li&gt;A text editor or IDE. VSCode is recommended.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Allowing users to communicate is becoming an essential feature for many apps. In my experience, chat closes the distance between you and your customers and can lead to more conversions, improved engagement; and ultimately, greater success for your business. However, implementing chat can be time-consuming.&lt;/p&gt;

&lt;p&gt;In this tutorial, I am excited to show you how you can build an aesthetic group chat with minimal code by leveraging, React, React Bootstrap, and CometChat.&lt;/p&gt;

&lt;p&gt;Here is a preview of what you will build:&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%2Fucarecdn.com%2F70f941bc-dbf6-4ae5-974f-c846ef9bafa4%2F" 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%2Fucarecdn.com%2F70f941bc-dbf6-4ae5-974f-c846ef9bafa4%2F" alt="Anonymous-group-chat-app.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can choose to dive right into &lt;a href="https://github.com/cometchat-pro-tutorials/react-anonymous-group-chat" rel="noopener noreferrer"&gt;code&lt;/a&gt; or go through our step by step tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaffolding a new React project
&lt;/h2&gt;

&lt;p&gt;For this article, to quickly scaffold a new React app, you will use one of the very popular tools available – the &lt;a href="https://github.com/facebook/create-react-app" rel="noopener noreferrer"&gt;create-react-app CLI tool&lt;/a&gt;. Open a terminal, move into the directory where you usually save your projects and run this command:&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 react-anonymous-chat 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the command, the CLI will begin the process of installing the default dependencies for a React project. Depending on your internet speed, this should take a couple of minutes to complete. After setting up your project, open your new project in your preferred text editor or IDE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Dependencies
&lt;/h2&gt;

&lt;p&gt;Now that you have scaffolded your app, the next step is to install dependencies necessary for your chat application. For this article, you’ll need the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@cometchat-pro/chat&lt;/code&gt;: This module will enable us to connect to CometChat and begin sending and receiving messages in real-time&lt;br&gt;
&lt;code&gt;react-bootstrap&lt;/code&gt;: This is a UI library built on top of react and core Bootstrap. You will use it to style the entire app in this article&lt;br&gt;
&lt;code&gt;react-router-dom&lt;/code&gt;: You will use it for client-side routing&lt;br&gt;
&lt;code&gt;uuid&lt;/code&gt;: This module will be used to generate unique identifiers&lt;/p&gt;

&lt;p&gt;To install the above modules, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# move into your project directory
cd react-anonymous-chat

# install dependencies using npm
npm install @cometchat-pro/chat react-bootstrap react-router-dom uuid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;To begin using the CometChat Pro SDK in your newly created React project, you’ll need a CometChat Pro account. If you don’t have an account, you can quickly create one here.&lt;/p&gt;

&lt;p&gt;After creating an account, go to your dashboard and create a new app called react-anonymous-chat. After creating a new app, you will find the APP ID attached close to the name of your app. If you open your app and go to the API Keys section, you will see a key with &lt;strong&gt;fullAccess&lt;/strong&gt; scope. Copy it out as well as the APP ID. We’ll need these shortly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get the CometChat API
&lt;/h2&gt;

&lt;p&gt;Next, create a &lt;code&gt;.env&lt;/code&gt; file in the root of your project to store your app credentials. Take care not to commit this file to version control! This is important for protecting your secrets when you publish your app. You can easily create the file by running this command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Open the file and paste this snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_COMETCHAT_APIKEY=YOUR_API_KEY_GOES_HERE
REACT_APP_COMETCHAT_APPID=YOUR_APP_ID_GOES_HERE 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the placeholders with your APP ID and API KEY from your dashboard.&lt;/p&gt;

&lt;p&gt;Since your keys are now ready, you can initialize &lt;code&gt;CometChat&lt;/code&gt; in the &lt;code&gt;index.js&lt;/code&gt; file generated by Create React App. Open your &lt;code&gt;index.js&lt;/code&gt; file and replace it with this snippet:&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 ReactDOM from 'react-dom';
import App from './App';
import { CometChat } from '@cometchat-pro/chat';

CometChat.init(process.env.REACT_APP_COMETCHAT_APPID)
  .then(() =&amp;gt; {
    console.log('Initialised CometChat');
  })
  .catch(() =&amp;gt; {
    console.log('Failed to Initialise CometChat');
  });

ReactDOM.render(, document.getElementById('root')); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before going ahead, you’ll need to import Bootstrap in public/index.htm 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;link
  rel="stylesheet"
  href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
  integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
  crossorigin="anonymous"
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building your components
&lt;/h2&gt;

&lt;p&gt;Your app will have three components, the signup, home, and chat component. The signup component is the page that will enable users to create new accounts. Create a folder named &lt;code&gt;components&lt;/code&gt; inside the &lt;code&gt;src&lt;/code&gt; directory. This is where you will add your components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signup component
&lt;/h2&gt;

&lt;p&gt;In this component, you will build out a form to help create new users on the app. A user will have a &lt;code&gt;UID&lt;/code&gt;, an email address, and a name. The &lt;code&gt;UID&lt;/code&gt; value has to be unique.&lt;/p&gt;

&lt;p&gt;Create a new file named &lt;code&gt;Signup.js&lt;/code&gt;, Inside the file, add these imports:&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 Button from 'react-bootstrap/Button'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Form from 'react-bootstrap/Form'
import Alert from 'react-bootstrap/Alert'
import Spinner from 'react-bootstrap/Spinner'
import { Redirect, Link } from 'react-router-dom'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, you are importing some components from the core &lt;code&gt;react-bootstrap&lt;/code&gt; components as well as components from &lt;code&gt;react-router-dom&lt;/code&gt; dependency.&lt;/p&gt;

&lt;p&gt;Next, you define the initial state for your signup component in the &lt;code&gt;Signup.js&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;class Signup extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      uid: '',
      name: '',
      email: '',
      UIDError: null,
      errors: null,
      redirect: false,
      isLoading: false
    };
  }
  //... other class methods
}
export default Signup;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, you defined a state to hold data for the signup form and error messages. Here are the specific functions of each of the objects declared in the state:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;uid&lt;/code&gt;: This holds the current value of the text inputted in the username form field.&lt;br&gt;
&lt;code&gt;name&lt;/code&gt;: This holds the current value of the user’s name in the form field.&lt;br&gt;
&lt;code&gt;email&lt;/code&gt;: This holds the current value of the user’s email in the form field.&lt;br&gt;
&lt;code&gt;UIDError&lt;/code&gt;: This object will keep track of errors when validating the username field.&lt;br&gt;
&lt;code&gt;errors&lt;/code&gt;: This stores error messages when validating other fields.&lt;br&gt;
redirect: This keeps tracks of success on form submission.&lt;br&gt;
&lt;code&gt;isLoading&lt;/code&gt;: This is used for providing visual feedback when using &lt;code&gt;&amp;lt;Spinner /&amp;gt;&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;UIDError&lt;/code&gt; object keeps track of errors on the username field while &lt;code&gt;errors&lt;/code&gt; keeps track of errors on other fields. They are separated because the username field does not accept spaces and as such, they do not have the same validation logic.&lt;/p&gt;

&lt;p&gt;After defining the state, you will create the user interface to represent the current state of your application. Add this render method to your &lt;code&gt;Signup&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render() {
  if (this.state.redirect) return ;
  return (
    &amp;lt;React.Fragment&amp;gt;
      &amp;lt;Row
        className='d-flex justify-content-center align-items-center w-100 mt-5'
        style={{
          minHeight: '100%'
        }}
      &amp;gt;
      &amp;gt;Col&amp;gt;
        {this.state.errors !== null &amp;amp;&amp;amp; (
          &amp;lt;Alert variant='danger'&amp;gt;
            &amp;lt;ul&amp;gt;
              {this.showErrors().map(err =&amp;gt; (
                &amp;lt;li key={err}&amp;gt;{err&amp;lt;/li&amp;gt;
              ))}
            &amp;lt;/ul&amp;gt;
          &amp;lt;/Alert&amp;gt;
        )}
        &amp;lt;Form onSubmit={this.handleSubmit}&amp;gt;
          &amp;lt;Form.Group controlId='username'&amp;gt;
            &amp;lt;Form.Label&amp;gt;User ID&amp;lt;/Form.Label&amp;gt;
            &amp;lt;Form.Control
              required
              type='text'
              name='uid'
              value={this.state.uid}
              placeholder='Choose a username'
              onChange={this.handleChange}
            /&amp;gt;
            {this.state.UIDError !== null &amp;amp;&amp;amp; (
              &amp;lt;Form.Control.Feedback
                style={{ display: 'block' }}
                type='invalid'
              &amp;gt;
                {this.state.UIDError}
              &amp;lt;/Form.Control.Feedback&amp;gt;
            )}
            &amp;lt;/Form.Group&amp;gt;
              &amp;lt;Form.Group controlId='display-name'&amp;gt;
                &amp;lt;Form.Label&amp;gt;Name&amp;lt;/Form.Label&amp;gt;
                &amp;lt;Form.Control
                  required
                  type='text'
                  name='name'
                  value={this.state.name}
                  placeholder='What is your name?'
                  onChange={this.handleChange}
                /&amp;gt;
              &amp;lt;/Form.Group&amp;gt;
              &amp;lt;Form.Group controlId='email'&amp;gt;
                &amp;lt;Form.Label&amp;gt;Email Address&amp;lt;/Form.Label&amp;gt;
                &amp;lt;Form.Control
                  required
                  type='email'
                  name='email'
                  value={this.state.email}
                  placeholder='Your email address'
                  onChange={this.handleChange}
                /&amp;gt;
              &amp;lt;/Form.Group&amp;gt;
              &amp;lt;Button
                disabled={this.state.isLoading}
                variant='primary'
                type='submit'
                className='btn-block'
              &amp;gt;
                {this.state.isLoading ? (
                  &amp;lt;&amp;gt;
                    &amp;lt;Spinner
                      as='span'
                      animation='grow'
                      size='sm'
                      role='status'
                      aria-hidden='true'
                    /&amp;gt;
                    Please wait...
                  &amp;lt;/&amp;gt;
                ) : (
                  &amp;lt;span&amp;gt;Create My Account&amp;lt;/span&amp;gt;
                )}
              &amp;lt;/Button&amp;gt;
              &amp;lt;p className='pt-3'&amp;gt;
                Already have an account? &amp;lt;Link to='/'&amp;gt;Login&amp;lt;/Link&amp;gt;
              &amp;lt;/p&amp;gt;
            &amp;lt;/Form&amp;gt;
          &amp;lt;/Col&amp;gt;
        &amp;lt;/Row&amp;gt;
      &amp;lt;/React.Fragment&amp;gt;
    );
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here in this snippet, you declared a form where the values of the inputs are bound to the state you defined earlier. The form contains three inputs with native form validation except for the username input. It also contains a &lt;code&gt;&amp;lt;Redirect /&amp;gt;&lt;/code&gt;component and a &lt;code&gt;Link&lt;/code&gt; that renders the home component where necessary.&lt;/p&gt;

&lt;p&gt;Next, you will create three methods used in the &lt;code&gt;render&lt;/code&gt; method, namely: &lt;code&gt;handleChange&lt;/code&gt;, &lt;code&gt;handleSubmit&lt;/code&gt; and &lt;code&gt;showErrors&lt;/code&gt;. Add these methods to the your &lt;code&gt;Signup.js&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;handleChange = e =&amp;gt; {
  if (e.target.name === 'uid') {
    const uid = e.target.value;
    if (uid.indexOf(' ') &amp;gt; 0) {
      this.setState(
        { UIDError: 'Username cannot contain white spaces' },
        () =&amp;gt; {
          console.log(this.state.UIDError);
        }
      );
    } else {
      this.setState({ UIDError: null });
    }
  }
  this.setState({ [e.target.name]: e.target.value });
};

handleSubmit = e =&amp;gt; {
  e.preventDefault();
  const { uid, name, email } = this.state;
  this.setState({ uid: '', name: '', email: '', isLoading: true });
  fetch('https://api.cometchat.com/v1/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      appid: process.env.REACT_APP_COMETCHAT_APPID,
      apikey: process.env.REACT_APP_COMETCHAT_APIKEY
    },
    body: JSON.stringify({
      uid,
      name,
      email
    })
  })
  .then(response =&amp;gt; response.json())
  .then(data =&amp;gt; {
    const error = data.error;
    if (error) {
      this.setState(
        {
          isLoading: false,
          errors: { ...error.details }
        },
        () =&amp;gt; {
          this.showErrors();
        }
      );
      return;
    }
    this.setState({
      isLoading: false,
      redirect: true
    });
  });
};

showErrors = () =&amp;gt; {
  const errors = this.state.errors;
  let errorMessages = [];
  if (errors !== null) {
    for (const error in errors) {
      errorMessages = [...errorMessages, ...errors[error]];
    }
  }
  return errorMessages;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are building a production app, it is not proper to keep your keys on the frontend. Instead, the keys should be kept on the server-side so that the private key can remain private.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;handleChange&lt;/code&gt; method updates the values of all the input fields as the user types. A custom validation is performed on the username field to prevent usernames without white spaces. The &lt;code&gt;handleSubmit()&lt;/code&gt; method makes a &lt;code&gt;POST&lt;/code&gt; request to the account creation API: &lt;code&gt;https://api.cometchat.com/v1/users&lt;/code&gt; with the details entered by the user. If it is successful, you are then redirected to the home page. The &lt;code&gt;showErrors&lt;/code&gt; method is used to show errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Home component
&lt;/h2&gt;

&lt;p&gt;Now that you are done with the signup component, you will now build the home component. This component is to enable logging in of users.&lt;/p&gt;

&lt;p&gt;Create a new file &lt;code&gt;Home.js&lt;/code&gt; inside the &lt;code&gt;/src/components&lt;/code&gt; directory. Inside the file, add these imports:&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 Button from 'react-bootstrap/Button';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Form from 'react-bootstrap/Form';
import Alert from 'react-bootstrap/Alert';
import Spinner from 'react-bootstrap/Spinner';
import { CometChat } from '@cometchat-pro/chat';
import { Redirect, Link } from 'react-router-dom';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, you imported components that you will make use of just like you did in the signup component. After that, add this snippet in the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Home extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      username: '',
      user: null,
      error: null,
      redirect: false,
      isLoading: false
    };
  }

  //... other class methods

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

&lt;/div&gt;



&lt;p&gt;Here, you declared the initial state for this component. This is similar to what you did in the signup component also, except that you have a username and user object to hold data about the logged in user.&lt;/p&gt;

&lt;p&gt;After that, add these two methods to your class &lt;code&gt;handleChange&lt;/code&gt; and &lt;code&gt;handleSubmit&lt;/code&gt; 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;handleChange = e =&amp;gt; {
  this.setState({ username: e.target.value });
};

handleSubmit = e =&amp;gt; {
  e.preventDefault();
  const username = this.state.username;
  this.setState({ username: '', isLoading: true });
  CometChat.login(username, process.env.REACT_APP_COMETCHAT_APIKEY)
  .then(user =&amp;gt; {
    this.setState({ redirect: true, user, isLoading: false });
    localStorage.setItem('cometchat:authToken', user.authToken);
  })
  .catch(err =&amp;gt; {
    this.setState({ error: err.message, isLoading: false });
  });
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;handleChange&lt;/code&gt; method updates the value of the input field as the user types while the &lt;code&gt;handleSubmit&lt;/code&gt; method will call the &lt;code&gt;login&lt;/code&gt; method provided by &lt;code&gt;CometChat&lt;/code&gt;. To make a login request, the API key defined in the &lt;code&gt;.env&lt;/code&gt; file is passed alongside the username.&lt;/p&gt;

&lt;p&gt;On successful login, the user data is returned and the &lt;code&gt;authToken&lt;/code&gt; is saved for re-authentication later. Next, add the &lt;code&gt;render&lt;/code&gt; method for this component below the &lt;code&gt;handleSubmit&lt;/code&gt; method 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;// other methods above...
render() {
  if (this.state.redirect)
  return (
    &amp;lt;Redirect
      to={{
        pathname: '/chat',
        user: this.state.user
      }}
    /&amp;gt;
  );
  return (
    &amp;lt;React.Fragment&amp;gt;
      &amp;lt;Row
        className='d-flex justify-content-center align-items-center w-100 mt-5'
        style={{
          minHeight: '100%'
        }}
      &amp;gt;
        &amp;lt;Col xs={10} sm={10} md={4} lg={4} className='mx-auto mt-5'&amp;gt;
          {this.state.error !== null &amp;amp;&amp;amp; (
            &amp;lt;Alert variant='danger'&amp;gt;{this.state.error}&amp;lt;/Alert&amp;gt;
          )}
          &amp;lt;Form onSubmit={this.handleSubmit}&amp;gt;
            &amp;lt;Form.Group controlId='username'&amp;gt;
              &amp;lt;Form.Label&amp;gt;Username&amp;lt;/Form.Label&amp;gt;
              &amp;lt;Form.Control
                required
                type='text'
                value={this.state.username}
                placeholder='Enter a Username'
                onChange={this.handleChange}
              /&amp;gt;
            &amp;lt;/Form.Group&amp;gt;
            &amp;lt;Button
              disabled={this.state.isLoading}
              variant='primary'
              type='submit'
              className='btn-block'
            &amp;gt;
              {this.state.isLoading ? (
                &amp;lt;&amp;gt;
                  &amp;lt;Spinner
                    as='span'
                    animation='grow'
                    size='sm'
                    role='status'
                    aria-hidden='true'
                  /&amp;gt;
                  Loading...
                &amp;lt;/&amp;gt;
              ) : (
                &amp;lt;span&amp;gt;Login&amp;lt;/span&amp;gt;
              )}
            &amp;lt;/Button&amp;gt;
            &amp;lt;p className='pt-3'&amp;gt;
              Don't have an account? &amp;lt;Link to='/signup'&amp;gt;Create One&amp;lt;/Link&amp;gt;
            &amp;lt;/p&amp;gt;
          &amp;lt;/Form&amp;gt;
        &amp;lt;/Col&amp;gt;
      &amp;lt;/Row&amp;gt;
    &amp;lt;/React.Fragment&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this snippet, you have a login form to take the user’s username. When the user clicks on the &lt;strong&gt;Login&lt;/strong&gt; button, you take the user input and call the &lt;code&gt;handleSubmit&lt;/code&gt; method you defined earlier in this component. If a success response is received, the user is redirected to the chat component, else, an error is displayed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chat component
&lt;/h2&gt;

&lt;p&gt;This is the component where a user will be able to view messages and send messages in a chat group. First, create a new &lt;code&gt;Chat.js&lt;/code&gt; file in the &lt;code&gt;src/components&lt;/code&gt; directory. After that, add these imports:&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 { CometChat } from '@cometchat-pro/chat';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Container from 'react-bootstrap/Container';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import Navbar from 'react-bootstrap/Navbar';
import { Redirect } from 'react-router-dom';
import uuid from 'uuid';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, add a class with a state inside the Chat.js file 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;class Chat extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      redirect: false,
      user: null,
      receiverID: 'supergroup',
      messageText: '',
      messages: [],
      authToken: null,
      messageType: CometChat.MESSAGE_TYPE.TEXT,
      receiverType: CometChat.RECEIVER_TYPE.GROUP
    };
  }
  //... other class methods
}

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

&lt;/div&gt;



&lt;p&gt;Here, you need a messages array to store all messages sent and received on the group. The &lt;code&gt;messageType&lt;/code&gt; and &lt;code&gt;receiverType&lt;/code&gt; objects define the type of message you want to listen for and for whom the message is for. The &lt;code&gt;receiverID&lt;/code&gt; object is used to identify the group name on which you listen for messages. Here, you used the default group generated for you – &lt;strong&gt;supergroup&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After that, add the &lt;code&gt;render&lt;/code&gt; method for the component just below the constructor 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;render() {
  if (this.state.redirect) return &amp;lt;Redirect to='/' /&amp;gt;;
  return (
    &amp;lt;div
      className='bg-light page'
      style={{ height: '100vh', overflowX: 'hidden' }}
    &amp;gt;
      &amp;lt;Row&amp;gt;
        &amp;lt;Col&amp;gt;
          &amp;lt;Container&amp;gt;
            &amp;lt;div className='d-flex align-items-center justify-content-between'&amp;gt;
              &amp;lt;h3 className='text-center py-3 d-inline'&amp;gt;
                React Anonymous Chat
              &amp;lt;/h3&amp;gt;
              &amp;lt;Button onClick={e =&amp;gt; this.logout()} variant='outline-primary'&amp;gt;
                Logout
              &amp;lt;/Button&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;ul className='list-group' style={{ marginBottom: '60px' }}&amp;gt;
              {this.state.messages.length &amp;gt; 0 ? (
                this.state.messages.map(msg =&amp;gt; (
                  &amp;lt;li className='list-group-item' key={uuid()}&amp;gt;
                    &amp;lt;strong&amp;gt;{msg.sender.name}&amp;lt;/strong&amp;gt;
                    &amp;lt;p&amp;gt;{msg.text}&amp;lt;/p&amp;gt;
                  &amp;lt;/li&amp;gt;
                ))
              ) : (
                &amp;lt;div className='text-center mt-5 pt-5'&amp;gt;
                  &amp;lt;p className='lead text-center'&amp;gt;Fetching Messages&amp;lt;/p&amp;gt;
                &amp;lt;/div&amp;gt;
              )}
            &amp;lt;/ul&amp;gt;
          &amp;lt;/Container&amp;gt;
        &amp;lt;/Col&amp;gt;
      &amp;lt;/Row&amp;gt;
      &amp;lt;Navbar fixed='bottom'&amp;gt;
        &amp;lt;Container&amp;gt;
          &amp;lt;Form
            inline
            className='w-100 d-flex justify-content-between align-items-center'
            onSubmit={this.sendMessage}
          &amp;gt;
            &amp;lt;Form.Group style={{ flex: 1 }}&amp;gt;
              &amp;lt;Form.Control
                value={this.state.messageText}
                style={{ width: '100%' }}
                required
                type='text'
                placeholder='Type Message here...'
                onChange={this.handleChange}
              /&amp;gt;
            &amp;lt;/Form.Group&amp;gt;
            &amp;lt;Button variant='primary' type='submit'&amp;gt;
              Send
            &amp;lt;/Button&amp;gt;
          &amp;lt;/Form&amp;gt;
        &amp;lt;/Container&amp;gt;
      &amp;lt;/Navbar&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this render method, you have a &lt;code&gt;&amp;lt;Redirect /&amp;gt;&lt;/code&gt; component that redirects to the home component when there is no logged in user. You also have a message box that displays all messages sent and received in the group, and finally, you have a form to handle the sending of messages.&lt;/p&gt;

&lt;p&gt;There are some methods that are called here, don’t worry yet, you will soon define these methods. Now that you have built the UI for the chat component, the next thing is to show messages to the user. You will do this as soon as the component is mounted. In your &lt;code&gt;Chat.js&lt;/code&gt; file, add this method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;componentDidMount() {
  this.setState({ user: this.props.location.user });
  this.getUser();
  this.receiveMessages();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a callback function provided by React. In this method, you will fetch the user details and listen for new messages in the group. Now, add the &lt;code&gt;getUser()&lt;/code&gt; method 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;getUser = () =&amp;gt; {
  CometChat.getLoggedinUser().then(
    user =&amp;gt; {
      this.joinGroup();
    },
    error =&amp;gt; {
      const authToken = localStorage.getItem('cometchat:authToken');
      if (authToken !== null) {
        this.setState({ authToken }, () =&amp;gt; {
          this.reAuthenticateUserWithToken(this.state.authToken);
        });
      } else {
        this.setState({ redirect: true });
      }
    }
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this method, you get the logged in user and join the group using the &lt;code&gt;joinGroup()&lt;/code&gt; method . If an error occurs in getting the user, the &lt;code&gt;authToken&lt;/code&gt; stored in &lt;code&gt;localStorage&lt;/code&gt; serves as a fallback option for re-authenticating the user. The &lt;code&gt;joinGroup()&lt;/code&gt; method is not defined yet. Create the method inside your &lt;code&gt;Chat.js&lt;/code&gt; to look 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;joinGroup = () =&amp;gt; {
  const GUID = this.state.receiverID;
  const password = '';
  const groupType = CometChat.GROUP_TYPE.PUBLIC;
  CometChat.joinGroup(GUID, groupType, password).then(
    group =&amp;gt; {},
    error =&amp;gt; {
      if (error.code === 'ERR_ALREADY_JOINED') {
        this.reAuthenticateUserWithToken();
      }
    }
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here in this method, the user is subscribed to this group and they can now send and receive messages from this group. Also, the &lt;code&gt;fetchMessages()&lt;/code&gt; method is called to fetch previous messages when the user successfully joins the group. Add the &lt;code&gt;fetchMessages()&lt;/code&gt; method too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetchMessages = () =&amp;gt; {
  const GUID = this.state.receiverID;
  const limit = 30;
  const messagesRequest = new CometChat.MessagesRequestBuilder()
    .setGUID(GUID)
    .setLimit(limit)
    .build();
  messagesRequest.fetchPrevious().then(
    messages =&amp;gt; {
      const textMessages = messages.filter(msg =&amp;gt; msg.type === 'text');
      this.setState({ messages: [...textMessages] });
      this.scrollToBottom();
    },
    error =&amp;gt; {
      console.log('Message fetching failed with error:', error);
    }
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fetches the previous messages sent to the group. To enable users to see the newest messages, the &lt;code&gt;scrollToBottom()&lt;/code&gt; method is called. Add a &lt;code&gt;scrollToBottom()&lt;/code&gt; method to your class 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;scrollToBottom = () =&amp;gt; {
  const page = document.querySelector('.page');
  page.scrollTop = page.scrollHeight;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you can fetch previous messages, it’s time to enable users to send new messages too. To achieve this, you first need to create a &lt;code&gt;handleChange()&lt;/code&gt; method to update the state whenever the user types a new message. Add this method to your class component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;handleChange = e =&amp;gt; {
  this.setState({ messageText: e.target.value });
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thereafter, you add the &lt;code&gt;sendMessage&lt;/code&gt; method 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;sendMessage = e =&amp;gt; {
  e.preventDefault();
  const { receiverID, messageText, messageType, receiverType } = this.state;
  const textMessage = new CometChat.TextMessage(
    receiverID,
    messageText,
    messageType,
    receiverType
  );
  CometChat.sendMessage(textMessage).then(
    message =&amp;gt; {
      this.setState({ messageText: '' });
      const oldMessages = [...this.state.messages];
      const filtered = oldMessages.filter(msg =&amp;gt; msg.id !== message);
      this.setState({ messages: [...filtered, message] });
      this.scrollToBottom();
    },
    error =&amp;gt; {
      console.log('Message sending failed with error:', error);
    }
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method is called when the form in the &lt;code&gt;render()&lt;/code&gt; method is submitted. After the &lt;code&gt;sendMessage&lt;/code&gt; method of &lt;code&gt;ComeChat&lt;/code&gt; is called, the input field is cleared and new messages will be added to the messages array. New messages are also filtered in case of duplicates, and lastly, the &lt;code&gt;scrollToBottom()&lt;/code&gt; is called to give focus to new messages.&lt;/p&gt;

&lt;p&gt;The second method you called in the &lt;code&gt;componentDidMount&lt;/code&gt; method was &lt;code&gt;receiveMessages&lt;/code&gt;. Now, create the method inside your class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;receiveMessages = () =&amp;gt; {
  const listenerID = 'supergroup';
  CometChat.addMessageListener(
    listenerID,
    new CometChat.MessageListener({
      onTextMessageReceived: textMessage =&amp;gt; {
        const oldMessages = this.state.messages;
        oldMessages.push(textMessage);
        this.setState(
          {
            messages: [...oldMessages]
          },
          () =&amp;gt; this.scrollToBottom()
        );
      }
    })
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since it’s only text messages that you are concerned with, only the &lt;code&gt;onTextMessageReceived&lt;/code&gt; handler is used. On receiving new messages, the messages array is updated to show messages in real time.&lt;/p&gt;

&lt;p&gt;After that, you have to add a logout method to enable authenticated users to log out of the application. Add a logout method in the &lt;code&gt;Chat.js&lt;/code&gt; file 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;logout = () =&amp;gt; {
  CometChat.logout().then(() =&amp;gt; {
    localStorage.removeItem('cometchat:authToken');
    this.setState({ redirect: true });
  });
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a user clicks the logout button, you call the &lt;code&gt;logout()&lt;/code&gt; method, then, you reset the &lt;code&gt;localStorage&lt;/code&gt; and redirect the user to the Home page.&lt;/p&gt;

&lt;p&gt;Now that you have defined your components, you would update the &lt;code&gt;App.js&lt;/code&gt; file with the routes. Open your &lt;code&gt;App.js&lt;/code&gt; file and replace it with this:&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 { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Home from "./components/Home";
import Chat from "./components/Chat";
import Signup from "./components/Signup";
function App() {
  return (
    &amp;lt;Router&amp;gt;
      &amp;lt;Switch&amp;gt;
        &amp;lt;Route exact path="/" component={Home} /&amp;gt;
        &amp;lt;Route exact path="/signup" component={Signup} /&amp;gt;

      &amp;lt;/Switch&amp;gt;
    &amp;lt;/Router&amp;gt;
  );
}
export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you have successfully finished building your app. Run this command in the root directory of your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should have something similar to what was shown to you earlier.&lt;/p&gt;

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

&lt;p&gt;In this article, you learned how to build an anonymous chat using React, React Bootstrap and CometChat Pro. You can now comfortably integrate group chats into React apps. As far as CometChat Pro SDK goes, there are a ton of other features not covered in this article. Feel free to expand on this by diving deeper into the &lt;a href="https://prodocs.cometchat.com/docs/js-quick-start" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>cometchat</category>
    </item>
    <item>
      <title>Building with Flutter!</title>
      <dc:creator>Idorenyin Obong</dc:creator>
      <pubDate>Fri, 30 Mar 2018 14:11:49 +0000</pubDate>
      <link>https://forem.com/kingidee/building-with-flutter-59fc</link>
      <guid>https://forem.com/kingidee/building-with-flutter-59fc</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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Firchmco8kj5bakprezjh.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Firchmco8kj5bakprezjh.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flutter is a mobile cross-development platform still in its beta. Flutter most importantly gives us the native feel with a better performance as compared to its competitors. In this article, we will learn why Flutter is a good option for development and we will also create a simple app with it. You can find the GitHub repository for this sample &lt;a href="https://github.com/KingIdee/rickandmorty" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Many companies prefer to use “one stone to kill two birds.” Therefore opting for cross-platform development is a natural decision. Over the years, cross-development platforms have been introduced with the aim of achieving this feat. The reasons for this choice include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A quick prototype of a product.&lt;/li&gt;
&lt;li&gt;A wider range of users with lesser investments etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This option and decision obviously saves time and cost - two very important entities. &lt;/p&gt;

&lt;p&gt;The earlier released cross-development platforms such as PhoneGap, Cordova, Ionic among others mostly used JavaScript and as such, they came with some bottlenecks. This was due to the extra effort required for the JavaScript code to communicate with the native code. According to a senior software engineer at Google &lt;a href="https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514" rel="noopener noreferrer"&gt;here&lt;/a&gt;, these platforms needed a bridge to communicate with the native code thereby causing performance lapses in the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Flutter?
&lt;/h2&gt;

&lt;p&gt;Flutter is an open source mobile app SDK from Google used in developing Android and IOS apps. The aim of Flutter is to produce the native feel which is rare in its competitors while utilizing a single codebase. Flutter considers differences in alignments, scrolling behaviors, typography, icons, and more when rendering your app to its platform. Flutter has been in development as far back as 2015 - the first commit which contained the &lt;code&gt;AUTHORS&lt;/code&gt;, &lt;code&gt;LICENSE&lt;/code&gt; and &lt;code&gt;README.md&lt;/code&gt; files was made on 30th October, 2015.&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%2Fd2mxuefqeaa7sj.cloudfront.net%2Fs_61C7FBFD62C749D5311201EA6851ED7FF4734742900C98F39AA870334E2A8E29_1522185117690_fio3.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%2Fd2mxuefqeaa7sj.cloudfront.net%2Fs_61C7FBFD62C749D5311201EA6851ED7FF4734742900C98F39AA870334E2A8E29_1522185117690_fio3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, &lt;a href="https://www.youtube.com/watch?v=w2TcYP8qiRI" rel="noopener noreferrer"&gt;it was officially announced and presented to the world during the Google IO in 2017&lt;/a&gt;. And so, the question arises - &lt;em&gt;is Flutter any different from other cross-development platforms ?&lt;/em&gt;&lt;br&gt;
Yes! Definitely! And here are some of its features you should take note of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Better performance: One of the major reasons for the success and better performance of Flutter is the &lt;a href="https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf" rel="noopener noreferrer"&gt;choice of language- Dart&lt;/a&gt;. Dart is compiled “ahead of time” (AOT) into native code and so it is easier for Flutter to communicate to the platform rather than use a bridge like the case of the JavaScript frameworks. Similarly, the way Flutter works, it needs to create and destroy a large number of short-lived objects very fast. Dart’s garbage collection is very well suited for such a use case.&lt;/li&gt;
&lt;li&gt;Hot reload: This is a feature that helps you update your code on the fly without restarting the entire app. &lt;/li&gt;
&lt;li&gt;A new approach to Widgets: In Flutter, everything is a widget. From layouts to alignments to padding, etc.&lt;/li&gt;
&lt;li&gt;Flutter is reactive: Flutter is inspired by React Native and just like React Native, it provides reactive-style views.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Before we get started with coding. We need to setup Flutter on our system. You can do that following the steps here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Clone the GitHub repository.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone -b beta https://github.com/flutter/flutter.git&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add Flutter to your PATH. &lt;a href="https://flutter.io/get-started/install/" rel="noopener noreferrer"&gt;Follow these instructions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run this command in your terminal:&lt;br&gt;
&lt;br&gt;
&lt;code&gt;flutter doctor&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is so you will be alerted of any other necessary dependency needed to complete the setup. You can always fall back to the &lt;a href="https://flutter.io/get-started/install/" rel="noopener noreferrer"&gt;Flutter docs&lt;/a&gt; if you encounter any hitch while setting this up.&lt;/p&gt;

&lt;p&gt;Before going ahead, you should also have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An IDE(Integrated Development Environment). You can use &lt;a href="https://www.jetbrains.com/idea/download" rel="noopener noreferrer"&gt;Intellij IDEA&lt;/a&gt;, &lt;a href="https://developer.android.com/studio/archive.html" rel="noopener noreferrer"&gt;Android Studio&lt;/a&gt; or &lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;. You can learn how to configure them &lt;a href="https://flutter.io/get-started/editor" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;An introductory knowledge of OOP(Object Oriented Programming).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What we will Build
&lt;/h2&gt;

&lt;p&gt;In this demo, we will make use of the Rick and Morty API to build a simple Flutter app  that will do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetch all the characters from the API and parse the &lt;code&gt;JSON&lt;/code&gt; response.&lt;/li&gt;
&lt;li&gt;Setup a list view to display the response which includes the image and the name of a character.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building our app
&lt;/h2&gt;

&lt;p&gt;Open your IDE and create a new Flutter application. We will name it &lt;code&gt;rick_and_morty&lt;/code&gt;. This conforms to the naming conventions of Flutter projects (i.e small letters with underscores only). The project will have this file structure.&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%2Fd2mxuefqeaa7sj.cloudfront.net%2Fs_61C7FBFD62C749D5311201EA6851ED7FF4734742900C98F39AA870334E2A8E29_1522184970451_fio2.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%2Fd2mxuefqeaa7sj.cloudfront.net%2Fs_61C7FBFD62C749D5311201EA6851ED7FF4734742900C98F39AA870334E2A8E29_1522184970451_fio2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only functionality we will implement here that will require an external package is loading of images. So, go ahead, open your &lt;code&gt;pubspec.yaml&lt;/code&gt; file and add the &lt;code&gt;cached_network_image&lt;/code&gt; package:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.0
  cached_network_image: "^0.3.0"
  # Other dependencies if you so which!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Click the ‘Packages get’ button at the top right corner so that the package will be fetched. The rest of our modifications for this app will be done in the &lt;code&gt;main.dart&lt;/code&gt;  file. The default app comes with a whole lot of boilerplate codes that we do not need for this demo. You should clear them out and have just this in the file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() =&amp;gt; runApp(new MyApp());
var httpClient = new HttpClient();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Rick and Morty',
      home: new RickAndMorty(),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here in this snippet, we have a class which extends a stateless widget. And in the overridden &lt;code&gt;build&lt;/code&gt; method, we return a MaterialApp with some modified properties. The title property is changed to ‘Rick and Morty’ - this will reflect as the text on our app bar. We also modified the home property to return yet another widget which we will implement later on. The class is called in the &lt;code&gt;main&lt;/code&gt; method and this is the widget shown when we run our app. We also created an instance of &lt;code&gt;HttpClient&lt;/code&gt; which we will use for our network calls.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;RickAndMorty&lt;/code&gt; widget which is returned through the home property is going to be a stateful widget. Flutter has two types of widgets, stateless and stateful widgets. Stateless widgets are widgets whose properties cannot change - that is the equivalent of constants while stateful widgets are widgets whose properties can change. Let us now set up our &lt;code&gt;RickAndMorty&lt;/code&gt; widget. Paste this snippet still in your &lt;code&gt;main.dart&lt;/code&gt; file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class RickAndMorty extends StatefulWidget {
  @override
  createState() =&amp;gt; new RickAndMortyState();
}

class RickAndMortyState extends State&amp;lt;RickAndMorty&amp;gt; {
  var modelList = &amp;lt;Model&amp;gt;[];
  final _customFont = const TextStyle(fontSize: 18.0);

  @override
  void initState() {
    super.initState();
    _getRickAndMortyCharacters();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold (
      appBar: new AppBar(
        title: new Text('Rick and Morty'),
      ),
      body: _buildListView()
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Variables and methods prefixed with _ are private to the class.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To create a stateful widget, we create a class which extends &lt;code&gt;StatefulWidget&lt;/code&gt;, we then override the &lt;code&gt;createState&lt;/code&gt; method to return a new class which extends &lt;code&gt;State&amp;lt;RickAndMorty&amp;gt;&lt;/code&gt;. We did exactly that in the snippet above. According to the docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to visually present stateful data in a widget, you should encapsulate this data in a &lt;code&gt;State&lt;/code&gt; object. You can then associate your &lt;code&gt;State&lt;/code&gt; object with a widget that extends the &lt;code&gt;StatefulWidget&lt;/code&gt; class.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the &lt;code&gt;RickAndMortyState&lt;/code&gt; class, we created a new list to hold custom data. This data is contained in the &lt;code&gt;Model&lt;/code&gt; class stored in the &lt;code&gt;model.dart&lt;/code&gt; file. Create a new file &lt;code&gt;model.dart&lt;/code&gt; and set it up like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Model{
  String name;
  String imageUrl;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The class contains two strings to hold the name of the character and the image URL.&lt;/p&gt;

&lt;p&gt;Still in the &lt;code&gt;RickAndMortyState&lt;/code&gt; class, we overridded the &lt;code&gt;initState&lt;/code&gt; method and made our network call here by calling the &lt;code&gt;_getRickAndMortyCharacters&lt;/code&gt; function. Setup the function within the class like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_getRickAndMortyCharacters() async {
  var url = 'https://rickandmortyapi.com/api/character';

  Logger.root.level = Level.ALL;
  Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.level.name}: ${rec.time}: ${rec.message}');
  });
  var _LOG = new Logger("R&amp;amp;M");

  var httpClient = new HttpClient();

  List&amp;lt;Model&amp;gt; result = &amp;lt;Model&amp;gt;[];
  try {
    var request = await httpClient.getUrl(Uri.parse(url));
    var response = await request.close();
    if (response.statusCode == HttpStatus.OK) {
      var json = await response.transform(UTF8.decoder).join();
      var data = JSON.decode(json);

      for (var k in data['results']) {
        var model = new Model();
        model.name = k['name'].toString();
        model.imageUrl = k['image'].toString();
        result.add(model);
      }

      httpClient.close();
    } else {
      _LOG.severe(response.statusCode);
      _LOG.severe(response);
    }
  } catch (exception) {
    _LOG.severe(exception);
  }


  if (!mounted) return;

  setState(() {
    modelList = result;
  });

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

&lt;/div&gt;

&lt;p&gt;This function performs our network call and assigns the result to our &lt;code&gt;modelList&lt;/code&gt;. The &lt;code&gt;setState&lt;/code&gt; function is an internal function used to inform the framework of a change in the object.&lt;/p&gt;

&lt;p&gt;Finally, in the &lt;code&gt;build&lt;/code&gt; method of the &lt;code&gt;RickAndMortyState&lt;/code&gt; class, we return a widget where we still specify the title and body. Here, the body is another method - &lt;code&gt;_buildListView&lt;/code&gt; which returns a widget and setups our list-view. Create a function within the class and set up the method like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Widget _buildListView(){
  return new ListView.builder(
      padding: const EdgeInsets.all(16.0),
      itemCount: modelList.length,
      itemBuilder: (context, i) {
        // Add a one-pixel-high divider widget before each row in theListView.
        if (i.isOdd) return new Divider();

        return _buildRow(modelList[i]);
      }
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the &lt;code&gt;ListView.builder&lt;/code&gt; , we added padding to the view, we set our length to be the size of the list, we returned a divider line to add some swagger to our list, and we returned another widget by calling the &lt;code&gt;_buildRow&lt;/code&gt; function. The &lt;code&gt;_buildRow&lt;/code&gt; function describes how a single item in the list will look like. Create the function within the class and set it up like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Widget _buildRow(Model model) {
  return new ListTile(

    title: new Text(
      model.name,
      style: _customFont,
    ),

    leading: new CachedNetworkImage(
      imageUrl: model.imageUrl,
      placeholder: new CircularProgressIndicator(),
      errorWidget: new Icon(Icons.error),
    )

  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The list item will have an image and a text. The image is added using the leading property. This property is configured to be the first item horizontally on the list and it precedes the title property which we used for the character’s title. We used the &lt;code&gt;CachedNetworkImage&lt;/code&gt; package to load the image. When we run our app, we should see something like this:&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%2Fd2mxuefqeaa7sj.cloudfront.net%2Fs_61C7FBFD62C749D5311201EA6851ED7FF4734742900C98F39AA870334E2A8E29_1522179996250_fio1.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%2Fd2mxuefqeaa7sj.cloudfront.net%2Fs_61C7FBFD62C749D5311201EA6851ED7FF4734742900C98F39AA870334E2A8E29_1522179996250_fio1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Some more awesome resources!
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Solido/awesome-flutter#introduction" rel="noopener noreferrer"&gt;https://github.com/Solido/awesome-flutter#introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codelabs.developers.google.com/codelabs/flutter" rel="noopener noreferrer"&gt;https://codelabs.developers.google.com/codelabs/flutter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@matthew.smith_66715/why-we-chose-flutter-and-how-its-changed-our-company-for-the-better-271ddd25da60" rel="noopener noreferrer"&gt;https://medium.com/@matthew.smith_66715/why-we-chose-flutter-and-how-its-changed-our-company-for-the-better-271ddd25da60&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hackernoon.com/why-native-app-developers-should-take-a-serious-look-at-flutter-e97361a1c073" rel="noopener noreferrer"&gt;https://hackernoon.com/why-native-app-developers-should-take-a-serious-look-at-flutter-e97361a1c073&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In this article, we have been introduced to yet another cross-development platform - Flutter. We were able to evaluate reasons why Flutter is a good choice for developing mobile apps as against earlier released platforms. Some of the reasons we were able to unravel include better performance, its reactive nature, its material design implementation, etc.&lt;/p&gt;

&lt;p&gt;We were equally able to build a simple demo app where we consumed an API to show off some awesome qualities of Flutter. Flutter has already produced some success stories. Feel free to play around with the &lt;a href="https://github.com/KingIdee/rickandmorty" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;. I can’t wait to see the next great thing you will build with this platform. Holla if you get stuck! &lt;/p&gt;

</description>
      <category>android</category>
      <category>flutter</category>
    </item>
  </channel>
</rss>
