<?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: Vivian</title>
    <description>The latest articles on DEV Community by Vivian (@vivianvu).</description>
    <link>https://dev.to/vivianvu</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%2F700692%2Fbed34b1b-367d-463c-b2b9-a13aa3a3e037.jpg</url>
      <title>DEV Community: Vivian</title>
      <link>https://dev.to/vivianvu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vivianvu"/>
    <language>en</language>
    <item>
      <title>OSD600 - The Final Release</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Thu, 09 Dec 2021 10:26:10 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-the-final-release-el3</link>
      <guid>https://dev.to/vivianvu/osd600-the-final-release-el3</guid>
      <description>&lt;h2&gt;
  
  
  1. Tasks
&lt;/h2&gt;

&lt;p&gt;When the modal form is created  and showed up in the web app, the next step in the plan is writing some unit tests to make sure that the form works appropriately. If there is no modification needed, I will be able to submit a PR for the maintainer to review.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Modification Process
&lt;/h2&gt;

&lt;p&gt;Because the project has currently used &lt;a href="https://jestjs.io/"&gt;Jest&lt;/a&gt; for testing, I also made use of this framework to write unit tests.&lt;/p&gt;

&lt;p&gt;I wrote two &lt;code&gt;describe&lt;/code&gt; blocks for the &lt;code&gt;Stories&lt;/code&gt; component and the &lt;code&gt;Modal Form&lt;/code&gt;, then in each &lt;code&gt;describe&lt;/code&gt; block, there are more detailed test cases.&lt;/p&gt;

&lt;p&gt;1) &lt;code&gt;describe&lt;/code&gt; block for &lt;code&gt;stories&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;should renders form without crashing&lt;/li&gt;
&lt;li&gt;should show the &lt;code&gt;Modal Form&lt;/code&gt; when &lt;code&gt;Create your story&lt;/code&gt; button is clicked
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; it("should show form modal when Create your story btn is clicked", () =&amp;gt; {
    render(&amp;lt;Stories initShow={true} /&amp;gt;);
    const modalForm = screen.getByRole(/modalForm/i);
    expect(modalForm).toBeInTheDocument();
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) &lt;code&gt;describe&lt;/code&gt; block for &lt;code&gt;form&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;input fields and selected fields should be rendered correctly
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; it("should render text fields correctly", () =&amp;gt; {
    render(&amp;lt;Stories initShow={true} /&amp;gt;);
    userEvent.type(screen.getByRole("title"), "My story");
    expect(screen.getByRole("title")).toHaveValue("My story");
    ...
  });

  it("should render selected fields correctly", () =&amp;gt; {
    render(&amp;lt;Stories initShow={true} /&amp;gt;);
    userEvent.selectOptions(screen.getByRole("country"), ["Afghanistan"]);
    expect(
      screen.getByRole("option", { name: "Afghanistan" }).selected
    ).toBeTruthy();
    ...
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Clear&lt;/code&gt; and &lt;code&gt;Close&lt;/code&gt; buttons perform appropriately
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it("clicks in clear button should clear all fields", () =&amp;gt; {
    render(&amp;lt;Stories initShow={true} /&amp;gt;);
    userEvent.type(screen.getByRole("title"), "My story");
    userEvent.type(screen.getByRole("desc"), "This is the body of desc");
    expect(screen.getByRole(/clearBtn/i)).toBeTruthy();
    fireEvent.click(screen.getByRole(/clearBtn/i));
    expect(screen.getByRole("title")).toHaveValue("");
    expect(screen.getByRole("desc")).toHaveValue("");
  });

  it("clicks in close button should close the modal form", () =&amp;gt; {
    render(&amp;lt;Stories initShow={true} /&amp;gt;);
    expect(screen.getByRole(/closeBtn/i)).toBeTruthy();
    fireEvent.click(screen.getByRole(/closeBtn/i));
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;should be display(show, hidden) appropriately&lt;/li&gt;
&lt;li&gt;etc...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Submit PR
&lt;/h2&gt;

&lt;p&gt;When all the test cases passed successfully, I tested the modal form once more time to make sure that the provided data inserted successfully to the database.&lt;/p&gt;

&lt;p&gt;Before submitting a PR, I also double check the task list provided by the maintainer to see whether there is any task which was accidentally missed. &lt;/p&gt;

&lt;p&gt;The maintainer reviewed the PR very quick, he required some minor changes before merging &lt;a href="https://github.com/redxzeta/Awesome-Adoption/pull/240"&gt;my PR&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Overall
&lt;/h2&gt;

&lt;p&gt;In this contribution, I communicated with the maintainer a lot to seek for help. As I mentioned in the previous post, he is very helpful and enthusiastic. I really appreciate that and definitely give a star for &lt;a href="https://github.com/redxzeta/Awesome-Adoption"&gt;his repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading the post!&lt;br&gt;
Happy coding!&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>OSD600 - The Final Release Progress</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Thu, 09 Dec 2021 07:02:55 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-the-final-release-progress-4cg3</link>
      <guid>https://dev.to/vivianvu/osd600-the-final-release-progress-4cg3</guid>
      <description>&lt;h2&gt;
  
  
  1. Tasks
&lt;/h2&gt;

&lt;p&gt;In the last blog, I have made a plan about how to add &lt;a href="https://github.com/redxzeta/Awesome-Adoption/issues/232"&gt;new feature&lt;/a&gt; to &lt;a href="https://github.com/redxzeta/Awesome-Adoption"&gt;Awesome-Adoption&lt;/a&gt; project. Here are some tasks I need to complete in this week: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a modal form for user story which has title, description, location(country + region)&lt;/li&gt;
&lt;li&gt;Check that the fields are not empty&lt;/li&gt;
&lt;li&gt;Have the option to reset fields&lt;/li&gt;
&lt;li&gt;Post valid story to the table stories using &lt;code&gt;react-supabase&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Display any errors for the user&lt;/li&gt;
&lt;li&gt;Use a spinner when posting the data (recommend &lt;code&gt;FetchingButton.jsx&lt;/code&gt; in layout)&lt;/li&gt;
&lt;li&gt;Success should close the modal&lt;/li&gt;
&lt;li&gt;Be sure to clear the fields after closing the modal&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Modification Process
&lt;/h2&gt;

&lt;p&gt;First of all, I create a pop up modal using &lt;a href="https://getbootstrap.com/docs/4.3/components/modal/"&gt;Modal components&lt;/a&gt; from bootstrap which will contain &lt;a href=""&gt;Form components&lt;/a&gt; in its body. As a result, when the &lt;code&gt;Create your story&lt;/code&gt; button is clicked, the modal form will show up for user to input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---PulukUT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1athi98m3n6urof8ewb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---PulukUT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1athi98m3n6urof8ewb.png" alt="Image description" width="631" height="772"&gt;&lt;/a&gt;&lt;br&gt;
After creating the form's input, I use &lt;code&gt;useState()&lt;/code&gt; hook to control input's value. As the suggestion of the maintainer, I had made use of &lt;a href="https://www.npmjs.com/package/react-country-region-selector"&gt;react-country-region-selector&lt;/a&gt; to display two dropdowns for country and region. To make sure that all fields are not empty when the form is submitted, I added &lt;code&gt;required&lt;/code&gt; attribute for all of them.&lt;/p&gt;

&lt;p&gt;Source code for the modal form:&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;Modal show={show} onHide={handleClose}&amp;gt;
        &amp;lt;Modal.Header closeButton&amp;gt;
          &amp;lt;Modal.Title&amp;gt;Create Your Story&amp;lt;/Modal.Title&amp;gt;
        &amp;lt;/Modal.Header&amp;gt;
        &amp;lt;Modal.Body&amp;gt;
          &amp;lt;div className="formContainer"&amp;gt;
            &amp;lt;Form onSubmit={handleSubmit}&amp;gt;
              &amp;lt;Form.Group controlId="form.title"&amp;gt;
                &amp;lt;Form.Label className="str-form-label"&amp;gt;Title&amp;lt;/Form.Label&amp;gt;
                &amp;lt;Form.Control
                  type="text"
                  name="title"
                  value={title}
                  onChange={(e) =&amp;gt; setTitle(e.target.value)}
                  required
                /&amp;gt;
              &amp;lt;/Form.Group&amp;gt;

              &amp;lt;Form.Group controlId="form.description"&amp;gt;
                &amp;lt;Form.Label className="str-form-label"&amp;gt;Description&amp;lt;/Form.Label&amp;gt;
                &amp;lt;Form.Control
                  as="textarea"
                  value={desc}
                  name="desc"
                  onChange={(e) =&amp;gt; setDesc(e.target.value)}
                  rows={5}
                  required
                /&amp;gt;
              &amp;lt;/Form.Group&amp;gt;

              &amp;lt;Form.Group controlId="form.country"&amp;gt;
                &amp;lt;Form.Label className="str-form-label"&amp;gt;Country&amp;lt;/Form.Label&amp;gt;
                &amp;lt;CountryDropdown
                  className="country"
                  name="country"
                  value={country}
                  onChange={(val) =&amp;gt; setCountry(val)}
                  required
                /&amp;gt;
              &amp;lt;/Form.Group&amp;gt;

              &amp;lt;Form.Group controlId="form.region"&amp;gt;
                &amp;lt;Form.Label className="str-form-label"&amp;gt;Region&amp;lt;/Form.Label&amp;gt;
                &amp;lt;RegionDropdown
                  className="region"
                  name="region"
                  blankOptionLabel="No Country Selected"
                  country={country}
                  value={region}
                  onChange={(val) =&amp;gt; setRegion(val)}
                  required
                /&amp;gt;
              &amp;lt;/Form.Group&amp;gt;
              &amp;lt;br /&amp;gt;
              &amp;lt;hr /&amp;gt;
              &amp;lt;div className="btnContainer"&amp;gt;
                &amp;lt;button className="mBtn clearBtn" onClick={clearInput}&amp;gt;
                  Clear
                &amp;lt;/button&amp;gt;
                &amp;lt;button className="mBtn closeBtn" onClick={handleClose}&amp;gt;
                  Close
                &amp;lt;/button&amp;gt;
                &amp;lt;FetchingButton
                  fetching={fetching}
                  action="Save"
                  type="submit"
                  className="mBtn saveBtn"
                /&amp;gt;
              &amp;lt;/div&amp;gt;
            &amp;lt;/Form&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/Modal.Body&amp;gt;
        {err &amp;amp;&amp;amp; (
          &amp;lt;div className="alert alert-danger" role="alert"&amp;gt;
            {err}
          &amp;lt;/div&amp;gt;
        )}
      &amp;lt;/Modal&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I need to add corresponding functions to each button in the form.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Clear&lt;/code&gt; button will clear all fields:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button className="mBtn clearBtn" onClick={clearInput}&amp;gt; Clear &amp;lt;/button&amp;gt;

 const clearInput = () =&amp;gt; {
    setTitle("");
    setDesc("");
    setCountry("");
    setRegion("");
    setErr("");
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Close&lt;/code&gt; button will set value of &lt;code&gt;show&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; to close the modal form:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button className="mBtn closeBtn" onClick={handleClose}&amp;gt;Close&amp;lt;/button&amp;gt;
const handleClose = () =&amp;gt; setShow(false);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Save&lt;/code&gt; button will submit the form, if all inputs are valid, the &lt;code&gt;story&lt;/code&gt; will be inserted to database using &lt;code&gt;react-supabase&lt;/code&gt; otherwise an error will be displayed.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();
    const { error } = await execute({
      user_id: user.id,
      title: title,
      description: desc,
      region: region,
      country: country,
    });
    if (!error) {
      // insert successfully
      clearInput();
      handleClose();
    } else {
      // display error
      setErr(error.message);
    }
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. New experience
&lt;/h2&gt;

&lt;p&gt;This is my very first time working with &lt;code&gt;react-supabase&lt;/code&gt;, at first I got into some troubles about inserting inputs to the database.&lt;br&gt;
After a couple of hours searching the solution in hopelessness, I decided to communicate with the maintainer to get some suggestions. He is very friendly and willing to give a hand, he helps me to find out the solution quickly. It turned out that he mistook to capitalize one field in the database. Then he gave me some solutions to simplify my work. I really appreciate that, truly give a big thank to him. Open source is extremely great! &lt;/p&gt;

&lt;p&gt;Thank you for reading the post!&lt;br&gt;
Happy coding!&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>OSD600 - Preparing For The Final Release</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Sun, 28 Nov 2021 23:18:27 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-preparing-for-the-final-release-39n4</link>
      <guid>https://dev.to/vivianvu/osd600-preparing-for-the-final-release-39n4</guid>
      <description>&lt;h3&gt;
  
  
  1. Introduction
&lt;/h3&gt;

&lt;p&gt;In the final release, I decided to work on an external project named &lt;a href="https://github.com/redxzeta/Awesome-Adoption"&gt;Awesome-Adoption&lt;/a&gt; which is a web application helping users find pets and adopt around their area. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. The issue
&lt;/h3&gt;

&lt;p&gt;I am going to add new feature to the app, here are some tasks I need to complete:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coding form and validating user's input

&lt;ul&gt;
&lt;li&gt;Create a modal form for user story which has title, description, location&lt;/li&gt;
&lt;li&gt;Check that the fields are not empty&lt;/li&gt;
&lt;li&gt;Have the option to reset fields&lt;/li&gt;
&lt;li&gt;Post valid story to the table stories using &lt;code&gt;react-supabase&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Display any errors for the user&lt;/li&gt;
&lt;li&gt;Use a spinner when posting the data (recommend &lt;code&gt;FetchingButton.jsx&lt;/code&gt; in layout)&lt;/li&gt;
&lt;li&gt;Success should close the modal&lt;/li&gt;
&lt;li&gt;Be sure to clear the fields after closing the modal&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Write some tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Planning
&lt;/h3&gt;

&lt;p&gt;To complete the tasks successfully, I am going to spend the next week to finish coding the form and validating user's input since the sub-tasks are interrelated. &lt;/p&gt;

&lt;p&gt;Then in the final week, when the form and validation code are done, the tests should be written to make sure that there are no unexpected behaviors. &lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>OSD600 - Publishing my-ssg To NPM</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Sat, 27 Nov 2021 06:39:02 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-publishing-my-ssg-to-npm-52le</link>
      <guid>https://dev.to/vivianvu/osd600-publishing-my-ssg-to-npm-52le</guid>
      <description>&lt;h1&gt;
  
  
  1. Lab10 requirement
&lt;/h1&gt;

&lt;p&gt;After a long time updating &lt;a href="https://github.com/hlavu/my-ssg"&gt;my-sgg&lt;/a&gt; with new features, this time is an appropriate time to provide a release that allows users to install and use the tool easier. &lt;/p&gt;

&lt;p&gt;Since the tool is written in &lt;a href="https://nodejs.org/en/"&gt;NodeJS&lt;/a&gt;, I will make use of &lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt; to share the tool.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Publishing process
&lt;/h1&gt;

&lt;p&gt;In order to publish a package to &lt;strong&gt;npm&lt;/strong&gt;, I need to &lt;strong&gt;create an npm account&lt;/strong&gt; first. If not, an error code &lt;code&gt;404&lt;/code&gt; will be appeared.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lRmLJYos--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mv4uolzuienec38s45r7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lRmLJYos--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mv4uolzuienec38s45r7.png" alt="Image description" width="880" height="199"&gt;&lt;/a&gt;&lt;br&gt;
Next, I &lt;strong&gt;verified the email&lt;/strong&gt; to authenticate the account. After having an authenticated account, I run &lt;code&gt;npm login&lt;/code&gt; command then provided &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt; to &lt;strong&gt;sign in the npm account&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When I logged in successfully, a message will be displayed to announce.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4OzXCZr---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8yerncqrkk6ozd7movvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4OzXCZr---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8yerncqrkk6ozd7movvv.png" alt="Image description" width="847" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, I run &lt;code&gt;npm publish&lt;/code&gt; command to publish the &lt;a href="https://www.npmjs.com/package/ssg-cli"&gt;package&lt;/a&gt; to &lt;strong&gt;npm&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;After making sure that the package is available in &lt;strong&gt;npm&lt;/strong&gt; I asked my friend to test the tool. Instead of telling her how to install and use the package, I recommended her to read through the &lt;code&gt;README.md&lt;/code&gt; file first. &lt;br&gt;
With the instruction on &lt;code&gt;README.md&lt;/code&gt; she succeeded in installing the package. On her machine, she tested all the provided features and they all worked as expected.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Overall
&lt;/h1&gt;

&lt;p&gt;This is an interesting lab, I have a chance to learn new knowledge about &lt;em&gt;npm package&lt;/em&gt; since I never published a package before. Also, this is a good way to share my work with others. &lt;/p&gt;

&lt;p&gt;All in all, thank you for reading the post.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>OSD600 - Doing Code Reviews</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Sat, 20 Nov 2021 01:52:33 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-doing-code-reviews-24ee</link>
      <guid>https://dev.to/vivianvu/osd600-doing-code-reviews-24ee</guid>
      <description>&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;For reviewing, I did code reviews for 3 other students pull requests on the &lt;a href="https://github.com/Seneca-ICTOER/IPC144"&gt;IPC144 repo&lt;/a&gt;. Since I also work on auditing and fixing markdown file, when I check their works I might find out what I have missed to fix for my task.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The first issue
&lt;/h2&gt;

&lt;p&gt;The first issue I found were pretty minor. It is almost about some address values were forgot to be wrapped in &lt;code&gt;backticks&lt;/code&gt;. Other issues in the repos were addressed well by the contributors or found by other reviewers. &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/74"&gt;PR1&lt;/a&gt; &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/101"&gt;PR2&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The second issue
&lt;/h2&gt;

&lt;p&gt;The second issue is the redundancy of whitespace in source code. This makes the source code's style become inconsistent. Sometimes, if there is a redundant whitespace before &lt;code&gt;bullet point&lt;/code&gt; it will produce different  result than we expected. &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/98"&gt;PR3&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Overall
&lt;/h2&gt;

&lt;p&gt;The review process was very enjoyable. Many people work on the same task will make it be perfect and error-free. &lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>OSD600 - Adding New Feature To Weather App</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Sat, 20 Nov 2021 00:59:25 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-adding-new-feature-to-weather-app-49kb</link>
      <guid>https://dev.to/vivianvu/osd600-adding-new-feature-to-weather-app-49kb</guid>
      <description>&lt;h2&gt;
  
  
  1. The issue
&lt;/h2&gt;

&lt;p&gt;In last contribution for Hacktoberfest, I created a Weather Forecast App. However, users can watch the weather information of one city at a time that is a little inconvenient. I want to update the app so it will have a list of searched locations with some information in another page.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Modification process
&lt;/h2&gt;

&lt;p&gt;Here are modifications I did to update the app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Refactor source code by reconstructing the architecture &lt;br&gt;
Putting all source code in the &lt;code&gt;main&lt;/code&gt; class is not a good practice so I decided to split the code into smaller models. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JOvINTdF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h9n4su6w8hbnbr03ntm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JOvINTdF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h9n4su6w8hbnbr03ntm0.png" alt="Image description" width="301" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AppController&lt;/code&gt; gets data from API and return the &lt;code&gt;JSON&lt;/code&gt; object to other models.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Main&lt;/code&gt; starts the app, prepares views. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Weather Data&lt;/code&gt; stores information of a weather data object&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;City Adapter&lt;/code&gt; describes how to display each City's info to &lt;code&gt;ListView&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HistoryListAcitivity&lt;/code&gt; displays info and listens for event on each &lt;code&gt;ListView&lt;/code&gt; item.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new &lt;code&gt;List&lt;/code&gt; button to the main screen which links to the &lt;code&gt;History List Activity&lt;/code&gt; and passes an &lt;code&gt;ArrayList&lt;/code&gt; of city's name to this activity.&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dC-02Sc1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9wb8x15720ousarbhac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dC-02Sc1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9wb8x15720ousarbhac.png" alt="Image description" width="377" height="88"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Design view for &lt;code&gt;History List&lt;/code&gt; Activity&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VxOxwvsN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7m5zihxlhb8gyndt4zut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VxOxwvsN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7m5zihxlhb8gyndt4zut.png" alt="Image description" width="377" height="348"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;View more details in &lt;a href="https://github.com/aadityamp01/Androapps/pull/73"&gt;PR&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Throwback
&lt;/h2&gt;

&lt;p&gt;During the modification process, the hardest part will be splitting the source code. I faced a problem with multi-thread in Java. The data was set to the view before it was returned from API. I tried to apply some knowledge about &lt;code&gt;Thread&lt;/code&gt; learning from JAC444 but it did not work well. &lt;/p&gt;

&lt;p&gt;As such, I started seeking help from an Android Dev Senior. He is very helpful and enthusiastic. After communicating with him, I found out the solution and got a lot of useful tips for working with Android App.&lt;/p&gt;

&lt;p&gt;All in all, thank you so much for reading the post. &lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>android</category>
      <category>java</category>
    </item>
    <item>
      <title>OSD600 - Auditing And Fixing Markdown File</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Sat, 20 Nov 2021 00:04:40 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-auditing-and-fixing-markdown-file-2dm0</link>
      <guid>https://dev.to/vivianvu/osd600-auditing-and-fixing-markdown-file-2dm0</guid>
      <description>&lt;h2&gt;
  
  
  1. Issue
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://ict.senecacollege.ca/~ipc144/pages/content/index.html"&gt;IPC144 notes&lt;/a&gt;  are written in 30 Markdown files. These files have been automatically translated to Markdown so it might contain typos and some misuse syntaxes. My task is to find and fix those issues to make the Markdown file become consistent and readable.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Modification Process
&lt;/h2&gt;

&lt;p&gt;After getting assigned to &lt;code&gt;string-library.md&lt;/code&gt; file which I want to work on, I forked, cloned &lt;a href="https://github.com/Seneca-ICTOER/IPC144"&gt;IPC144's repo&lt;/a&gt; to my local machine and read through the &lt;code&gt;CONTRIBUTING.md&lt;/code&gt; to set up and run the project locally. &lt;/p&gt;

&lt;p&gt;Then I created a new branch and started finding and fixing existing errors. Here are some modifications I made:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fix typo&lt;/li&gt;
&lt;li&gt;Replace block quotes with admonitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to &lt;a href="https://docusaurus.io/"&gt;Docusaurus&lt;/a&gt; which supports admonitions, I can make use of this feature to display &lt;strong&gt;note&lt;/strong&gt; for a better readability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:::note

We have allocated 62 characters to accommodate 30+30 characters plus the blank space separator and the null terminator byte.

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

&lt;/div&gt;



&lt;p&gt;The above code will be displayed as:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2RJkaemc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0393wzmg64doj4x21iqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2RJkaemc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0393wzmg64doj4x21iqg.png" alt="Image description" width="880" height="141"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove extra white spaces in code blocks&lt;/li&gt;
&lt;li&gt;Fix frontmatter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I update the frontmatter with more information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
id: string-library
title: "String Library"
sidebar_position: 2
slug: /refinements/string-library
description: "String library is a standard library to process character strings"
---
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add inter-site links to other page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Linking to another page which has related information helps learners to review the knowledge so I decided to add some links to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The standard library that ships with [C compilers](/A-Introduction/compilers#the-c-compiler "C compiler") and processes [character strings](/F-Refinements/character-strings "Character Strings") is called the string library. 

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add bold emphasis for some words &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Getting reviewed
&lt;/h2&gt;

&lt;p&gt;After summitting a &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/75/commits/e12fc316b14cc9e2403a0b203e443272acef2319"&gt;PR&lt;/a&gt;, Leyang Yu suggested me to replace the headings for String Length, Copy, Compare, and Concatenate with the third level heading. It's totally appropriate so I applied it and here is the final result:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M9ifrr0v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/liull4qkw37e0ej6v890.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M9ifrr0v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/liull4qkw37e0ej6v890.png" alt="Image description" width="254" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The process was interesting and enjoyable!&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>OSD600 - Adding Continuous Integration (CI)</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Fri, 19 Nov 2021 21:51:38 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-adding-continuous-integration-ci-469h</link>
      <guid>https://dev.to/vivianvu/osd600-adding-continuous-integration-ci-469h</guid>
      <description>&lt;h1&gt;
  
  
  1. Lab9 requirement
&lt;/h1&gt;

&lt;p&gt;In this lab, I am required to create a GitHub Actions Workflow to my repo. By doing so, the tests I created in the previous lab will be triggered and run whenever a PR is submitted or a commit is pushed.  &lt;/p&gt;

&lt;p&gt;In addition, I need to add tests to Dustin's project.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Setup process
&lt;/h1&gt;

&lt;p&gt;To set up the GitHub workflow, I came to the &lt;code&gt;Action&lt;/code&gt; tab and clicked &lt;code&gt;set up this workflow&lt;/code&gt; button in the &lt;code&gt;Node.js&lt;/code&gt; section. &lt;/p&gt;

&lt;p&gt;After that, a new file called &lt;code&gt;node.js.yml&lt;/code&gt; is created, I modified some parts to make the &lt;code&gt;build&lt;/code&gt; suit my purpose. And its content is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Node.js CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [14.x, 16.x]
        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"
      - run: npm ci
      - run: npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I created some e2e tests. Then, submitting a PR to make sure that it did trigger the CI Workflow. After a couple of times modifying the source code. My tests were passed successfully. &lt;a href="https://github.com/hlavu/my-ssg/runs/4247846019?check_suite_focus=true"&gt;Successful GitHub Action Run&lt;/a&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  3. Adding Tests To Another Project
&lt;/h1&gt;

&lt;p&gt;After forking and cloning &lt;a href="https://github.com/tuanthanh2067/cv-ssg"&gt;Dustin's repo&lt;/a&gt; to my local machine, I read through the &lt;code&gt;CONTRIBUTING.md&lt;/code&gt; to set up and run the tool to make sure it work correctly.&lt;/p&gt;

&lt;p&gt;I saw the &lt;code&gt;init()&lt;/code&gt; in the &lt;code&gt;readPath&lt;/code&gt; module did not have any test so I created a new branch and started working on it.&lt;/p&gt;

&lt;p&gt;After all, here are 4 tests I came up with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constructor should set the value of &lt;code&gt;path&lt;/code&gt; equals to the link passed from arg.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;readFile()&lt;/code&gt; should return &lt;code&gt;1&lt;/code&gt; if file path is invalid .&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;init()&lt;/code&gt; should set &lt;code&gt;ext&lt;/code&gt; and &lt;code&gt;result&lt;/code&gt; values correctly for text file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;init()&lt;/code&gt; should set &lt;code&gt;ext&lt;/code&gt; and &lt;code&gt;result&lt;/code&gt; values correctly for markdown file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When newly created tests run successfully in the local machine, I submitted a &lt;a href="https://github.com/tuanthanh2067/cv-ssg/pull/34"&gt;PR&lt;/a&gt; to the repo and make sure it passed the repo's CI workflow.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Overall
&lt;/h1&gt;

&lt;p&gt;It's interesting to work and learn about CI. I definitely make use of this tool to my future projects.&lt;/p&gt;

&lt;p&gt;All in all, thank you for reading the post.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>testing</category>
    </item>
    <item>
      <title>OSD600 - Adding Testing Tool</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Sat, 13 Nov 2021 03:32:26 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-adding-testing-tool-m7e</link>
      <guid>https://dev.to/vivianvu/osd600-adding-testing-tool-m7e</guid>
      <description>&lt;h1&gt;
  
  
  1. Lab8 requirement
&lt;/h1&gt;

&lt;p&gt;Testing is an important part of developer's community, it helps programmers to test their code, detect unexpected bugs, etc. &lt;br&gt;
In this lab, I will set up a testing framework called &lt;a href="https://jestjs.io/"&gt;Jest&lt;/a&gt; to test my-ssg.&lt;/p&gt;

&lt;p&gt;Jest is a JavaScript testing framework, it helps JS developers to ensure the correctness of their source code. Jest pays attention to simplicity and that is the reason I make use of it in my project.&lt;/p&gt;
&lt;h1&gt;
  
  
  2. Modification process
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Install Jest:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add script for testing so you can run &lt;code&gt;npm test&lt;/code&gt; to run all tests in the command line:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "scripts": {
    "test": "jest --verbose"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Write tests:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My-ssg is divided into 6 modules but in this lab I just created testing for 3 modules namely &lt;code&gt;generateHTML&lt;/code&gt;, &lt;code&gt;readTextFile&lt;/code&gt; and &lt;code&gt;readJson&lt;/code&gt;, the rest will be updated later on.&lt;/p&gt;

&lt;p&gt;I created &lt;code&gt;generateHTML.test.js&lt;/code&gt;, &lt;code&gt;readTextFile.test.js&lt;/code&gt;, &lt;code&gt;readJson&lt;/code&gt; files which contains all test cases for 3 modules I chose.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;generateHTML.test.js&lt;/code&gt;, I came up with some ideas to test the &lt;code&gt;generateHTML(title, body, language, stylesheet, htmlContainer)&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Function should create a &lt;code&gt;title.html&lt;/code&gt; file inside the specified folder or &lt;code&gt;./dist&lt;/code&gt; by default.&lt;/li&gt;
&lt;li&gt;Function will throw an error if the &lt;code&gt;title&lt;/code&gt; is an empty string or is not passed to the function&lt;/li&gt;
&lt;li&gt;Function will use default value if &lt;code&gt;language&lt;/code&gt;, &lt;code&gt;stylesheet&lt;/code&gt; and &lt;code&gt;htmlContainer&lt;/code&gt; are not passed to the function &lt;/li&gt;
&lt;li&gt;Function accepts empty value for &lt;code&gt;language&lt;/code&gt; and &lt;code&gt;stylesheet&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before turning these ideas into code, I need to &lt;strong&gt;require&lt;/strong&gt; the function from &lt;code&gt;generateHTML&lt;/code&gt; module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { generateHTML } = require("./generateHTML");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will create test cases inside a &lt;code&gt;describe&lt;/code&gt; block, I declare some &lt;code&gt;const&lt;/code&gt; variables which can be reuse in some test cases (best practice is declare them locally in each test case):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("test generateHTML(title, body, language, stylesheet, htmlContainer)", () =&amp;gt; {
  const title = "index";
  const body = "Hello World!";
  const lang = "en-CA";
  const stylesheet = "https://cdn.jsdelivr.net/npm/water.css@2/out/water.css";
  const htmlContainer = "./dist";
  const expectedPath = "./dist/index.html";

  // test cases...
}

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

&lt;/div&gt;



&lt;p&gt;And here is how the test case look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test("function should create new HTML file named ${title}.html inside the ${htmlContainer} folder", () =&amp;gt; {
    expect(
      generateHTML(title, body, lang, stylesheet, htmlContainer)
    ).toStrictEqual(expectedPath);
  });


test("function should throw an error when title is an empty string", () =&amp;gt; {
    try {
      generateHTML("");
    } catch (err) {
      expect(err).toEqual(
        new Error(chalk.bold.red("***title cannot be empty!***"))
      );
    }
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic to test &lt;code&gt;readTextFile()&lt;/code&gt; and &lt;code&gt;readJson()&lt;/code&gt; are very similar, I check how the function behaves when the &lt;code&gt;arg&lt;/code&gt; is empty or it is not passed to the function.&lt;/p&gt;

&lt;p&gt;To pass all created test cases, I need to make some small modifications to the original source code.&lt;/p&gt;

&lt;p&gt;View my commit: &lt;a href="https://github.com/hlavu/my-ssg/commit/6313fab04be683ee135b2f5caa4f94da75280c92"&gt;6313fab&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Overall
&lt;/h1&gt;

&lt;p&gt;Writing test is a painful process, you may never know &lt;em&gt;how many more tests&lt;/em&gt; you need to write for a snippet code to make sure that you get all problems it may produce. However, writing good tests helps improve the quality of the source code so this skill is necessary for any programmer to achieve.  &lt;/p&gt;

&lt;p&gt;All in all, thank you for reading the post.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>testing</category>
    </item>
    <item>
      <title>OSD600 - Adding Static Analysis Tools</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Sat, 06 Nov 2021 02:18:23 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-adding-static-analysis-tools-46bh</link>
      <guid>https://dev.to/vivianvu/osd600-adding-static-analysis-tools-46bh</guid>
      <description>&lt;h1&gt;
  
  
  1. Lab7 requirement
&lt;/h1&gt;

&lt;p&gt;In this lab, I will make use of Static Analysis Tools which help me maintain the quality of the source code by formatting the code, spotting and warning suspicious errors. Additionally, when other programmers contribute to this project, they can use these tools to ensure a consistent coding style.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Adding process
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt; Formatter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prettier&lt;/strong&gt; is an opinionated code formatter which will automatically format the source code. As a result, programmers do not have to waste their time to format each code snippet. Moreover, prettier keeps a consistent coding style when there are a lot of contributors who have different coding styles working in the same project. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Install prettier&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev --save-exact prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Create configuration file&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo {}&amp;gt; .prettierrc.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Create .prettierignore which bases on .gitignore and .eslintignore&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create scripts for prettier&lt;/em&gt;&lt;br&gt;
In &lt;code&gt;package.json&lt;/code&gt; file, add these two lines inside &lt;code&gt;scripts&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;"prettier": "npx prettier --write .",
"prettier-check": "npx prettier --check ."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing so, I can run &lt;code&gt;npm run prettier&lt;/code&gt; to format all files with Prettier and &lt;code&gt;npm run prettier-check&lt;/code&gt; to check whether all files are formatted with Prettier.&lt;/p&gt;

&lt;p&gt;Initially, I tended to write a statement in a single after using prettier, a statement has been stretched across two more lines.&lt;br&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%2Frektcuxw0jtcyuj62ov9.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%2Frektcuxw0jtcyuj62ov9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;a href="https://eslint.org/" rel="noopener noreferrer"&gt;ESlint&lt;/a&gt; Linter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ESLint&lt;/strong&gt; helps analyze the code to quickly find problems and it is able to fix some errors automatically. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Install ESLint&lt;/em&gt;&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 eslint --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Create configuration file&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx eslint --init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After completing the initiation &lt;code&gt;.eslintrc.js&lt;/code&gt; might look some how like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  env: {
    browser: true,
    node: true, // without this, process is undefined
    commonjs: true,
    es2021: true,
  },
  extends: "eslint:recommended",
  parserOptions: {
    ecmaVersion: 13,
  },
  rules: {
    quotes: ["error", "double"], // using double quotes
    semi: ["error", "always"],
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Create .eslintignore which contains files/folders which don't need to be checked&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create scripts for ESLint&lt;/em&gt;&lt;br&gt;
In &lt;code&gt;package.json&lt;/code&gt; file, add these two lines inside &lt;code&gt;scripts&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;"eslint": "eslint .",
"eslint-fix": "eslint --fix ."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing so, I can run &lt;code&gt;npm run eslint&lt;/code&gt; to find errors in all files with Eslint and &lt;code&gt;npm run eslint-fix&lt;/code&gt; to fix fixable errors.&lt;/p&gt;

&lt;p&gt;After using ESLint, I got some errors about not using &lt;code&gt;double quote&lt;/code&gt;.  To solve the problem, I had added a comment above the line containing error to disable the rule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; // eslint-disable-next-line quotes
head: '&amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;',
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Editor/IDE Integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To integrate formatter and linter into the editor, I created &lt;code&gt;.vscode&lt;/code&gt; folder which has &lt;code&gt;setting.json&lt;/code&gt; file to provide the default formatter and &lt;code&gt;extentions.json&lt;/code&gt; file to share the extensions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add Pre-commit Hook&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are some options available for me to choose, my final pick is using &lt;a href="https://github.com/okonet/lint-staged" rel="noopener noreferrer"&gt;lint-staged&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lint-staged will require you to have &lt;strong&gt;Prettier installed&lt;/strong&gt; and &lt;strong&gt;put into &lt;code&gt;devDependencies&lt;/code&gt;&lt;/strong&gt; before installing it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Install lint-staged&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx mrm@2 lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will install &lt;a href="https://github.com/typicode/husky" rel="noopener noreferrer"&gt;husky&lt;/a&gt;, &lt;a href="https://github.com/okonet/lint-staged" rel="noopener noreferrer"&gt;lint-staged&lt;/a&gt; and add proper configuration to &lt;code&gt;package.json&lt;/code&gt; file. Then, all supported files will be checked and formatted before I commit new change.&lt;/p&gt;

&lt;p&gt;It will display error if there exists one.&lt;br&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%2F9sdm3kp50wpw8qdkmv6m.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%2F9sdm3kp50wpw8qdkmv6m.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&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%2Fuuyst9ur947me76es7yi.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%2Fuuyst9ur947me76es7yi.png" alt="Image description"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;View my commit at &lt;a href="https://github.com/hlavu/my-ssg/commit/8dfbe63b9a9478f4608c141b5367a442054cc7b6" rel="noopener noreferrer"&gt;8dfbe63b&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Overall
&lt;/h1&gt;

&lt;p&gt;Static analysis tools help programmers save a lot of time to format and check for vulnerabilities while validating the code. They plays a critical role in keeping code style consistency in large projects.&lt;/p&gt;

&lt;p&gt;All in all, thank you for reading the post.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>OSD600 - My Fourth Hacktoberfest Contribution</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Sat, 30 Oct 2021 08:32:27 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-my-fourth-hacktoberfest-contribution-1a17</link>
      <guid>https://dev.to/vivianvu/osd600-my-fourth-hacktoberfest-contribution-1a17</guid>
      <description>&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;This semester, I also attend to the Mobile App Development - Android (MAP524) which is about developing mobile applications for the Android platform. I feel quite interested in designing a mobile app so I searched for all android projects with Hacktoberfest label in Git Hub. Luckily, I found one named &lt;a href="https://github.com/aadityamp01/Androapps"&gt;Androapps&lt;/a&gt;, this project contains a lot of Android applications which were contributed by many developers. And I decided to engage in.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The issue
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/aadityamp01/Androapps/issues/53"&gt;issue&lt;/a&gt; I was assigned is to create a Weather forecast application. The maintainer is quite easy-going, he was not be strict about how the app should look like but gave me the freedom to be creative.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The solution
&lt;/h2&gt;

&lt;p&gt;Here are steps I did to create my application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find a weather API

&lt;ul&gt;
&lt;li&gt;After a quick research, I decided to use &lt;a href="https://openweathermap.org/guide"&gt;Open Weather Map&lt;/a&gt; which returns JSON objects. For more information about how to use this, please read the &lt;a href="https://openweathermap.org/guide"&gt;guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Design the UI&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since I just learned about some layouts and basic views in MAP524 so I am going to design a simple UI with an &lt;code&gt;EditText&lt;/code&gt; to get user input, a &lt;code&gt;Button&lt;/code&gt; to submit the input, some &lt;code&gt;TextView&lt;/code&gt; to display information and a &lt;code&gt;ImageView&lt;/code&gt; for app background.&lt;/li&gt;
&lt;li&gt;The UI design:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bvNyqd-1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38gps0ecqc3fkeui2n1e.png" alt="Image description" width="880" height="1858"&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement Java code&lt;br&gt;&lt;br&gt;
1) Using &lt;a href="https://developer.android.com/training/volley"&gt;Volley&lt;/a&gt; library to request data from the API.&lt;br&gt;&lt;br&gt;
2) Get JSON objects/data from response:&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; // gets JSON objects
JSONObject mainWeather = response.getJSONObject("main");
JSONObject weather = response.getJSONArray("weather").getJSONObject(0);
JSONObject windInfo = response.getJSONObject("wind");
JSONObject sunInfo = response.getJSONObject("sys");
int humidity = mainWeather.getInt("humidity");
double windSpeed = windInfo.getDouble("speed");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Calculate data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// converts unix time stamp to date
Date dateInfo = new Date(response.getLong("dt")*1000);
Date sunRiseD = new Date(sunInfo.getLong("sunrise") * 1000);
Date sunSetD = new Date(sunInfo.getLong("sunset") * 1000);
int timezone = response.getInt("timezone");

 // formats output and changes timezone
@SuppressLint("SimpleDateFormat") SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, dd MMM yyyy");         
dateFormat.setTimeZone(TimeZone.getTimeZone(ZoneOffset.ofTotalSeconds(timezone)));

@SuppressLint("SimpleDateFormat") SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm a");           
timeFormat.setTimeZone(TimeZone.getTimeZone(ZoneOffset.ofTotalSeconds(timezone)));

 int tempC = (int) (Math.round(mainWeather.getDouble("temp") - 273.15));
 int feelTemp = (int)(Math.round(mainWeather.getDouble("feels_like") - 273.15));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Display data appropriately to the UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;currentDate.setText(dateStr);
currentTime.setText(timeStr);
temperature.setText(tempC + "°");
location.setText(city.toUpperCase());          
displayWeather.setText(weather.getString("main"));
feels.setText("Feels like: " + feelTemp + "°C");
humid.setText(humidity + "%");
wind.setText(windSpeed + "m/s");
sunRise.setText(sunRiseStr);
sunSet.setText(sunSetStr);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Function to set &lt;code&gt;ImageView&lt;/code&gt; and text color based on time&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void setBackground(int hour, ImageView imgV){...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://drive.google.com/file/d/16VumiNXevAgXSQW-tmHzRN1CEc7xQjML/view?usp=sharing"&gt;View the app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The maintainer reviewed the PR very quick, he merged my PR without any requirements.&lt;/p&gt;

&lt;p&gt;If you want to get more information about the app, please take a look to this &lt;a href="https://github.com/aadityamp01/Androapps/pull/67"&gt;PR&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Overall
&lt;/h2&gt;

&lt;p&gt;I gained a lot of new information after completing this issue. It was painful and enjoyable at the same time.&lt;br&gt;
Thank you for reading the post.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>hacktoberfest</category>
      <category>android</category>
      <category>java</category>
    </item>
    <item>
      <title>OSD600 - My Third Hacktoberfest Contribution</title>
      <dc:creator>Vivian</dc:creator>
      <pubDate>Sat, 30 Oct 2021 06:48:11 +0000</pubDate>
      <link>https://dev.to/vivianvu/osd600-my-third-hacktoberfest-contribution-pie</link>
      <guid>https://dev.to/vivianvu/osd600-my-third-hacktoberfest-contribution-pie</guid>
      <description>&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;This time, I am working on a project which pays attention to make API for food ordering system. The project used JavaScript, CSS and Embedded JavaScript(EJS).&lt;/p&gt;

&lt;p&gt;EJS is a templating language allowing users to generate HTML markup with plain JavaScript. This language is totally new to me so I want to give myself a chance to learn about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The issue
&lt;/h2&gt;

&lt;p&gt;At first, I was assigned to the &lt;a href="https://github.com/MSTC-DA-IICT/REST-API-Node/issues/41"&gt;issue&lt;/a&gt; where I need to check the user authentication before allowing them to create a comment. However when I started working on it, I realized that this issue is related to an unsolved issue. As a result, I decided to communicate with the maintainer and move to another issue in the project.&lt;/p&gt;

&lt;p&gt;My new &lt;a href="https://github.com/MSTC-DA-IICT/REST-API-Node/issues/59"&gt;issue&lt;/a&gt; is about creating a menu page, its &lt;code&gt;url&lt;/code&gt; will receive a query string and display corresponding pictures based on the provided query string.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The solution
&lt;/h2&gt;

&lt;p&gt;Here are some steps I made to solve the issue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a slider at the top of the page showing the most popular food or new food.

&lt;ul&gt;
&lt;li&gt;Create some &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;img&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; tags to contain pictures&lt;/li&gt;
&lt;li&gt;Create css styling&lt;/li&gt;
&lt;li&gt;Create &lt;code&gt;slider.js&lt;/code&gt; to control the slider
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// slider.js
var slideIndex = 0;
showSlides();

function showSlides() {
  var i;
  var slides = document.getElementsByClassName("slide");
  var dots = document.getElementsByClassName("dot");
  for (i = 0; i &amp;lt; slides.length; i++) {
    slides[i].style.display = "none";
  }
  slideIndex++;
  if (slideIndex &amp;gt; slides.length) {slideIndex = 1}
  for (i = 0; i &amp;lt; dots.length; i++) {
    dots[i].className = dots[i].className.replace("active", "");
  }
  slides[slideIndex-1].style.display = "block";
  dots[slideIndex-1].className += " active";
  setTimeout(showSlides, 4000); 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BF5ryLwo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05r7jt4qk7pcgh6akm9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BF5ryLwo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05r7jt4qk7pcgh6akm9v.png" alt="Image description" width="880" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create food items with some information such as name, price, etc.

&lt;ul&gt;
&lt;li&gt;Make use of &lt;code&gt;grid&lt;/code&gt; to create food items&lt;/li&gt;
&lt;li&gt;Create css styling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3WArqqL2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dcbfisv78xyn6m8fbzlo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3WArqqL2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dcbfisv78xyn6m8fbzlo.png" alt="Image description" width="880" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update &lt;code&gt;href&lt;/code&gt; liking to the menu page, read the query string and pass it to the template &lt;code&gt;menu.ejs&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Update &lt;code&gt;href&lt;/code&gt; in menu section so they will link to the menu page and also pass a proper query string
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;li class="mb-2"&amp;gt;&amp;lt;a href="/menu?type=starters"&amp;gt;Starters&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li class="mb-2"&amp;gt;&amp;lt;a href="/menu?type=burgers"&amp;gt;Burgers&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li class="mb-2"&amp;gt;&amp;lt;a href="/menu?type=pastas"&amp;gt;Pastas&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li class="mb-2"&amp;gt;&amp;lt;a href="/menu?type=wraps"&amp;gt;Wraps&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li class="mb-2"&amp;gt;&amp;lt;a href="/menu?type=desserts"&amp;gt;Desserts&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Get the query string and pass it to the template &lt;code&gt;menu.ejs&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.get('/menu', verifyUser,  function(req, res, next) {
  let loggedIn = false;
  if (req.cookies &amp;amp;&amp;amp; req.cookies.user &amp;amp;&amp;amp; req.cookies.login) {
    loggedIn = isUserValid(req.cookies.user, req.cookies.login);
  } 
  let type  = req.query.type;
  res.render('menu', { title: 'Express', type ,loggedIn});

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Retrieve data and check data in the template &lt;code&gt;menu.ejs&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be honest, this is the most tricky part since I never expose to EJS before. It takes me about 10 minutes to find documentation of this language and read through some code examples to understand how its syntax means. &lt;/p&gt;

&lt;p&gt;I used some &lt;code&gt;if&lt;/code&gt; statements to display corresponding heading to the string query.&lt;br&gt;
&lt;strong&gt;Note&lt;/strong&gt;: With the same code but I got stuck at this step about 10 mins for the error &lt;strong&gt;"type" is undefined&lt;/strong&gt; and when I found out the solution, just don't know what to say :x . &lt;strong&gt;JUST RESTART THE SERVER!!&lt;/strong&gt;&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;% if (type == 'starters') { %&amp;gt;
   &amp;lt;div class="title"&amp;gt;&amp;lt;h1&amp;gt;Starters&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;%} %&amp;gt;

  &amp;lt;% if (type == 'burgers') { %&amp;gt;
   &amp;lt;div class="title"&amp;gt;&amp;lt;h1&amp;gt;Burgers&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;%} %&amp;gt;

  &amp;lt;% if (type == 'pastas') { %&amp;gt;
   &amp;lt;div class="title"&amp;gt;&amp;lt;h1&amp;gt;Pastas&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;%} %&amp;gt;

  &amp;lt;% if (type == 'wraps') { %&amp;gt;
   &amp;lt;div class="title"&amp;gt;&amp;lt;h1&amp;gt;Wraps&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;%} %&amp;gt;

  &amp;lt;% if (type == 'desserts') { %&amp;gt;
   &amp;lt;div class="title"&amp;gt;&amp;lt;h1&amp;gt;Desserts&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;%} %&amp;gt;   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I use the value of the string query to get the corresponding path to the correct picture.&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 class="grid-item"&amp;gt;
 &amp;lt;img src="/images/&amp;lt;%= type%&amp;gt;2.jpg"&amp;gt; 
 ...
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--40oN3BBU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jcklujqoacipyufy8k7q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--40oN3BBU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jcklujqoacipyufy8k7q.png" alt="Image description" width="880" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The maintainer reviewed the PR very quick, he merged my &lt;a href="https://github.com/MSTC-DA-IICT/REST-API-Node/pull/60"&gt;PR&lt;/a&gt; without any requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Overall
&lt;/h2&gt;

&lt;p&gt;In my opinion, EJS's syntax will make you confused at first but working with it is still fun. &lt;br&gt;
Thank you for reading the post.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
