<?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: Mayvid14</title>
    <description>The latest articles on DEV Community by Mayvid14 (@mayvid14).</description>
    <link>https://dev.to/mayvid14</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%2F644507%2Fd6ad7bba-a385-4f13-8244-9d204922cc97.png</url>
      <title>DEV Community: Mayvid14</title>
      <link>https://dev.to/mayvid14</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mayvid14"/>
    <language>en</language>
    <item>
      <title>File uploads in Angular 10+ (or JavaScript in general)</title>
      <dc:creator>Mayvid14</dc:creator>
      <pubDate>Sun, 06 Jun 2021 11:59:22 +0000</pubDate>
      <link>https://dev.to/mayvid14/file-uploads-in-angular-10-or-javascript-in-general-4g9p</link>
      <guid>https://dev.to/mayvid14/file-uploads-in-angular-10-or-javascript-in-general-4g9p</guid>
      <description>&lt;p&gt;Recently, I was working on a side project where I had to upload multiple files. It was a while back that I last worked on file uploads in Angular. So my first instinct was to search for some resources on file uploads in Angular. As expected, I found a lot of them (e.g &lt;a href="https://www.itsolutionstuff.com/post/angular-10-multiple-image-upload-with-preview-exampleexample.html"&gt;Angular 10 Multiple Image Upload with Preview Example&lt;/a&gt;, &lt;a href="https://www.freecodecamp.org/news/formdata-explained/"&gt;How to upload single or multiple files the easy way with FormData&lt;/a&gt;). I found these resources very helpful but they did not solve my problem completely, although they helped me reach a solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem statement
&lt;/h2&gt;

&lt;p&gt;The task had a pretty straight-forward requirement.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User should be able to upload multiple images.&lt;/li&gt;
&lt;li&gt;User should be able to view the images they uploaded.&lt;/li&gt;
&lt;li&gt;User should be able to delete multiple uploaded images.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So basically, it is CRUD for images (without the &lt;strong&gt;U&lt;/strong&gt; part, so should it be CRD?). For this post, I won't go into details of backend implementation, the read and delete parts, as I had no major issue implementing them. The thing I found interesting was the creation/upload part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generic first steps
&lt;/h2&gt;

&lt;p&gt;I must say that the requirement was stated in very simple words, &lt;strong&gt;User should be able to upload multiple images&lt;/strong&gt;. When we hear file uploads, the first thing that comes to mind is the &lt;code&gt;&amp;lt;input type="file" /&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;&amp;lt;input type="file" /&amp;gt;&lt;/code&gt; tag
&lt;/h3&gt;

&lt;p&gt;The input tag with file type is used to open a file browser window in which you can select file/files you want to upload. This is the primary requirement for file uploads. This tag can have more attributes to control it's behavior. Following are the attributes that I used.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;multiple: "true"&lt;/strong&gt;: This lets us upload multiple files at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;accept: "image/*"&lt;/strong&gt;: This restricts the type of files to images only.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So my input tag looked like this:&lt;br&gt;
&lt;/p&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;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;accept=&lt;/span&gt;&lt;span class="s"&gt;"image/*"&lt;/span&gt; &lt;span class="na"&gt;multiple=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  UX perspective
&lt;/h3&gt;

&lt;p&gt;From a user's point of view, whenever I want to upload file/files, I should know what images I have uploaded. A preview of the uploaded images is the best way to achieve this. Luckily, there were abundant resources, and I ended up using the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- The html is something like --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;accept=&lt;/span&gt;&lt;span class="s"&gt;"image/*"&lt;/span&gt; &lt;span class="na"&gt;multiple=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;(change)=&lt;/span&gt;&lt;span class="s"&gt;"onFileChange($event)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The component.ts file&lt;/span&gt;
&lt;span class="nf"&gt;onFileChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;readerEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readerEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Do something with the content, use in src of an img&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsDataURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For multiple files, this will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&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;currentFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readerEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readerEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Using the content&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsDataURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentFile&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;Now what if I don't like one of the images I selected, or what if I wanted to add another image to the queue of images I selected prior? One can say these cases need no attention as the requirement doesn't state these, but from an end-user's perspective, I would want these features as a bare minimum. And once you think about it, you can see that you cannot achieve this by just using the above snippets.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hurdle
&lt;/h2&gt;

&lt;p&gt;Had I not thought of the UX and cared only about completing the requirements, my task would be over in 1 hour and I would have had more sleep, but alas. Jotting down the points we want to achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have the capability to add one or more files to the upload queue.&lt;/li&gt;
&lt;li&gt;Have the capability to remove one or more files from the upload queue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what's stopping us? The answer is &lt;code&gt;input&lt;/code&gt; tag. The &lt;code&gt;input&lt;/code&gt; tag can neither add more files in the list of selected files, nor remove them. So how will we achieve the above improvements? &lt;/p&gt;

&lt;h2&gt;
  
  
  The approach
&lt;/h2&gt;

&lt;p&gt;Let's take baby steps and work out one problem at a time. We will select the first one first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add one or more files to the upload queue
&lt;/h3&gt;

&lt;p&gt;As we have seen, the &lt;code&gt;input&lt;/code&gt; tag cannot add files to the queue. Let's say I select 2 images, &lt;code&gt;img1&lt;/code&gt; and &lt;code&gt;img2&lt;/code&gt;. Now I want to add another image &lt;code&gt;img3&lt;/code&gt; to my queue. If I select the image by clicking on the &lt;code&gt;input&lt;/code&gt; tag and selecting my file, I see that now I only have &lt;code&gt;img3&lt;/code&gt;. The other two are gone. &lt;/p&gt;

&lt;p&gt;This is frustrating because if I had 10+ images, not in any order, and if I wanted to add one more, I had to add all 11 of them again (10 from earlier and 1 that I wish to add to the list).&lt;/p&gt;

&lt;p&gt;We can see that the &lt;code&gt;event.target.files&lt;/code&gt; which is the &lt;code&gt;FileList&lt;/code&gt; cannot keep track of the earlier uploaded files. So why not keep track of them using an array. So I changed my code to store the files in an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;images&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="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&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;currentFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readerEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readerEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&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;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentFile&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsDataURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentFile&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;Now my &lt;code&gt;images&lt;/code&gt; array has the list of files I upload, along with properties &lt;code&gt;id&lt;/code&gt; to uniquely identify them, and &lt;code&gt;src&lt;/code&gt; which has their content (used to display the preview by looping through the images array). And now I can just upload more images and they get appended to the &lt;code&gt;images&lt;/code&gt; array.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deleting one or more files
&lt;/h3&gt;

&lt;p&gt;Now that we have the array, we can delete the images by splicing it. Following is my code for Angular, which can be modified to use in vanilla javascript as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- image.component.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;'let image of images; let index = i'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;[src]=&lt;/span&gt;&lt;span class="s"&gt;"image.src"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"remove-button"&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"removeImage(image.id)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// image.component.ts&lt;/span&gt;
&lt;span class="nf"&gt;removeImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;index&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;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;id&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;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&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;h2&gt;
  
  
  So is it over yet 🙄?
&lt;/h2&gt;

&lt;p&gt;Since we have achieved the desired, is it over? Well, no. An issue with this approach is that if I upload an image, say &lt;code&gt;img1&lt;/code&gt; and then delete it, then we think that it has been deleted, but in reality, it is still present in &lt;code&gt;event.target.files&lt;/code&gt;. And so, if I try to upload &lt;code&gt;img1&lt;/code&gt; again, it does nothing, because there is no change in file and so our function does not trigger.&lt;/p&gt;

&lt;p&gt;The approach that I used might not be an optimal one, and I welcome any suggestions/feedback on it. The issue is the &lt;code&gt;FileList&lt;/code&gt; of the &lt;code&gt;input&lt;/code&gt; tag. So after each upload, I just reset it using &lt;code&gt;this.imageForm.reset()&lt;/code&gt; where &lt;code&gt;this.imageForm&lt;/code&gt; is my &lt;a href="https://angular.io/guide/reactive-forms"&gt;Reactive Form&lt;/a&gt;. The files are already in the array, and since the input has no files, if I try to remove a file and upload it again, it works.&lt;/p&gt;

&lt;p&gt;One may say "What if I upload the same image again without deleting the first one? Wouldn't that make two copies of the same file to be uploaded?" And I don't think that's a problem. Again, if you disagree, I would love to hear your points.&lt;/p&gt;

&lt;p&gt;And so I achieved my "Multiple upload, multiple delete" for images. I hope this helps someone who has similar requirements 😁😁.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
