<?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: Minh Hang Nguyen</title>
    <description>The latest articles on DEV Community by Minh Hang Nguyen (@minhhang107).</description>
    <link>https://dev.to/minhhang107</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%2F701102%2F02f6734d-a78a-4426-a9ff-cdd75c8e1bf7.jpeg</url>
      <title>DEV Community: Minh Hang Nguyen</title>
      <link>https://dev.to/minhhang107</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/minhhang107"/>
    <language>en</language>
    <item>
      <title>The final release</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Sat, 11 Dec 2021 04:49:58 +0000</pubDate>
      <link>https://dev.to/minhhang107/the-final-release-576n</link>
      <guid>https://dev.to/minhhang107/the-final-release-576n</guid>
      <description>&lt;h3&gt;
  
  
  Release 0.4
&lt;/h3&gt;

&lt;p&gt;After completing the implementation mentioned in &lt;a href="https://dev.to/minhhang107/release-04-progress-on-a-new-way-to-subscribe-3ajf"&gt;previous blog&lt;/a&gt;, this week, I focused on testing the new feature. Currently, the project is not using any testing framework so I had to manually test the feature. I went through several aspects of the feature:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing on video/channel page&lt;/li&gt;
&lt;li&gt;Testing on dark/light theme&lt;/li&gt;
&lt;li&gt;Testing the existing &lt;code&gt;Subscribe&lt;/code&gt; button&lt;/li&gt;
&lt;li&gt;Subscribing to a profile more than once&lt;/li&gt;
&lt;li&gt;Ensuring list of subscriptions is updated correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since everything was working as expected, I continued to create the &lt;a href="https://github.com/FreeTubeApp/FreeTube/pull/1934"&gt;pull request&lt;/a&gt;. After a few days without any response from the maintainers, I send a private message to the project owner on the project channel. Unfortunately, all the maintainers are busy so even though the pull request was created on Monday, only one of them got the time to review my implementation. After a quick check, he approved my new feature and didn't request any changes, but he didn't merge it either. There is another pull request that is under progress and he wants that issue to be resolved first before merging my pull request. He also suggested another feature that can be implemented similarly. Though nothing is decided yet, I'm open to continue working on this project and take on the new feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final thoughts on OSD600
&lt;/h3&gt;

&lt;p&gt;After 14 weeks working intensely in open source, I finally understand what "open source" really is. Open source is not randomly picking an issue and working on it. To effectively resolve an issue, I need to spend a lot of time with it to understand the codebase, to know how the project works. I feel much more motivated when I can work on project that I like and would personally use. It gives me a sense of responsibility since I also put myself in the shoe of the users and also gives me ideas on what the feature/the fix should do. &lt;/p&gt;

&lt;p&gt;Having worked on open source makes me understand that collaboration is very important. The best advice I could give myself on anyone starting this path is to not be afraid of code reviews, they could be one of the best things that you can learn from the open source community. Code reviews can make you see your code from a different aspect, they can also give you good practices on coding that you never learned before. Therefore, if you really hope to get the best out of open source community, you need to actively participate in discussion and don't be afraid to raise questions.&lt;/p&gt;

&lt;p&gt;This journey is not too long but I did learn a lot from it: a whole new framework, better understanding of Git/Github and the workflow of coding - review. There were a lot of happy moments where I finished a contribution and they are actually big booster for my confidence in coding. There were also stressful moments but I believe that's a part of learning and I can say that I'm proud of myself for not giving up at those times. I'm also grateful to David, who has brought this amazing course to us. Thank you for sharing such a wonderful source of learning and guiding us on how to make the most out it. OSD600 has ended but it's only the starting point of my journey into open source and I hope I could bring what I learn here into greater contributions in the future.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Release 0.4: Progress on a new way to subscribe</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Mon, 06 Dec 2021 18:05:55 +0000</pubDate>
      <link>https://dev.to/minhhang107/release-04-progress-on-a-new-way-to-subscribe-3ajf</link>
      <guid>https://dev.to/minhhang107/release-04-progress-on-a-new-way-to-subscribe-3ajf</guid>
      <description>&lt;p&gt;Last week, I was &lt;a href="https://dev.to/minhhang107/planning-for-a-new-feature-25dp"&gt;planning&lt;/a&gt; on implementing a &lt;a href="https://github.com/FreeTubeApp/FreeTube/issues/1615"&gt;new feature&lt;/a&gt; for &lt;a href="https://github.com/FreeTubeApp/FreeTube"&gt;FreeTube&lt;/a&gt; and have been working on it for the whole week.&lt;/p&gt;

&lt;p&gt;I first commented on the issue to let the maintainers know that I would like to take on the issue. After a few days without response from them, I had to reach out to them through their private channel and got their approval. Then I went on to work as planned in &lt;a href="https://dev.to/minhhang107/planning-for-a-new-feature-25dp"&gt;previous blog post&lt;/a&gt; and was able to finish all the tasks.&lt;/p&gt;

&lt;p&gt;After some testing, I realized that combining the new feature with the existing functionality of &lt;code&gt;Subscribe&lt;/code&gt; button can be confusing since the button also has to handle &lt;code&gt;unsubscribe&lt;/code&gt; functionality. Therefore I decided to add a separate button just to handle the new feature. I mentioned this approach to the maintainers and they agreed with that.&lt;/p&gt;

&lt;p&gt;With this new approach, the &lt;code&gt;Subscribe&lt;/code&gt; button is kept separately without any changes. The &lt;code&gt;plus&lt;/code&gt; button is implemented as a toggle to show and hide the profile list. Clicking this button will trigger a simple function &lt;code&gt;showProfileList()&lt;/code&gt; to change the &lt;code&gt;showProfiles&lt;/code&gt; property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;showProfileList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showProfiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showProfiles&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the profile list is shown, users can click on any profile and function &lt;code&gt;subscribe(profile)&lt;/code&gt; (&lt;a href="https://github.com/minhhang107/FreeTube/blob/394e550425dbef50afae66789b7d4ffa7fe6eeb6/src/renderer/components/ft-subscribe-button/ft-subscribe-button.js#L54"&gt;code&lt;/a&gt;) will be triggered to directly add the subscription to the target profile without switching.&lt;/p&gt;

&lt;p&gt;Another thing I found was that the feature can also be added to the Channel page so I suggested creating a component for the two buttons and added it to both Video page and Channel page. &lt;/p&gt;

&lt;p&gt;To do this, I had to first create a &lt;a href="https://github.com/minhhang107/FreeTube/tree/add-channel-to-multiple-profiles/src/renderer/components/ft-subscribe-button"&gt;new component&lt;/a&gt; including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ft-subscribe-button.js&lt;/code&gt; file that contains the logic of the component&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ft-subscribe-button.vue&lt;/code&gt; file that is responsible for the template of the component&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ft-subscribe-button.sass&lt;/code&gt; file that has all the styling for the component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After that, I added the component to the Video page and Channel page by &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;including the component in the &lt;code&gt;components&lt;/code&gt; property of the logic files:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ft-subscribe-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FtSubscribeButton&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;replacing the existing &lt;code&gt;Subscribe&lt;/code&gt; button with the new component in the template files and passed any related properties
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ft-subscribe-button&lt;/span&gt;
  &lt;span class="na"&gt;:channel-id=&lt;/span&gt;&lt;span class="s"&gt;"channelId"&lt;/span&gt;
  &lt;span class="na"&gt;:channel-name=&lt;/span&gt;&lt;span class="s"&gt;"channelName"&lt;/span&gt;
  &lt;span class="na"&gt;:channel-thumbnail=&lt;/span&gt;&lt;span class="s"&gt;"channelThumbnail"&lt;/span&gt;
  &lt;span class="na"&gt;:is-subscribed=&lt;/span&gt;&lt;span class="s"&gt;"isSubscribed"&lt;/span&gt;
  &lt;span class="na"&gt;:subscribed-text=&lt;/span&gt;&lt;span class="s"&gt;"subscribedText"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have finished the implementation for all these ideas and in the remaining week, I will be sending the PR, waiting for the maintainers' review and work with them to finalize the new feature.&lt;/p&gt;

&lt;p&gt;Before:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h5lYFBzS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8s97cgp4z7091pjbe136.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h5lYFBzS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8s97cgp4z7091pjbe136.jpg" alt="before" width="880" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

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

</description>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Planning for a new feature</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Wed, 01 Dec 2021 07:05:15 +0000</pubDate>
      <link>https://dev.to/minhhang107/planning-for-a-new-feature-25dp</link>
      <guid>https://dev.to/minhhang107/planning-for-a-new-feature-25dp</guid>
      <description>&lt;p&gt;For the next two weeks, I will be implementing a new feature for &lt;a href="https://github.com/FreeTubeApp/FreeTube"&gt;FreeTube&lt;/a&gt;. FreeTube is a desktop Youtube player with lots of features that I find useful for myself. I've been interested in this repo but haven't got the chance to contribute to it. &lt;/p&gt;

&lt;p&gt;There are a lot of feature requests from users and I found 1 feature that was requested twice (&lt;a href="https://github.com/FreeTubeApp/FreeTube/issues/1615"&gt;request 1&lt;/a&gt;, &lt;a href="https://github.com/FreeTubeApp/FreeTube/issues/568"&gt;request 2&lt;/a&gt;) but unfortunately hasn't been implemented. With this feature, users will be able to quickly add the subscriptions to profile without switching. This would be very useful especially when users want to add to multiple profiles.&lt;/p&gt;

&lt;p&gt;In week 2, I will look into the codebase to understand the structure of the project. I also need to get myself familiar with the coding styles, naming conventions, etc. After that, I will start the actual implementation and try to create a pull request with the first version of the new feature. Implementation of this feature will include the following tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a dropdown to display the list of profiles&lt;/li&gt;
&lt;li&gt;Add tooltip to profile so that when user hovers over, they can see the full name of the profile (the dropdown only shows the initials)&lt;/li&gt;
&lt;li&gt;Modify the current behavior of &lt;code&gt;Subscribe&lt;/code&gt; button. Right now, user will add the subscription to  the active profile on clicking the button. I'll need to make some changes so that clicking the button will open/close the dropdown&lt;/li&gt;
&lt;li&gt;Add click event on each profile in the dropdown to handle the actual subscription&lt;/li&gt;
&lt;li&gt;Add logic to prevent adding a subscription to a profile twice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For week 3, I will wait for the maintainers' reviews, discuss any issues that arise and try to resolve them until we are all satisfied with the code. In week 3, I'll also look closely at the new feature to find any aspects that might be affected by it.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Publishing my first package</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Sat, 27 Nov 2021 07:15:40 +0000</pubDate>
      <link>https://dev.to/minhhang107/publishing-my-first-package-1pf3</link>
      <guid>https://dev.to/minhhang107/publishing-my-first-package-1pf3</guid>
      <description>&lt;p&gt;This week, I've published my 1st package on &lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt; - &lt;a href="https://github.com/minhhang107/mh-ssg"&gt;mh-ssg&lt;/a&gt; - a static site generator CLI.&lt;/p&gt;

&lt;p&gt;The process is not complicated and only involves 4 steps:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Configure the package
&lt;/h4&gt;

&lt;p&gt;In the &lt;code&gt;package.json&lt;/code&gt;, I need to make sure that I have all the required information filled: &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt;. When the package is first published, usually it should be version 1.0.0.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Publish the package
&lt;/h4&gt;

&lt;p&gt;In order to publish package on &lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt;, I had to first create an account on the website. Then log in from the command line with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After successfully logging in, I can publish the package with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm publish &lt;span class="nt"&gt;--access&lt;/span&gt; public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Test the package
&lt;/h4&gt;

&lt;p&gt;I asked my friend for help to test the package I just published. She was able to install the package but when she tried to run it, she found a bug and noticed that &lt;code&gt;README.md&lt;/code&gt; was outdated. Following her feedbacks, I fixed the bug and updated &lt;code&gt;README.md&lt;/code&gt; with more instructions on how to use the tool.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Update the package
&lt;/h4&gt;

&lt;p&gt;When all the bug fixes were in place, I updated the version in &lt;code&gt;package.json&lt;/code&gt; with any related test cases, committed those changes and did a final &lt;code&gt;npm publish&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now &lt;a href="https://www.npmjs.com/package/mh-ssg"&gt;mh-ssg&lt;/a&gt; is available on &lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt; and ready to be used by the community. The tool can be installed with the simple command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i mh-ssg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Creating dark mode for the first time </title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Fri, 19 Nov 2021 03:03:53 +0000</pubDate>
      <link>https://dev.to/minhhang107/creating-dark-mode-for-the-first-time-k6f</link>
      <guid>https://dev.to/minhhang107/creating-dark-mode-for-the-first-time-k6f</guid>
      <description>&lt;h3&gt;
  
  
  The issue
&lt;/h3&gt;

&lt;p&gt;Looking through my classmates' contributions for Hacktoberfest, I found &lt;a href="https://github.com/MichaelCurrin/badge-generator"&gt;badge-generator&lt;/a&gt; - a cool tool that helps us create markdown badges for our documentations. The owner wants to implement the &lt;a href="https://github.com/MichaelCurrin/badge-generator/issues/106"&gt;dark mode&lt;/a&gt; for the site, and since the tool is written with &lt;a href="https://vuejs.org/"&gt;VueJS&lt;/a&gt;, I decided to challenge myself as I could also continue to learn this framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  The implementation
&lt;/h3&gt;

&lt;p&gt;The owner suggested some resources for my inspirations. I found them very useful and had some basic ideas for this. &lt;/p&gt;

&lt;p&gt;First, I added the dark and light theme for the site and applied them to the elements that would be affected by the theme change such as the background, the font of the main content as well as the links and logo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt;&lt;span class="nc"&gt;.light-theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--background-color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--background-color-secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#eeeeee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--accent-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--grey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--text-primary-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#222&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nd"&gt;:root&lt;/span&gt;&lt;span class="nc"&gt;.dark-theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--background-color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1e1e1e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--background-color-secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#3f3f3f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--accent-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e4e4e4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--text-primary-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f3f3f3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next thing I did was to create a &lt;code&gt;ThemeToggle&lt;/code&gt; component and add the it to the &lt;code&gt;App&lt;/code&gt; component. &lt;code&gt;ThemeToggle&lt;/code&gt; includes 3 parts: the template, the script and the style. For the template, I used &lt;code&gt;input&lt;/code&gt; of a checkbox so I could switch between 2 modes. The styling was inspired by &lt;a href="https://dev.to/tqbit/create-your-own-dark-mode-toggle-component-with-vue-js-1284"&gt;tq-bit's blog&lt;/a&gt;, which was one of the owner's suggestions.&lt;/p&gt;

&lt;p&gt;In the script, I added one data that is &lt;code&gt;userTheme&lt;/code&gt; and 3 methods. These include&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;getMediaPreference()&lt;/code&gt; is used to retrieve the initial theme when the website is launched&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setTheme()&lt;/code&gt; will set the class name of the root element to &lt;code&gt;"light-theme"&lt;/code&gt; or &lt;code&gt;"dark-theme"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toggleTheme()&lt;/code&gt; will switch to the other theme on user's click action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also added a &lt;code&gt;mounted()&lt;/code&gt; hook to set a theme for the website on initialization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initUserTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getMediaPreference&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initUserTheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After I sent my &lt;a href="https://github.com/MichaelCurrin/badge-generator/pull/130"&gt;pull request&lt;/a&gt;, the owner requested some changes including removal of unnecessary class and refactoring code with shorter syntax for readability. For example, he suggested that I should use the ternary operator instead of traditional &lt;code&gt;if ... else&lt;/code&gt; statements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasDarkPreference&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark-theme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light-theme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be changed into&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hasDarkPreference&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark-theme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light-theme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Final thoughts
&lt;/h3&gt;

&lt;p&gt;Working with dark mode, I have learned a lot. Last time when I worked with Vue for my 4th contribution in Hacktoberfest, I only had to migrate the existing code to a newer version of Vue. This time, I got the chance to create a brand new component, which gave me better understanding of how the component works. I also learned the general steps to create a dark mode for an application and this is a good foundation for me to generate different themes not just with Vue but with any other frameworks as well. &lt;/p&gt;

&lt;p&gt;The details of the PR can be found &lt;a href="https://github.com/MichaelCurrin/badge-generator/pull/130"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Code Reviews for IPC144 Course Notes Project</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Fri, 19 Nov 2021 02:57:12 +0000</pubDate>
      <link>https://dev.to/minhhang107/code-reviews-for-ipc144-course-notes-project-4ff5</link>
      <guid>https://dev.to/minhhang107/code-reviews-for-ipc144-course-notes-project-4ff5</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;As mentioned in my [previous post], we are currently working on auditing the &lt;a href="https://github.com/Seneca-ICTOER/IPC144/tree/main/docs"&gt;markdown files&lt;/a&gt; for &lt;a href="https://cghub.ca/"&gt;Seneca IPC144 course notes&lt;/a&gt;. Another way I'm contributing to this project is by sending reviews to other students' pull requests.&lt;/p&gt;

&lt;p&gt;There were 2 existing pull requests by &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/73"&gt;hphan9&lt;/a&gt; and &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/72"&gt;oliver-pham&lt;/a&gt; at the moment so I decided to take a look at both.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Process
&lt;/h2&gt;

&lt;p&gt;While I could quickly look at the changes on GitHub, it's still necessary to add their repo as remotes so I could properly test their code locally.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fixing &lt;code&gt;compilers.md&lt;/code&gt; by &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/73"&gt;hphan9&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Emily already fixed a great deal of issues on this page such as the typos, markdown syntax, Frontmatter metadata, improving page's accessibility, adding inter-site links and alt text on images. However, I also found a grammatical mistake and some minor parts that needed to be wrapped in backticks. I also suggested her to replace the plain &lt;code&gt;**Notes**&lt;/code&gt; with &lt;a href="https://docusaurus.io/docs/markdown-features/admonitions"&gt;Admonitions&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fixing &lt;code&gt;algorithms.md&lt;/code&gt; by &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/72"&gt;oliver-pham&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Oliver did a great job fixing the major problems of the page including: updating Frontmatter for page, fixing all code to be wrapped with backticks, replacing &lt;strong&gt;&lt;code&gt;...&lt;/code&gt;&lt;/strong&gt; used as a fourth heading level with &lt;code&gt;####&lt;/code&gt;, replacing blockquote with Admonitions and adding inter-site links. The page content looks much clearer after his changes and all the links are working as intended. There are only 2 things I found which was a grammatical mistake and some extra indentations. These are minor issues but I believe that fixing them will improve the overall consistency of the document.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;After both receiving and giving reviews, I believe that the best approach to do review is to also give suggestions along pointing out the issues. &lt;/p&gt;

</description>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Auditing markdown file</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Fri, 19 Nov 2021 02:56:33 +0000</pubDate>
      <link>https://dev.to/minhhang107/auditing-markdown-file-3e4k</link>
      <guid>https://dev.to/minhhang107/auditing-markdown-file-3e4k</guid>
      <description>&lt;h3&gt;
  
  
  IPC144 course notes
&lt;/h3&gt;

&lt;p&gt;For a long time, students at Seneca College have been using the class notes for course IPC144 at &lt;a href="https://ict.senecacollege.ca/~ipc144/pages/content/index.html"&gt;this website&lt;/a&gt;. For better maintenance, we are moving the notes into a new platform using Docusaurus. Docusaurus will convert the notes into markdown files to be hosted. The auto-conversion, however, has some limitations and we also want to have some customizations. Therefore, the students are joining hands to audit all the markdown files generated by Docusaurus.&lt;/p&gt;

&lt;h3&gt;
  
  
  The process of auditing
&lt;/h3&gt;

&lt;p&gt;The page I decided to work on is &lt;a href="https://cghub.ca/B-Computations/a-simple-calculation"&gt;A Simple Calculation&lt;/a&gt;. To start the work, I followed the basic workflow: fork and clone the repo, run the page locally, go through the checklist mentioned in the &lt;a href="https://github.com/Seneca-ICTOER/IPC144/issues/18"&gt;meta issue&lt;/a&gt; and was able to resolve some issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fixed typo mistakes&lt;/li&gt;
&lt;li&gt;removed unnecessary markdown syntaxes: removing &lt;strong&gt;bold&lt;/strong&gt; when the text is already wrapped in &lt;code&gt;inline code&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;added backticks for anything related to code&lt;/li&gt;
&lt;li&gt;added alt tags for photos to improve accessibility
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;image22&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;png&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;used admonitions for notes and additional information
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fihj24ew--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yijbxm20u3ms411zrzct.jpg" alt="Image description" width="880" height="118"&gt;
&lt;/li&gt;
&lt;li&gt;updated Frontmatter to include more tags:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id: a-simple-calculation
title: A Simple Calculation
sidebar_position: 2
slug: /B-Computations/a-simple-calculation
description:  Create a computer program to solve a basic programming task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Receiving reviews
&lt;/h3&gt;

&lt;p&gt;The great thing of working with open source is that we can get reviews from other developers. After sending the pull request, I got some suggestions from other students, mainly for some minor parts that need backticks but I didn't notice. I was also suggested to update the slug in Frontmatter to match with the standardized format.&lt;/p&gt;

&lt;p&gt;Fixing a problem by one self is never enough. It is very helpful to have other people also looking at the same issue so we can get suggestions from multiple perspectives, which can give us an even better solution.&lt;/p&gt;

&lt;p&gt;To know the detailed solution, read more in the &lt;a href="https://github.com/Seneca-ICTOER/IPC144/issues/38"&gt;issue&lt;/a&gt; and &lt;a href="https://github.com/Seneca-ICTOER/IPC144/pull/74"&gt;pull request&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Adding Continuous Integration - GitHub Actions</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Thu, 18 Nov 2021 19:14:15 +0000</pubDate>
      <link>https://dev.to/minhhang107/adding-continuous-integration-github-actions-n1m</link>
      <guid>https://dev.to/minhhang107/adding-continuous-integration-github-actions-n1m</guid>
      <description>&lt;h3&gt;
  
  
  Continuous Integration
&lt;/h3&gt;

&lt;p&gt;In order to avoid breaking the code in the main branch, I added the Continuous Integration to the GitHub workflow. In this workflow, I want it to run on &lt;code&gt;node ver 14.x&lt;/code&gt; whenever there's push or a pull request to the &lt;code&gt;main&lt;/code&gt; branch. There are 2 actions I wanted to include: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a clean install of all dependencies: &lt;code&gt;npm ci&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a full test run: &lt;code&gt;npm test&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;yml&lt;/code&gt; file would 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;name: Node.js CI
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14.x]
    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;After setting it up myself, I found that CI is not too hard to use and it also brings lots of conveniences as it can quickly detect if a push or pull request might contain a potential error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding more tests to another project
&lt;/h3&gt;

&lt;p&gt;This week, I also created some test cases for another &lt;a href="https://github.com/lyu4321/jellybean"&gt;repo&lt;/a&gt;. Adding tests for someone else's code is no doubt for difficult than working on my own code. I had to understand the logic of the code and try to figure out what each function is supposed to do in order to find all possible scenarios. &lt;/p&gt;

&lt;p&gt;For Leyang's &lt;a href="https://github.com/lyu4321/jellybean"&gt;project&lt;/a&gt;, I found that &lt;code&gt;getHtlmlTitleBody()&lt;/code&gt; was not tested yet so I decided to contribute some tests to it. This function accepts the content of the file as a string and a boolean indicating whether it's a text file or not, it then returns an object with 2 properties: title and body.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;getHtmlTitleBody&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isTxt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="err"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="err"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;tempTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/^&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tempTitle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tempTitle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isTxt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;para&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;para&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;para&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;para&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;markdownit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After investigating the function carefully, I came up with 3 scenarios to test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a text file input with title&lt;/li&gt;
&lt;li&gt;a text file input without title &lt;/li&gt;
&lt;li&gt;a markdown input file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The details of the tests can be found &lt;a href="https://github.com/lyu4321/jellybean/pull/32/files"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Add testing to SSG </title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Sat, 13 Nov 2021 04:17:20 +0000</pubDate>
      <link>https://dev.to/minhhang107/add-testing-to-ssg-1d58</link>
      <guid>https://dev.to/minhhang107/add-testing-to-ssg-1d58</guid>
      <description>&lt;p&gt;For this lab, I picked &lt;a href="https://jestjs.io/"&gt;Jest&lt;/a&gt; as the testing tool for &lt;a href="https://github.com/minhhang107/mh-ssg"&gt;mh-ssg&lt;/a&gt;. This is a popular Javascript testing framework thanks to its simplicity and ease of usage.&lt;/p&gt;

&lt;p&gt;The framework can be easily installed with the following command&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Since &lt;a href="https://github.com/minhhang107/mh-ssg"&gt;mh-ssg&lt;/a&gt; is using ESLint, I also have to install &lt;a href="https://www.npmjs.com/package/eslint-plugin-jest"&gt;eslint-plugin-jest&lt;/a&gt; so that ESLint can work with Jest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add --dev eslint eslint-plugin-jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;.eslintrc&lt;/code&gt; config file, I added the plugin for Jest and &lt;code&gt;"jest/globals": true&lt;/code&gt; to the &lt;code&gt;env&lt;/code&gt; variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "plugins": ["jest"],
   "env": {
      "jest/globals": true
   },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also configured the rules under the rules section&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "rules": {
    "jest/no-disabled-tests": "warn",
    "jest/no-focused-tests": "error",
    "jest/no-identical-title": "error",
    "jest/prefer-to-have-length": "warn",
    "jest/valid-expect": "error"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this lab, I wrote some test cases for &lt;code&gt;generateHTML.js&lt;/code&gt; and &lt;code&gt;validateOutputFolder.js&lt;/code&gt; as unit tests. I realized that sometimes the code for testing can be even more than the code itself. Since the program might have several paths and in each path, it could direct even more sub-paths. Effective testing should cover most of these paths, hence, the amount of testing can be too much if we don't know which feature to focus on. For these test cases, I also learned about mocking. To be specific, I created a mock for the &lt;code&gt;fs&lt;/code&gt; module to test the output folder.&lt;/p&gt;

&lt;p&gt;Another thing I learned was to create end-to-end testing. In order to run this, I had to install another module - &lt;a href="https://www.npmjs.com/package/execa"&gt;execa&lt;/a&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 execa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I created &lt;code&gt;run.js&lt;/code&gt; to execute the program for end-to-end testing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const execa = require("execa");

async function run(...args) {
  try {
    const result = await execa.node("bin/index.js", args);
    return result;
  } catch (err) {
    return err;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thinking from a testing perspective, there are a lot of scenarios to be tested since the program allows several options. I was planning to write tests for all scenarios but due to the limited time, I couldn't complete all of them. Currently, only the tests for &lt;code&gt;--input&lt;/code&gt; are finished and other tests are commented out and I'll find some time to update them soon.&lt;/p&gt;

</description>
      <category>osd600</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Adding Static Analysis Tools to SSG</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Thu, 04 Nov 2021 19:15:27 +0000</pubDate>
      <link>https://dev.to/minhhang107/adding-static-analysis-tools-to-ssg-5ao0</link>
      <guid>https://dev.to/minhhang107/adding-static-analysis-tools-to-ssg-5ao0</guid>
      <description>&lt;p&gt;To maintain the quality of source code, I added a formatter and a linter for &lt;a href="https://github.com/minhhang107/mh-ssg"&gt;my project&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prettier
&lt;/h3&gt;

&lt;p&gt;I pick &lt;a href="https://prettier.io/"&gt;Prettier&lt;/a&gt; as the project's formatter. Prettier will help fix any format issues and generates a neatly-formatted version of your code. That means a consistent style will be applied to the whole code and we can also add any addition styles that we want to apply.&lt;/p&gt;

&lt;p&gt;I installed the plug-in with the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then, I added an empty config file to let the editor and other tools know Prettier is used:&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;One thing I noticed when using this command was that running it from the terminal will generate the file encoded in UTF-16, which won't work. Instead, I had to run the command from &lt;code&gt;cmd&lt;/code&gt; (Windows) so that the file is encoded in UTF-8.&lt;/p&gt;

&lt;p&gt;If you have any style that you want to code to conform to, &lt;code&gt;.prettierrc.json&lt;/code&gt; is the right place to put your styles into. For me, the default format is good enough for me so I keep the file blank as for now. Another file I created was &lt;code&gt;.prettierignore&lt;/code&gt;, which stores the files/folders that I don't want to be processed by Prettier.&lt;/p&gt;

&lt;p&gt;Right from the beginning of the project, I used the extension of Prettier in VSCode so after installing, there was no changes in the format of the code.&lt;/p&gt;

&lt;p&gt;I also added scripts to run Prettier from the terminal so contributors who work on this project can quickly use the tool.&lt;/p&gt;

&lt;p&gt;To format, run:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;To check if all files are already formatted, run:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  ESLint
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://eslint.org/"&gt;ESLint&lt;/a&gt; was chosen as the linter for the project. ESLint will analyze the code to quickly find problems. It can also automatically fix many of them.&lt;/p&gt;

&lt;p&gt;The tool can be installed with:&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;A configuration file called &lt;code&gt;.eslintrc&lt;/code&gt; will be created with this command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This command will prompt you to choose the file type you want - js, yml or json.&lt;/p&gt;

&lt;p&gt;To include the basic rules marked with the tick on &lt;a href="https://eslint.org/docs/rules/"&gt;rules page&lt;/a&gt;, this line should be on the config file you just created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"extends": "eslint:recommended"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ESLint also allows you to add any rules you want to implement. These additional rules should be put in &lt;code&gt;"rules"&lt;/code&gt; property in the same file. &lt;/p&gt;

&lt;p&gt;Similar to Prettier, we can also add the &lt;code&gt;.eslintignore&lt;/code&gt; file to define which files/folders we don't want to be linted.&lt;/p&gt;

&lt;p&gt;To check for problems and automatically fix problems, you can use the following scripts respectively:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





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

&lt;/div&gt;



&lt;p&gt;After running the linting, I found some issues with my code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS C:\Users\hang0\Documents\CPD\S5\OSD\mh-ssg&amp;gt; npx eslint bin

C:\Users\hang0\Documents\CPD\S5\OSD\mh-ssg\bin\index.js
  51:3  error  Parsing error: 'return' outside of function

C:\Users\hang0\Documents\CPD\S5\OSD\mh-ssg\bin\utils\generateHTML.js
  16:23  error  Unnecessary escape character: \&amp;lt;  no-useless-escape
  16:45  error  Unnecessary escape character: \&amp;gt;  no-useless-escape
  16:20  error  Empty block statement  no-empty

✖ 4 problems (4 errors, 0 warnings)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem descriptions are very clear so it was easy to find and fix those issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  IDE Integration
&lt;/h3&gt;

&lt;p&gt;To integrate the tools into the IDE, I installed the Prettier and ESLint extensions and created &lt;code&gt;.vscode&lt;/code&gt; folder. Inside the folder are two items: &lt;code&gt;extensions.json&lt;/code&gt; and &lt;code&gt;settings.json&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;extensions.json&lt;/code&gt; indicates which extensions are used&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "recommendations": ["dbaeumet.vscode-eslint", "esbenp.prettier-vscode"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;settings.json&lt;/code&gt; defines the default formatter to be Prettier and the behavior on save to be auto format and auto fix linting&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": { "source.fixAll.eslint": true }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The commit for new changes can be found &lt;a href="https://github.com/minhhang107/mh-ssg/commit/cb420610496d510591b01dcc39be56dd564f714b"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Static Site Generator - Support static files</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Fri, 29 Oct 2021 04:19:45 +0000</pubDate>
      <link>https://dev.to/minhhang107/static-site-generator-support-static-files-f73</link>
      <guid>https://dev.to/minhhang107/static-site-generator-support-static-files-f73</guid>
      <description>&lt;p&gt;Throughout the previous week, I was exploring &lt;a href="https://docusaurus.io/"&gt;Docusaurus&lt;/a&gt; and found that they have a feature to &lt;a href="https://docusaurus.io/docs/static-assets"&gt;support static files&lt;/a&gt;. I find this feature very useful for any static site generator since images, favicons, stylesheets, etc. are very common parts of a webpage. Therefore, I decided to add &lt;a href="https://github.com/minhhang107/mh-ssg/commit/4ffc2e934d1266eecd8f349cd652c3632afb0b68"&gt;this feature&lt;/a&gt; in my tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Planning
&lt;/h3&gt;

&lt;p&gt;To add this feature,  I sketched out a few tasks to finish:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add markdown support for image syntax&lt;/li&gt;
&lt;li&gt;Create a folder inside the output folder to store all assets&lt;/li&gt;
&lt;li&gt;Save all static files from user input to assets folder&lt;/li&gt;
&lt;li&gt;Parse the saved assets to the html file&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;While finding a way to parse image syntax, I decided to fully implement support for markdown. I used &lt;a href="https://www.npmjs.com/package/markdown-it"&gt;markdown-it&lt;/a&gt; and &lt;a href="https://highlightjs.org/"&gt;highlight&lt;/a&gt; for this task.&lt;/li&gt;
&lt;li&gt;I added a new module - &lt;code&gt;copyAssets&lt;/code&gt; and imported &lt;a href="https://www.npmjs.com/package/fs-extra#copy"&gt;fs-extra&lt;/a&gt; to easily copy the assets from users' folder to the default &lt;code&gt;assets&lt;/code&gt; in output folder.&lt;/li&gt;
&lt;li&gt;Since the process of generating HTML file is getting more and more complicated, I separated a part of the logic into the &lt;code&gt;generateHTML&lt;/code&gt; module. Apart from the existing logic, I also added code to replace old image path to the new one that I just create.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The actual implementation turned out to be more complicated that expected. In step 1, 2, 3, my original plan was to code them myself but then I had to look for libraries to simplify the process, otherwise it would take too much time and there might be unnecessary errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next step
&lt;/h3&gt;

&lt;p&gt;The feature is currently working but there are still rooms for improvement.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For now, t he tool only accepts static files through the config json file. It should accept the assets as an option. For example, users should be able to use &lt;code&gt;mh-ssg -i file.md -a assets&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Currently all files in user input folder are copied to the default &lt;code&gt;assets&lt;/code&gt; folder. However, the tool should go through all the files and only filter out image files before copying so that the storage is not wasted.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>osd600</category>
    </item>
    <item>
      <title>Hacktoberfest - 4th contribution</title>
      <dc:creator>Minh Hang Nguyen</dc:creator>
      <pubDate>Thu, 28 Oct 2021 07:29:35 +0000</pubDate>
      <link>https://dev.to/minhhang107/hacktoberfest-4th-contribution-14mp</link>
      <guid>https://dev.to/minhhang107/hacktoberfest-4th-contribution-14mp</guid>
      <description>&lt;p&gt;For the last contribution in this Hacktoberfest, I decided to take this opportunity to learn a new technology - Vue.js. Therefore, I picked &lt;a href="https://github.com/DavidGolodetsky/GeekScore"&gt;GeekScore&lt;/a&gt; as my starting point.&lt;/p&gt;

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

&lt;p&gt;The project originally used Vue.js 2 and is currently migrating to Vue.js 3. The &lt;a href="https://github.com/DavidGolodetsky/GeekScore/issues/131"&gt;issue&lt;/a&gt; I picked was to do the migration for one of the components - &lt;code&gt;GamesEditDialog.vue&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;To resolve this issue, I imported &lt;code&gt;defineComponent&lt;/code&gt; and &lt;code&gt;ref&lt;/code&gt; from &lt;code&gt;composition-api&lt;/code&gt; while removing &lt;code&gt;vuex&lt;/code&gt;. An important change in Vue.js 3 is that both the data and methods will be set inside the &lt;code&gt;setup()&lt;/code&gt; function. &lt;/p&gt;

&lt;p&gt;I had to remove any &lt;code&gt;this&lt;/code&gt; instances because in the new &lt;code&gt;composition-API&lt;/code&gt;, &lt;code&gt;setup()&lt;/code&gt; does not resolve &lt;code&gt;this&lt;/code&gt; anymore. Instead, &lt;code&gt;ref&lt;/code&gt; is used to manage reactivity. In Vue 2, function &lt;code&gt;data()&lt;/code&gt; returns one single object containing the data. However, in Vue 3, the data are defined in &lt;code&gt;setup()&lt;/code&gt; with the use of &lt;code&gt;ref&lt;/code&gt; to mark each them as a reactive and mutable object. Apart from the data, the two existing methods &lt;code&gt;submitGame()&lt;/code&gt; and &lt;code&gt;updateTheGame()&lt;/code&gt; were also moved inside this function. The function &lt;code&gt;setup()&lt;/code&gt; will then return an object containing these data and methods so that the view can be automatically updated when reactive state changes. &lt;/p&gt;

&lt;h3&gt;
  
  
  Owner's feedback
&lt;/h3&gt;

&lt;p&gt;The owner suggested that there was an instance where I should use &lt;code&gt;reactive&lt;/code&gt; instead of &lt;code&gt;ref&lt;/code&gt;. I looked for more explanations and found that while their main purpose is the same, the usage is a bit different. &lt;code&gt;ref&lt;/code&gt; is mostly used to wrap non-object data while &lt;code&gt;reactive&lt;/code&gt; only wraps an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const toDelete = ref(false);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fields = reactive({
      name: {
        label: 'Name',
        icon: 'dice-multiple-outline',
        value: game.value.name,
        rules: [...standardField, requiredField]
      },
      ...
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another suggested change was about the use of &lt;code&gt;props&lt;/code&gt;. Instead of directly using &lt;code&gt;props&lt;/code&gt;, the repo owner pointed out that I should use &lt;code&gt;toRefs&lt;/code&gt; to restructure it to improve readability and maintain consistency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { game } = toRefs(props);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Final thoughts
&lt;/h3&gt;

&lt;p&gt;Learning a new technology can be confusing at first, but directly working on an existing project like this really gained me better understanding of the concepts. The comments from the project owner also pointed out the parts that I was missing while learning. Looking through them again, I was able to clarify any confusions between &lt;code&gt;ref&lt;/code&gt;, &lt;code&gt;reactive&lt;/code&gt; and &lt;code&gt;toRefs&lt;/code&gt;. &lt;br&gt;
There is still a long way to learn about Vue.js but I believe this has been a good starting point already and I'm ready to go to the next step.&lt;/p&gt;

&lt;p&gt;Issue-4 link: &lt;a href="https://github.com/DavidGolodetsky/GeekScore/issues/131"&gt;https://github.com/DavidGolodetsky/GeekScore/issues/131&lt;/a&gt;&lt;br&gt;
PR-4 link: &lt;a href="https://github.com/DavidGolodetsky/GeekScore/pull/202"&gt;https://github.com/DavidGolodetsky/GeekScore/pull/202&lt;/a&gt;&lt;/p&gt;

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