<?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: Shalom SK</title>
    <description>The latest articles on DEV Community by Shalom SK (@shalom).</description>
    <link>https://dev.to/shalom</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%2F652408%2F7cb3e0f0-8cc4-499e-9d93-67a4560fe65a.JPG</url>
      <title>DEV Community: Shalom SK</title>
      <link>https://dev.to/shalom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shalom"/>
    <language>en</language>
    <item>
      <title>Local State In React Components</title>
      <dc:creator>Shalom SK</dc:creator>
      <pubDate>Sun, 20 Jun 2021 04:58:06 +0000</pubDate>
      <link>https://dev.to/shalom/local-state-in-react-components-19gl</link>
      <guid>https://dev.to/shalom/local-state-in-react-components-19gl</guid>
      <description>&lt;p&gt;For my final project, I worked on a React app that allows users to sell to and buy items from one another. In order to display existing items to the user, I created an ‘ItemsList’ component, using useEffect hook to dispatch my “getItems” action that fetched all existing items from my Rails backend API as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
      props.getItems();
  },[]);
export const getItems = () =&amp;gt; {
    return (dispatch) =&amp;gt;{
        fetch('http://localhost:3001/api/v1/items')
            .then((res) =&amp;gt; res.json())
            .then((items) =&amp;gt; 
                dispatch({
                    type: 'FETCH_ITEMS',
                    payload: items
                })
        )
    }   
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the functionalities I tried to add was an option for users to ‘UpVote’ an item. Initally, I tried to accomplish this by creating a local state (using a useState hook) that keeps track of the number of times an item has been updated. I also wrote a “handleVote” function that would increment the count of UpVotes when the user clicks on it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [count, setCount] = useState(0);

const handleVote = () =&amp;gt;{
    setCount(
      count +1 
 )

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

&lt;/div&gt;



&lt;p&gt;I added a button on the page, so that each item would have the UpVote option:&lt;/p&gt;

&lt;p&gt;Item List View&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Although this seemed like a quick, simple way to add this functionality, I ran into a problem. Everytime a user clicks on the upvote button, the upvote count of ALL items were incremented! Definitely NOT the user experience I was looking for. But it made sense why. I had set the state for the entire ItemsList component. So when I incremented the upvote count in the local state by clicking on “Upvote” on any item, that state was shared by all the items.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;What I really needed was for each item on the page to have its own upvote count. What I needed was for each item to be its own component and keep track of its own upvote count. This was accomplished by creating an Item component and placing it within my ItemsList component. (Alternatively, it could also be put in its own component file and imported into my ItemList component).&lt;/p&gt;

&lt;p&gt;The Item component could then be created as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Item = ({user, id, image_url, name, price, userId, handleDelete}) =&amp;gt; {
  const [count, setCount] = useState(0);

  const handleVote = () =&amp;gt;{
    setCount(
      count +1 
    )
  }

  return &amp;lt;div className = "col-sm-3"&amp;gt;

    {user ? 
    &amp;lt;div className="item-box"&amp;gt;
        &amp;lt;Link to={`/items/${id}`}&amp;gt;&amp;lt;img src={image_url} className="item-img"&amp;gt;&amp;lt;/img &amp;gt;&amp;lt;/Link&amp;gt;
       ** &amp;lt;button onClick={handleVote}&amp;gt;Upvote&amp;lt;/button&amp;gt; {count}**
        &amp;lt;p&amp;gt;{name}&amp;lt;/p&amp;gt;
        &amp;lt;b&amp;gt;${price}&amp;lt;/b&amp;gt;
    &amp;lt;/div&amp;gt;
    : null}  
  &amp;lt;/div&amp;gt;  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would allow me to iterate through Items array and for each item, render an Item component, passing into it the properties it would need (the item’s attributes, the userId, and handleDelete method) from the ItemsList parent component:&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;div className= "row"&amp;gt;
    {props.items.map(item =&amp;gt; 
             &amp;lt;Item {...item} userId={props.user.id} handleDelete={handleDelete} key={`item${item.id}`}/&amp;gt;
        )}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this accomplishes is that now each item is its own component and could keep track of its own local state (i.e. upvote count). The handleVote method will then update the local state by incrementing the vote count just for that item. Thus, when a user click on ‘Upvote’ for one item, only that item’s state would be updated. Success!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://drive.google.com/file/d/1qJpFhSIPecAaqdVt631QCd3PLgn5637y/view?usp=sharing"&gt;Link&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My Final (React) Project at Flatiron School</title>
      <dc:creator>Shalom SK</dc:creator>
      <pubDate>Sun, 20 Jun 2021 04:55:55 +0000</pubDate>
      <link>https://dev.to/shalom/my-final-react-project-at-flatiron-school-2pom</link>
      <guid>https://dev.to/shalom/my-final-react-project-at-flatiron-school-2pom</guid>
      <description>&lt;p&gt;For my final project, I worked on a React App with a Rails API backend. Initially, the project started out with a simple inventory system for a small store but as I worked on the project, I wanted to expand on the idea as I thought it would be a great way to learn more about react. So, I decided to expand it to be a simple app where users can buy and sell items, making sure the project lined up with the expectations below:&lt;/p&gt;

&lt;p&gt;Use the create-react-app generator to start your project.&lt;br&gt;
Your app should have one HTML page to render your react-redux application&lt;br&gt;
There should be 5 stateless components&lt;br&gt;
There should be 3 routes&lt;br&gt;
The Application must make use of react-router and proper RESTful routing&lt;br&gt;
Use Redux middleware to respond to and modify state change&lt;br&gt;
Make use of async actions and redux-thunk middleware to send data to and receive data from a server&lt;br&gt;
Your Rails API should handle the data persistence with a database. You should be using fetch() within your actions to GET and POST data from your API - do not use jQuery methods.&lt;br&gt;
Your client-side application should handle the display of data with minimal data manipulation&lt;br&gt;
Your application should have some minimal styling&lt;/p&gt;
&lt;h2&gt;
  
  
  Backend
&lt;/h2&gt;

&lt;p&gt;To set up the backend, I set up the following associations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Category &amp;lt; ApplicationRecord
    has_many :items
    validates :name, presence: true
end

class Item &amp;lt; ApplicationRecord
    belongs_to :category
    belongs_to :user
    validates :name, presence: true
end

class User &amp;lt; ApplicationRecord
    has_many :items
    has_secure_password
    validates :username, presence: true
    validates :email, uniqueness: true
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I set up the files to include respective controllers and serializers as below:&lt;/p&gt;

&lt;p&gt;To set up the database, I ran 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;rake db:migrate
rake db: seed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Frontend
&lt;/h2&gt;

&lt;p&gt;To create the react app, I ran create-react-app, following the instructions at this repo&lt;/p&gt;

&lt;p&gt;I started out with setting up redux to manage the app’s state, such as user, item, and category states. In the redux directory, I set up actions and reducers. Whereas the actions are responsible for running actions such as fetch to get and post data from the backend, reducers determine the changes made to the app’s states. For my particular project, for instance, my item actions and reducer 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;ItemActions.js

export const getItems = () =&amp;gt; {
    return (dispatch) =&amp;gt;{
        fetch('http://localhost:3001/api/v1/items')
            .then((res) =&amp;gt; res.json())
            .then((items) =&amp;gt; 
                dispatch({
                    type: 'FETCH_ITEMS',
                    payload: items
                })
        )
    }   
}

export const createItem = (newItemData, history) =&amp;gt;{    
    return(dispatch) =&amp;gt; {        
        fetch('http://localhost:3001/api/v1/items', {
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            method: 'POST',
            body: JSON.stringify({item: newItemData})
        })
        .then((response) =&amp;gt; {
            if(response.ok){
                return response.json();
            } else {
                throw new Error(response.statusText);                
            }
        })
        .then((item) =&amp;gt; 
            (dispatch({type: 'CREATE_ITEM', payload: item}),
            history.push('/items'))
        )
        .catch((err) =&amp;gt; 
            dispatch({
                type: 'ERROR', 
                payload: "Error creating item. Please enter a name"}))
    }
}

export const deleteItem = (itemId, history) =&amp;gt; {
    return(dispatch) =&amp;gt; {        
        fetch(`http://localhost:3001/api/v1/items/${itemId}`, {
            method: 'DELETE'
        })
        .then((res) =&amp;gt; res.json())
        .then((item) =&amp;gt; 
            (dispatch({type: 'DELETE_ITEM', payload: item}),
            history.push('/items'))
        )
    }
}
ItemReducer.js

export default (state = [], action) =&amp;gt; {
    switch(action.type){
        case 'FETCH_ITEMS':
            return action.payload
        case 'CREATE_ITEM':
            {
                alert(action.payload.message)
                return [...state, action.payload]
            }           
        case 'DELETE_ITEM':                   
            {alert(action.payload.message)
            return [...state, action.payload]}
        case 'ERROR':
            {
            alert(action.payload)
            return  [...state, action.payload]
            }
        default:
            return state;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Redux setup, I could map the states to props and pass those props on to different components. Although this was only the beginning, I felt like it was a good place to start before.&lt;/p&gt;

&lt;p&gt;Overall, it was a fun project to work on and look forward to writing a more detailed blog about the experience.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My JS Project</title>
      <dc:creator>Shalom SK</dc:creator>
      <pubDate>Sun, 20 Jun 2021 04:52:29 +0000</pubDate>
      <link>https://dev.to/shalom/my-js-project-423m</link>
      <guid>https://dev.to/shalom/my-js-project-423m</guid>
      <description>&lt;p&gt;For my Javascript Project, I initially worked on an app that allows users to buy and sell books from one another at discount prices. I, being a student, know how expensive books can be, particularly those you use for just a semester! So, that was my initial inspiration for the project. After building the MVP for this project, however, I realized that for the app to be used as intended, a user model was crucial. Given the time constraint to finish the project, I decided not to work on the additional user model and authentications as my intention was to build a simple app with relatively simple functionalities. So, I did what I would never advise anyone to do and switched project ideas!&lt;/p&gt;

&lt;p&gt;I decided to create an app called My Devotional, which is an app that allows users to create and save their daily Bible devotions or reflections on scripture that they read that day. As it uses a very similar structure and premise as my initial idea, making the switch was not difficult. I set up the project into two repositories: a backend repo (using rails) and a frontend (using html, css, and javascript)&lt;/p&gt;

&lt;p&gt;I set up my rails backend api by first running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails new &amp;lt;my_app_name&amp;gt; --database=postgresql --api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this app, I only had two models: a category model and a devotion model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Category &amp;lt; ApplicationRecord
    has_many :devotions, dependent: :destroy
end

class Devotion &amp;lt; ApplicationRecord
   belongs_to :category 
   validates :title, presence: true
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each model had the attributes as shown in the db schema below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create_table "categories", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "devotions", force: :cascade do |t|
    t.string "title"
    t.string "date"
    t.string "verse"
    t.string "content"
    t.string "image_url"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.bigint "category_id", null: false
    t.index ["category_id"], name: "index_devotions_on_category_id"
  end

    add_foreign_key "devotions", "categories"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I set up the routes as follows, using namespacing to organize the controllers and allow for version control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :devotions
      resources :categories
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the backend was complete, I linked to to the front end by setting the fetch endpoint to “&lt;a href="http://localhost:3000/api/v1/devotions%E2%80%9D"&gt;http://localhost:3000/api/v1/devotions”&lt;/a&gt; so that the front end can communicate with the backend.&lt;/p&gt;

&lt;p&gt;Overall, although I stuck to just the MVP for this project, I felt like I learned a lot. I look forward to expanding on it further in the future&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My Rails Project</title>
      <dc:creator>Shalom SK</dc:creator>
      <pubDate>Sun, 20 Jun 2021 04:49:33 +0000</pubDate>
      <link>https://dev.to/shalom/my-rails-project-52k</link>
      <guid>https://dev.to/shalom/my-rails-project-52k</guid>
      <description>&lt;p&gt;For my Rails project, I decided to work on a recipe managment app with a bit of a social aspect to it. I created an app where users can create and save some of their favorite recipes and share them with others. Users can also browse through other users’ profiles and recipes. They can add other chefs to their friends and gain inspiration from others. This was my favorite project so far because I had a great time exploring different aspects of the project such as adding recipes to favorites, making friend, using various useful gems….etc.&lt;/p&gt;

&lt;p&gt;These are the associations I set up for my two main models:&lt;/p&gt;

&lt;p&gt;User:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  has_many :recipes, dependent: :destroy
  has_many :comments, :dependent =&amp;gt; :destroy
  has_many :commented_recipes, through: :comments, source: :recipe
  has_many :friendships, :dependent =&amp;gt; :destroy
  has_many :friends, through: :friendships
  has_many :user_recipes, :dependent =&amp;gt; :destroy
  has_many :added_recipes, through: :user_recipes, source: :recipe 
  has_one_attached :avatar

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  devise :omniauthable, :omniauth_providers =&amp;gt; [:facebook]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recipe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; belongs_to :user
  belongs_to :category
  has_many :comments, :dependent =&amp;gt; :destroy
  has_many :commented_users, through: :comments, source: :user
  has_many :user_recipes, :dependent =&amp;gt; :destroy
  has_many :added_users, through: :user_recipes, source: :user

  has_many :ingredients, dependent: :destroy
  accepts_nested_attributes_for :ingredients, reject_if: :all_blank, allow_destroy: true

  has_many :steps, dependent: :destroy
  accepts_nested_attributes_for :steps, allow_destroy: true

  validates :name, :ingredients, :steps, :category_name, presence: true

  scope :most_commented, -&amp;gt; {left_joins(:comments).group('recipes.id').order('count(recipes.id) desc')}

  has_many_attached :images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also had a few other models, namely:&lt;/p&gt;

&lt;p&gt;Comment&lt;br&gt;
Categories&lt;br&gt;
Ingredient&lt;br&gt;
Step&lt;br&gt;
Friendship&lt;br&gt;
User_Recipe&lt;/p&gt;

&lt;p&gt;Some of the gems I found to be great were:&lt;/p&gt;

&lt;p&gt;Devise - The first model I set up was my user model. Devise worked great for setting up user authentication. After adding the devise gem to my gemfile and running bundle install, I used $ rails generate devise:install to install devise. Next, I generated the user model by using $ rails generate devise MODEL and ran rails db:migrate to set up the user table&lt;/p&gt;

&lt;p&gt;Facebook omniauth - I also integrated devise with facebook omniauth to give users the option to sign in using their facebook account. I found this resource to be quite useful in setting up the integration&lt;/p&gt;

&lt;p&gt;Bootstrap - Bootstrap was great for styling the page. In fact, I used boostrap to create styled views for the user instead of using devise:views&lt;/p&gt;

&lt;p&gt;Cocoon - I used gem cocoon to set up my nested forms. Ingredients and instructions were nested into the new recipe creation form.&lt;/p&gt;

&lt;p&gt;Font-awesome-rails - I also used this gem to add some icons for styling purposes.&lt;/p&gt;

&lt;p&gt;Overall, this was a fun project and I hope to expand on it in the future!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My Sinatra Project</title>
      <dc:creator>Shalom SK</dc:creator>
      <pubDate>Sun, 20 Jun 2021 04:46:36 +0000</pubDate>
      <link>https://dev.to/shalom/my-sinatra-project-doh</link>
      <guid>https://dev.to/shalom/my-sinatra-project-doh</guid>
      <description>&lt;p&gt;For my second project, I build a sinatra app called EduTasks, an app students can use to keep track of upcoming assignments, tasks, and reminders related to courses they are enrolled in. I chose this idea because I’m a student myself and with all classes being virtual at the moment, having a place to track all tasks, classes and due dates collectively would be beneficial to me and I assume to others as well.&lt;/p&gt;

&lt;p&gt;The app is a CRUD, MVC app using Sinatra and a simple Content Management System (CMS) using the tools we have learned in Module 2. It uses four basic types of functionality: Create, Read, Update, and Delete. It also uses a Model-View-Controller design pattern that divides the logic of the program into 3 section and each section of the code has its own distinct purpose. So, I set up the following:&lt;/p&gt;

&lt;p&gt;A user can create an account and can create courses&lt;br&gt;
A user can view his/her account information and can view courses they are enrolled in&lt;br&gt;
A user can edit his/her own account as well as courses they are enrolled in&lt;br&gt;
A user can delete his/her account as well as delete any courses&lt;br&gt;
To set this up, I set up the following association:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User &amp;lt; ActiveRecord::Base
    has_secure_password
    has_many :courses
end

class Course &amp;lt; ActiveRecord::Base
    belongs_to :user
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some gems and resources I found to be useful are:&lt;/p&gt;

&lt;p&gt;Corneal Gem - I used this gem to set up the scaffolding for the project.&lt;br&gt;
Sintra-Flash: - I used this gem to set alerts and notices to the user. (eg. incorrect password, account doesn’t exist, password too short, etc)&lt;br&gt;
Sass - I found this to be useful for styling css.&lt;br&gt;
Boostrap - I actually ended up not using this since I watching this tutorial and ended up using sass instead, but it’s a great resource for styling.&lt;br&gt;
bcrypt - this was useful for encrypting passwords&lt;br&gt;
Overall, this was a fun project and one I hope to expand with additional features!&lt;/p&gt;

&lt;p&gt;My walkthrough video of the current status of the project can be found here.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My Ruby CLI Project</title>
      <dc:creator>Shalom SK</dc:creator>
      <pubDate>Sun, 20 Jun 2021 04:43:47 +0000</pubDate>
      <link>https://dev.to/shalom/my-ruby-cli-project-40gl</link>
      <guid>https://dev.to/shalom/my-ruby-cli-project-40gl</guid>
      <description>&lt;p&gt;So, for my first Ruby CLI project, I decided to scrape a website for information about travel destinations around the world. It was fun and exciting but definitely challenging as well! The requirements for the project was to use an API or scraping to get data from a public website and to create a Command Line interface where users can interact with the data.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Getting started To start off, I had to come up with an idea, which should have been the easiest part! But it actually took me a while to find an idea I loved. Initially I started with the idea of scraping a website for information for career changers like myself! I was going to scrape data about 2020’s top tech careers and display information about those careers as per the user’s choice that would allow them to learn about tech career options, salaries, job descriptions, typical education entry requirement, etc. And I even found a website that displayed exactly the information I wanted to scrape. But I started with first coding the CLI before checking if the site was actually scrapable! Mistake #1. After working on it for days, and designing the interface with hard coded data, I was unable to scrape the site and so was on the search again for another site. After going through a few and even looking through API’s, I decided to switch tracks. I went with the next best thing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I love to travel so I decided to go with my World Traveler ruby gem, which scrapes Lonely Planet for top travel highlights in each destination. This time, I made sure to check if I can scrape the information I need first before starting to code! A great way to do so was using this&lt;/p&gt;

&lt;p&gt;Next, I watched a ton of videos! Avi’s walkthrough of the CLI project on learn.co as well the live build here were incredibly useful resources.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;What the Gem Does World Traveler gem displays a list of continents to users, asking them where they would like to explore. It then displays travel highlights for the user’s continent of choice. Next, it prompts users to choose a highlight they would like to learn more about and displays details for that highlight.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Planning! It helped to think though the relationships I wanted my classes to have and planning before starting to code. I knew I wanted a scraper class and a CLI class and I knew I wanted to scrape a list of continents and highlights of each continent. So, the continents would have a name, a URL and highlights. The highlights would also have a name, a URL, details and also belong to a continent. Once I had this idea in mind, I was ready to begin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bundler Before scraping, I had to set up the structure of the gem. First thing was to run bundle gem world_traveler to create the gem. This was really neat as it stubbed out the structure of the gem and gave me most of the files and directories i needed, including a Readme file. But to make this work, I had to first install bundler using gem install bundler&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coding my classes! I started with coding the scraper class. Unlike my initial tech career project, thankfully Lonely Planet did not put data in tables! After playing around with scraper to make sure I was getting the intended data, I was ready to start! Using Nokogiri I was able to successfully scrape continents and highlights.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next i worked on my Continents class, responsible for instantiating new instances of continents once scraped when the gem runs. I then worked on a Highlights class responsible for initializing new instances of highlights. But I didn’t want all the highlights being scraped at once like the continents. That would be a whole lot of data! I had to set up the class to access the scraper only when the user choses a highlight to look into. In order to do so, I had to link the classes by passing the return values of one method as an argument into another.&lt;/p&gt;

&lt;p&gt;I also had to set up the methods to check if user input was valid i.e. it was an integer and within the choices given.&lt;/p&gt;

&lt;p&gt;After a lot of work tweaking and re-tweaking the code, it was finally working! I was able to design the user interface that I wanted. I still had a day or two before the deadline, so I decided to have a bit more fun with it and add some art and color. I used a cool gem called colorize to get color. I also learned that you can add some ASCII art to make it add a bit of art. A google search for “ASCII art generator” helped me find one that worked for me.&lt;/p&gt;

&lt;p&gt;Lastly, I wanted to publish the gem so I spend some time reading up on how to do so and created an account on rubygems.org. I had to run gem command and use gem push to publish.&lt;/p&gt;

&lt;p&gt;In short, this project was not as easy as this blog makes it sound. But I definitely learned a lot about using GitHub, visual code, scraping, how gems work……the list goes on. I look forward to doing a follow up blog with more specific details!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
