<?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: Zion Onwujuba</title>
    <description>The latest articles on DEV Community by Zion Onwujuba (@zion_onwujuba_894fe00cd83).</description>
    <link>https://dev.to/zion_onwujuba_894fe00cd83</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%2F1659364%2Ff2ea1fbc-178a-4d94-9420-7e9c96fc6298.jpg</url>
      <title>DEV Community: Zion Onwujuba</title>
      <link>https://dev.to/zion_onwujuba_894fe00cd83</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zion_onwujuba_894fe00cd83"/>
    <language>en</language>
    <item>
      <title>Reading a CSV using OpenCSV and Kotlin</title>
      <dc:creator>Zion Onwujuba</dc:creator>
      <pubDate>Thu, 08 Aug 2024 21:23:50 +0000</pubDate>
      <link>https://dev.to/zion_onwujuba_894fe00cd83/reading-a-csv-using-opencsv-and-kotlin-d02</link>
      <guid>https://dev.to/zion_onwujuba_894fe00cd83/reading-a-csv-using-opencsv-and-kotlin-d02</guid>
      <description>&lt;p&gt;CSVs are a great tool for storing data in easily readable and structured format. Accessing that data in Kotlin can allow their capabilities to grow even more. &lt;/p&gt;

&lt;p&gt;In this article, we will learn how we can use the free Java library, OpenCSV, to read a CSV and populate a Kotlin class with the data from the CSV.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting with CSVs and Digital Dreams
&lt;/h2&gt;

&lt;p&gt;Let's start with our CSV. We will use the template below as our example.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Age&lt;/th&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tim&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Steve&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;Swift&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bill&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;.NET&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This csv needs to be accessible by our code, so save it into the codebase. In this example, it will be saved under &lt;code&gt;csv/languages.csv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With this, we can import OpenCSV into the build file of the build automation tool of our choice (&lt;a href="https://mvnrepository.com/artifact/com.opencsv/opencsv" rel="noopener noreferrer"&gt;The latest version and import code can be found here&lt;/a&gt;). Then we need to import the &lt;a href="https://kotlinlang.org/docs/no-arg-plugin.html" rel="noopener noreferrer"&gt;noArg&lt;/a&gt; plugin. OpenCSV requires that the class that will be populated by the CSV data contain a constructor with no arguments. Without this plugin, we can get some nasty errors. &lt;/p&gt;

&lt;p&gt;With all of this now added, we can writing the class that will be populated by the CSV.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing the Class
&lt;/h2&gt;

&lt;p&gt;Now we need to write our class that can be populated by the CSV data. We can do that with a class 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;import com.opencsv.bean.CsvBindByName
@NoArg
data class CSVToObject(
    @CsvBindByName(column = "Name", required = true)
    val name: String,
    @CsvBindByName(column = "Age", required = true)
    val age: String,
    @CsvBindByName(column = "Language", required = true)
    val language: String,
    ) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can break the code down into pieces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@NoArg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This annotation calls the noArg plugin and binds our class to it to enforce our class being initialized with a constructor with no arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@CsvBindByName(column = "Name", required = true)
val name: String,
@CsvBindByName(column = "Age", required = true)
val age: String,
@CsvBindByName(column = "Language", required = true)
val language: String,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@CsvBindByName&lt;/code&gt; annotation binds the argument in our class to the header name in the CSV. The &lt;code&gt;required&lt;/code&gt; parameter is optional and just enforces that each cell under a specific header must be filled. We then create an argument that will be bound with the annotation, type casting it to a string. &lt;/p&gt;

&lt;p&gt;So in this example, with the header names being name, age, and language, we are telling the OpenCSV that for each row in the CSV, the data for in the name column for that row will be populated into the name argument. &lt;/p&gt;

&lt;p&gt;So the first row will create an object with the name argument populated with "Tim", the age argument populated with "25", and the language argument populated with "HTML".&lt;/p&gt;

&lt;p&gt;This annotation isn't required. Instead of binding arguments by header name, you can use &lt;code&gt;@CsvBindByPosition&lt;/code&gt; and (with the first column being 0) assign arguments based on their position. &lt;/p&gt;

&lt;p&gt;Here's how that would look with our example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@CsvBindByPosition(position = 0, required = true)
val name: String,
@CsvBindByName(position = 1, required = true)
val age: String,
@CsvBindByName(position = 2, required = true)
val language: String,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have our class we can start reading our CSV and populating our class with its data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading Time!
&lt;/h2&gt;

&lt;p&gt;Now to read our file, we need to make it readable. That involves turning it into a character stream. We can do that by using Java's Path interface to create a URI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; val csvPath : Path = Paths.get(
      ClassLoader.getSystemResource("csv/langauges.csv").toURI()); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use Java's file interface and reader object to create a character stream:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val reader : Reader = Files.newBufferedReader(path) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we can build a javaBean, using &lt;code&gt;CsvToBeanBuilder&lt;/code&gt; and assigning the &lt;code&gt;csvBean&lt;/code&gt; to our &lt;code&gt;CSVToObject&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val csvBean = CsvToBeanBuilder&amp;lt;CSVToObject&amp;gt;(reader)
            .withFieldAsNull(CSVReaderNullFieldIndicator.BOTH)
            .withIgnoreLeadingWhiteSpace(true)
            .withThrowExceptions(false)
            .build()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.withFieldAsNull(CSVReaderNullFieldIndicator.BOTH)&lt;/code&gt; tells the csv parser to consider empty separators and empty quotes in the csv as null.&lt;/li&gt;
&lt;li&gt; &lt;code&gt;.withIgnoreLeadingWhiteSpace(true)&lt;/code&gt; tells the parser to ignore any leading whitespace found in the csv cells.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.withThrowExceptions(false)&lt;/code&gt; tells the parser that if there are any errors in parsing, store them in a list of exceptions. This can be made true if you want the build to stop if there is a &lt;code&gt;CsvException&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.build()&lt;/code&gt; builds our CSV bean&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now with the &lt;code&gt;csvBean&lt;/code&gt; variable we can parse it to get a list of &lt;code&gt;CSVToObject&lt;/code&gt; objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val errorRows:  MutableList&amp;lt;CsvException&amp;gt; = csvBean.capturedExceptions
val successfulRows: MutableList&amp;lt;CSVToObject&amp;gt; = csvBean.parse()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;errorRows&lt;/code&gt; variable, all the rows that were not able to be built will have an &lt;code&gt;CsvException&lt;/code&gt;. If we run &lt;code&gt;errorRows.elementAt(0).message&lt;/code&gt; it will return the error message explaining why the first row couldn't be built.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;successfulRows&lt;/code&gt; variable, all the rows that were able to be built will be stored. And if we run &lt;code&gt;successfulRows.elementAt(0).name&lt;/code&gt; it will return "Tim".&lt;/p&gt;

&lt;p&gt;And with that you'll have a list of objects that you can do whatever you want with. Now that the objects are populated, all the normal rules apply and you can use them however you please. Happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>URL Validation or: How I Learned to Stop Worrying and Love the User</title>
      <dc:creator>Zion Onwujuba</dc:creator>
      <pubDate>Thu, 08 Aug 2024 17:50:45 +0000</pubDate>
      <link>https://dev.to/zion_onwujuba_894fe00cd83/url-validation-or-how-i-learned-to-stop-worrying-and-love-the-user-19k0</link>
      <guid>https://dev.to/zion_onwujuba_894fe00cd83/url-validation-or-how-i-learned-to-stop-worrying-and-love-the-user-19k0</guid>
      <description>&lt;p&gt;There comes a time for every web developer when they have to do some type of input validation. A form isn't a blog post where a user can wax poetically about their love of Yahoo Mail in an email field. Eventually, there needs to be word count limits, checks for specific characters, and simple validation techniques that stops the user from sending a junk POST request. &lt;/p&gt;

&lt;p&gt;However, what if you need to validate a URL? And to add another layer to the problem, what if you only want the hostname of a URL, no paths, no protocol, just the "dubya dubya dubya dot" &lt;code&gt;(www.)&lt;/code&gt; and the &lt;code&gt;.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's start with knowing if a URL is a URL. A link requires a second and top level domain, the &lt;code&gt;walmart&lt;/code&gt; and &lt;code&gt;.com&lt;/code&gt; in &lt;code&gt;walmart.com&lt;/code&gt; respectively, and a scheme (&lt;code&gt;https://&lt;/code&gt;). Without these parts, the link doesn't link to anything and becomes no different from a line of text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqyza0jzypin7mddgcwj5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqyza0jzypin7mddgcwj5.png" alt="Breakdown of an example URL" width="586" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But now that we know the parts of a URL, we reach a fork in or development path. Should the validation restrict the user at the field or sanitize the user input when the data is sent to the server?&lt;/p&gt;

&lt;p&gt;There are merits and deficiencies in either options: &lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Validation Before Submission&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you restrict the user from submitting an invalid URL, it allows you to easily take the data on the server side without any extra work by forcing the user to submit the exact input structure you need. In this case, the &lt;code&gt;pattern&lt;/code&gt; attribute for the &lt;code&gt;input&lt;/code&gt; element combined with some regex would allow for some good old fashioned field validation. &lt;/p&gt;

&lt;p&gt;Here's an example of this approach:&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;input type="text" pattern="https?://.*"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, it comes with a downside of restricting the user. It requires the user to have specific parts to their input and if you just need there to be a &lt;code&gt;.com&lt;/code&gt;, then the long regex pattern might be overkill.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Validation After Submission&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, if you choose to sanitize the data after the user submits it, it allows the user to type anything and lets the server decide what to do with the data. Javascript's &lt;code&gt;URL&lt;/code&gt; constructor does the validation for you, returning a &lt;code&gt;TypeError&lt;/code&gt; if the input is invalid and also allowing you to extract specific parts of the URL like the origin or hostname.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const formatWebsiteAfterDomain = (website: string): string =&amp;gt; {
  if (!website.trim().length) {
    return '';
  }
  const regEx = /:\/\//;
  const websiteTrimmed = website.trim();
  const hasProtocol = regEx.exec(websiteTrimmed);
  const updatedWebsite = hasProtocol
    ? websiteTrimmed
    : `https://${websiteTrimmed}`;

  try {
    const url = new URL(updatedWebsite);
    return hasProtocol ? url.origin : url.origin.replace('https://', '');
  } catch (_err) {
    return websiteTrimmed;
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, because you give the user so much freedom in their input, it requires some compromises in what the server does with the data. If the user puts an invalid URL, what do you do with it? Do you use the &lt;code&gt;TypeError&lt;/code&gt; response and notify the user or do you just allow the server to consume what the user sent? Furthermore, the &lt;code&gt;URL&lt;/code&gt; constructor validates the input by checking if there is a scheme present (&lt;code&gt;https://&lt;/code&gt; or &lt;code&gt;http://&lt;/code&gt;), which may be too little validation for your uses.&lt;/p&gt;




&lt;p&gt;In the end, the path taken depends on the specific edge cases of your problem. A combination of both solutions might be the most comprehensive and versatile or one of the choices might be just enough. The user can put in any input and your solution will be determined on the amount of freedom you're willing to give the user.  However, what remains universal is that the ability of the user to type anything will always force the user and developer to come to some sort of compromise (often the developer gets a specific input pattern and the user gets to use their application). &lt;/p&gt;

&lt;p&gt;But since the peculiarities of user input are eternal, there will always be developers frantically pushing out solutions so their web apps don't break when users try to paste images in the URL field of a form.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
