<?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: Zyrianov Viacheslav</title>
    <description>The latest articles on DEV Community by Zyrianov Viacheslav (@viacheslavzyrianov).</description>
    <link>https://dev.to/viacheslavzyrianov</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%2F378883%2Ff09f6683-d7c3-497c-ba36-86510ff0ad2f.jpg</url>
      <title>DEV Community: Zyrianov Viacheslav</title>
      <link>https://dev.to/viacheslavzyrianov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viacheslavzyrianov"/>
    <language>en</language>
    <item>
      <title>The only real free external media storage you'll need!</title>
      <dc:creator>Zyrianov Viacheslav</dc:creator>
      <pubDate>Tue, 19 Dec 2023 18:58:30 +0000</pubDate>
      <link>https://dev.to/viacheslavzyrianov/the-only-real-free-external-media-storage-youll-need-3g57</link>
      <guid>https://dev.to/viacheslavzyrianov/the-only-real-free-external-media-storage-youll-need-3g57</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I have Nuxt3/ExpressJS project. I need to store images somewhere. I had two options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Store as Base64 in my SQL database. Pros - no external storage, cons - storing Base64 in SQL isn't quite a good practice :D And if I do like that, I will have to compress my images on client side to, let's say, 128kb max. That will cause images to look like, you know 💩&lt;/li&gt;
&lt;li&gt;Use external storage. Pros - images will be perfect, plus these storages often give you some optimization on your images and thumbnails and more cool stuff. Cons - most of them are paid.
So after few hours of investigation and work, I've decided to share with you my experience about implementing external media storage for my app. Spoiler - it's free :)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What to choose?
&lt;/h2&gt;

&lt;p&gt;I've browser through some of them and &lt;a href="https://imagekit.io/"&gt;imagekit.io&lt;/a&gt; grabbed my attention. There was the most free gigabytes of media storage (20GB at the moment) so I've decided to try out that one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;First of what i want to say - docs are amazingly understandable. They have SDKs for all popular frameworks and libraries:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k5TPbmGT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fld0gm5omztv1d9lw3i7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k5TPbmGT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fld0gm5omztv1d9lw3i7.png" alt="Image description" width="800" height="115"&gt;&lt;/a&gt;&lt;br&gt;
I've encountered lots of docs and the were not so good, haha. So, where from do we start?&lt;/p&gt;
&lt;h3&gt;
  
  
  Client side
&lt;/h3&gt;

&lt;p&gt;That would be quite easy and nothing special if you've worked with images and FormData before, but I still gonna wrap it up.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an &lt;code&gt;input&lt;/code&gt; with &lt;code&gt;type="file"&lt;/code&gt;, for it to accept files.&lt;/li&gt;
&lt;li&gt;Add handler, that will create &lt;code&gt;new FormData()&lt;/code&gt; and append image from &lt;code&gt;input&lt;/code&gt; into newly created &lt;code&gt;FormData&lt;/code&gt;. To get image from &lt;code&gt;input&lt;/code&gt; you can simply do &lt;code&gt;const [file] = fileInput.target.files&lt;/code&gt;, checks and validations are on your own for now.&lt;/li&gt;
&lt;li&gt;Send it to your api.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Server side
&lt;/h3&gt;

&lt;p&gt;Now more interesting part, how do we send and store image to imagekit.io from node?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install package &lt;a href="https://www.npmjs.com/package/express-fileupload"&gt;express-fileupload&lt;/a&gt;
That will allow us to work with a bit more comfortable.&lt;/li&gt;
&lt;li&gt;Do &lt;code&gt;const fileUpload = require('express-fileupload')&lt;/code&gt; in your main file, it's &lt;code&gt;app.js&lt;/code&gt; by default.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;app.use(fileUpload())&lt;/code&gt; below.&lt;/li&gt;
&lt;li&gt;Install package &lt;a href="https://www.npmjs.com/package/imagekit"&gt;imagekit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create in your &lt;code&gt;/utils&lt;/code&gt; folder (or anywhere, but I would recommend this approach) file &lt;code&gt;imagekit.js&lt;/code&gt; with basic configuration for our imagekit:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ImageKit = require('imagekit')

module.exports = new ImageKit({
  publicKey: process.env.IMAGEKIT_PUBLIC_KEY,
  privateKey: process.env.IMAGEKIT_PRIVATE_KEY,
  urlEndpoint: process.env.IMAGEKIT_URL_ENDPOINT
})
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you use another framework or library, check page &lt;a href="https://imagekit.io/dashboard/developer/api-keys"&gt;&lt;/a&gt;&lt;a href="https://imagekit.io/dashboard/developer/api-keys"&gt;https://imagekit.io/dashboard/developer/api-keys&lt;/a&gt; for another configurations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In your controllers, import that imagekit by doing &lt;code&gt;const imagekit = require('../utils/imagekit')&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;I've wrote very basic snippet, that's responsible for uploading files to imagekit and returns &lt;code&gt;Promise&lt;/code&gt;. It looks like that:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const uploadImageToStorage = (file, params) =&amp;gt; {
  const uploadOptions = {
    file: file.data,
    fileName: file.name,
    ...params
}
  return imagekit.upload(uploadOptions)
    .then(response =&amp;gt; response)
    .catch(error =&amp;gt; error)
}
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;You can write it in utils and import it to any controller file where you need to upload files, but I've temporarily wrote it right inside controller file (not good, gonna fix it later).&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now use that snippet! But how? As you see, i have &lt;code&gt;params&lt;/code&gt; in my snippet. I won't write about all parameters imagekit provides, for now I've needed only one - &lt;code&gt;folder&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
For now, I've decided to store images structured by folders with user id. How to do it? Easy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;I've created params object:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const uploadImageParams = {
  folder: `user-${user.id}`
}
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;And made a variable with result of uploading that file:&lt;br&gt;
&lt;code&gt;const uploadedImageResult = await uploadImageToStorage(req.files.image, uploadImageParams)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your request succeeded, it will return object that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  fileId: '6581e02044c257da433888de',
  name: 'somefilename.jpg',
  size: 2508483,
  versionInfo: { id: '6581e02044c257da433888de', name: 'Version 1' },
  filePath: '/user-3/somefilename.jpg',
  url: 'https://ik.imagekit.io/${storageName}/user-3/somefilename.jpg',
  fileType: 'image',
  height: 1560,
  width: 1302,
  thumbnailUrl: 'https://ik.imagekit.io/leera/tr:n-ik_ml_thumbnail/user-3/somefilename.jpg'',
  AITags: null
}
&lt;/code&gt;&lt;/pre&gt;




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

&lt;p&gt;The most needed basic props we need from here are &lt;code&gt;url&lt;/code&gt; and &lt;code&gt;thumbnailUrl&lt;/code&gt; to display image on client side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Definitely one of the most comfortable and easy-to-use bucket for files, very friendly DX and tons of free features.&lt;/p&gt;

&lt;h2&gt;
  
  
  P.S.
&lt;/h2&gt;

&lt;p&gt;Also it can add tags to your images, optimize 'em, connect external buckets (like AWS, etc.) and do lots of custom stuff.&lt;/p&gt;

&lt;p&gt;I hope you will find it useful and will never struggle in searching for free image storage again :)&lt;/p&gt;

</description>
      <category>vue</category>
      <category>nuxt</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Vue store action: commit or return data?</title>
      <dc:creator>Zyrianov Viacheslav</dc:creator>
      <pubDate>Fri, 02 Apr 2021 07:23:29 +0000</pubDate>
      <link>https://dev.to/viacheslavzyrianov/vue-store-action-commit-or-return-data-1hpc</link>
      <guid>https://dev.to/viacheslavzyrianov/vue-store-action-commit-or-return-data-1hpc</guid>
      <description>&lt;p&gt;Based on my experience, there are some things that may be useful for novice Vue developers. This time, I want to share with you some info about how to manage response data from API, based on context of using actions.&lt;/p&gt;

&lt;p&gt;There are 2 basic ways, how you can manage response data from action in store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;commit into state&lt;/li&gt;
&lt;li&gt;return instantly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But how to choose, when to use what?&lt;br&gt;
If you want to use data from API anywhere in application e.g. in another store module, vue-component or any other JS file and it is used in multiple files, then you should commit data in state. In that case the data will be available anywhere in application.&lt;/p&gt;

&lt;p&gt;For example, when you retrieve user data, it may be used on user account page and in header to show user name and last name. It means, that response will be used in different components. It can be even requested in completely different component, like &lt;code&gt;App.vue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the data from action is being used as soon as being requested – you should return the data instantly as it was requested.&lt;/p&gt;

&lt;p&gt;For example, there is list of social links, that are being passed from API and being rendered only in footer. So why do we need to save response data in state? We can simply return it from action and instantly use it in &lt;code&gt;Footer.vue&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Another case is dynamic component. What exactly do i mean? If there is component, like news item, that is being rendered only based on specific request, you don’t need to store data in state. Instead of it – simply return data from action, store it in this component! &lt;/p&gt;

&lt;p&gt;Why should it has been done like that? There are two reasons for it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store won’t be littered with unnecessary data&lt;/li&gt;
&lt;li&gt;Store will feel itself more freely and developer will have much less data in store module&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In conclusion, i will say that both approaches are actually legal, but by using return you will not litter store.&lt;/p&gt;

&lt;p&gt;See you later &amp;lt;3&lt;/p&gt;

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