<?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: Patrick Zocli</title>
    <description>The latest articles on DEV Community by Patrick Zocli (@patzi275).</description>
    <link>https://dev.to/patzi275</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%2F996646%2F20c535bf-3535-4dc7-b01c-61cad87f0be9.jpg</url>
      <title>DEV Community: Patrick Zocli</title>
      <link>https://dev.to/patzi275</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/patzi275"/>
    <language>en</language>
    <item>
      <title>Send email with nodejs</title>
      <dc:creator>Patrick Zocli</dc:creator>
      <pubDate>Sat, 06 Jul 2024 01:22:26 +0000</pubDate>
      <link>https://dev.to/patzi275/send-email-with-nodejs-1ajh</link>
      <guid>https://dev.to/patzi275/send-email-with-nodejs-1ajh</guid>
      <description>&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;an e-mail address (to be used for sending e-mails)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the package nodemail&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;nodemail

&lt;span class="c"&gt;# For typescript projects&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;nodemail @types/nodemail
&lt;/code&gt;&lt;/pre&gt;

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

&lt;p&gt;The email address used must have « &lt;em&gt;2-factor authentication enabled&lt;/em&gt; ». To find out how to activate it, click here: &lt;a href="https://support.google.com/accounts/answer/185839?hl=en&amp;amp;co=GENIE.Platform%3DDesktop" rel="noopener noreferrer"&gt;2-factor authentication&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, you'll need to provide &lt;code&gt;nodemail&lt;/code&gt; with your account authentication information. This includes your email address and a password, but not just any password.&lt;/p&gt;

&lt;p&gt;Google has a platform that &lt;strong&gt;allows you to generate separate passwords&lt;/strong&gt;. These passwords are only used for third-party services such as email clients, email applications (like Nodemailer), and other tools that require secure access to your Google Account.&lt;/p&gt;

&lt;p&gt;To do this, you need to :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to link : &lt;a href="https://myaccount.google.com/apppasswords" rel="noopener noreferrer"&gt;https://myaccount.google.com/apppasswords&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you are logged in to your sender account&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5k60jk7znuspfxgngivb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5k60jk7znuspfxgngivb.png" alt="Google app password plateform interface with red arrow to profile picture" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new application&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6devn6dcpg45xlo5s9hr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6devn6dcpg45xlo5s9hr.png" alt="New application code creation" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the supplied password&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjon20eed5blnqm250ii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjon20eed5blnqm250ii.png" alt="Supplied password for the Test application" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 If the interface is empty, this means you haven't activated &lt;a href="https://support.google.com/accounts/answer/185839?hl=en&amp;amp;co=GENIE.Platform=Desktop" rel="noopener noreferrer"&gt;2-factor authentication&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Development
&lt;/h2&gt;

&lt;p&gt;First, here's a complete example for those of you who understand quickly. Let's say you want to send a nice email to several friends. Here's how to do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nodemailer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nodemailer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// create reusable transporter object using the default SMTP transport&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;transporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nodemailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gmail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;votre.email@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;votre_mot_de_passe&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="c1"&gt;// setup email data with unicode symbols&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mailOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;"Fred Foo 👻" &amp;lt;foo@example.com&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// sender address&lt;/span&gt;
    &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bar@example.com, baz@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// list of receivers&lt;/span&gt;
    &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello ✔&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Subject line&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// plain text body&lt;/span&gt;
    &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;b&amp;gt;Hello world?&amp;lt;/b&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// html body&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// send mail with defined transport object&lt;/span&gt;
&lt;span class="nx"&gt;transporter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mailOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;info&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="nx"&gt;error&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Message sent: %s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messageId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Preview URL: %s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nodemailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTestMessageUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;info&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;Don't forget to replace &lt;code&gt;your.email@gmail.com&lt;/code&gt; and &lt;code&gt;your_password&lt;/code&gt; with your own authentication information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Import module :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nodemailer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nodemailer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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


&lt;p&gt;We start by importing  &lt;code&gt;nodemailer&lt;/code&gt;. Of course, you can also use the ES6 syntax &lt;code&gt;import nodemail from 'nodemail';&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a "transporter" :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nodemailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gmail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your.email@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_password&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;p&gt;Here, we configure our mailman with our Gmail account information. We give him our email address and password so he can access our mailbox and send messages for us.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prepare the email&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mailOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;"Fred Foo 👻" &amp;lt;foo@example.com&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Who sends the email&lt;/span&gt;
    &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ami1@example.com, ami2@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Who to send the email to&lt;/span&gt;
    &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello ✔&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Email subject&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Plain text or&lt;/span&gt;
    &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;b&amp;gt;Hello world?&amp;lt;/b&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// HTML content&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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


&lt;p&gt;We write our email. We define who's sending it (here, Fred Foo), who it's for (several friends), the subject (e.g. "Hello ✔"), and the content (a nice message in text or HTML).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Send the email&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;transporter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mailOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;info&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="nx"&gt;error&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Message sent: %s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messageId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Preview URL: %s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nodemailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTestMessageUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;info&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;p&gt;Finally, we ask our digital letter carrier to send the e-mail. If there's a problem (for example, if the password is incorrect), we display the error. Otherwise, we indicate that the e-mail has been sent and even provide a link to view the e-mail sent (handy for checking).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Never put your password in plain text in your code! Use environment variables or password management services to keep your information safe.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically, it's like asking a trusted mailman to send an e-mail using your Gmail account.&lt;/p&gt;




&lt;p&gt;Now you need to be able to send emails anywhere in the world. If you have any questions, don't hesitate to ask. Happy coding ✨&lt;/p&gt;

</description>
      <category>backend</category>
      <category>webdev</category>
      <category>node</category>
      <category>beginners</category>
    </item>
    <item>
      <title>4 time saving tailwind tips… ⏱️</title>
      <dc:creator>Patrick Zocli</dc:creator>
      <pubDate>Fri, 03 May 2024 22:57:08 +0000</pubDate>
      <link>https://dev.to/patzi275/tailwind-tips-ive-learned-while-using-it--20o4</link>
      <guid>https://dev.to/patzi275/tailwind-tips-ive-learned-while-using-it--20o4</guid>
      <description>&lt;p&gt;When we learn a tech, around 40% of the knowledge we acquire comes from study and the rest from practice.&lt;/p&gt;

&lt;p&gt;Tailwind is no exception.&lt;/p&gt;

&lt;p&gt;So here are 4 tips I've had the pleasure of discovering during my long hours of coding with tailwind&lt;/p&gt;

&lt;h2&gt;
  
  
  1 - Utility classes
&lt;/h2&gt;

&lt;p&gt;Tailwind offers several utility classes, which are combinations of different CSS properties. Here are some, unfortunately, less well-known ones &lt;/p&gt;

&lt;h3&gt;
  
  
  Container (&lt;a href="https://tailwindcss.com/docs/container" rel="noopener noreferrer"&gt;&lt;code&gt;container&lt;/code&gt;&lt;/a&gt;)
&lt;/h3&gt;

&lt;p&gt;This component can be used to set the maximum size of an element as a function of screen width.&lt;br&gt;
In effect, it maps the minimum size of the current breakpoint to the maximum size of the component. Useful if you prefer to code for a fixed screen size.&lt;/p&gt;
&lt;h3&gt;
  
  
  Size (&lt;a href="https://tailwindcss.com/docs/size" rel="noopener noreferrer"&gt;&lt;code&gt;size-*&lt;/code&gt;&lt;/a&gt;)
&lt;/h3&gt;

&lt;p&gt;Sets the height and width of an element at the same time: &lt;code&gt;w-10 h-10 &amp;lt;=&amp;gt; size-10&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Line Clamp (&lt;a href="https://tailwindcss.com/docs/line-clamp" rel="noopener noreferrer"&gt;&lt;code&gt;line-clamp-*&lt;/code&gt;&lt;/a&gt;)
&lt;/h3&gt;

&lt;p&gt;Reduces the number of lines in a text block by replacing the rest with "...".&lt;br&gt;
&lt;em&gt;&lt;code&gt;line-clamp-3&lt;/code&gt; sur un paragraphe&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwbkqlrj2ua8opoxo8q6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwbkqlrj2ua8opoxo8q6.png" alt="line-clamp-3 on a paragraph" width="559" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Others&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/docs/text-overflow#truncate" rel="noopener noreferrer"&gt;&lt;code&gt;truncate&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/docs/divide-width" rel="noopener noreferrer"&gt;&lt;code&gt;divide-x-*, divide-y-*&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  2 - Best approach
&lt;/h2&gt;

&lt;p&gt;Tailwind is designed to be used with a mobile-first approach. &lt;br&gt;
In other words, the class names (e.g. &lt;code&gt;mb-4 text-lg&lt;/code&gt;) you add initially without the prefixes sm, md, lg ... are specifically intended for the mobile version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4de6wqfbd7of44nar7x9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4de6wqfbd7of44nar7x9.png" alt="tailwind mobile first responsive example" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, if you prefer a completely different approach, you can always &lt;a href="https://stackoverflow.com/a/56096070" rel="noopener noreferrer"&gt;customize breakpoints&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  3 - Common properties of children in the parent
&lt;/h2&gt;

&lt;p&gt;I was surprised to discover that we could avoid duplicating the same style from one child to another by grouping common styles in the parent.&lt;br&gt;
Let's say you have a simple list:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex gap-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-black p-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-black p-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-black p-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can apply the same classname to all &lt;code&gt;li&lt;/code&gt; children, adding them to those of parent &lt;code&gt;ol&lt;/code&gt; but preceded by &lt;code&gt;[&amp;amp;&amp;gt;*]&lt;/code&gt;.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex gap-4 [&amp;amp;&amp;gt;*]:bg-black [&amp;amp;&amp;gt;*]:p-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;[&amp;amp;&amp;gt;*]&lt;/code&gt; is a temporary selector which, as you may have guessed, transmits the class that follows it to all children.&lt;/p&gt;

&lt;h2&gt;
  
  
  4 - Prettier for better navigation
&lt;/h2&gt;

&lt;p&gt;For all lovers of clean code, Tailwind recommends an organized way of ordering class names (&lt;a href="https://tailwindcss.com/blog/automatic-class-sorting-with-prettier#how-classes-are-sorted" rel="noopener noreferrer"&gt;&lt;em&gt;details&lt;/em&gt;&lt;/a&gt;).&lt;br&gt;
What's more, an extension is available to help with this. This &lt;a href="https://tailwindcss.com/blog/automatic-class-sorting-with-prettier" rel="noopener noreferrer"&gt;plugin&lt;/a&gt; scans your templates for class attributes containing Tailwind CSS classes, and then sorts those classes automatically following their recommendation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmm88jtxalloohhmvcns.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmm88jtxalloohhmvcns.jpg" alt="Image prettier tailwind" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;This is all I have to share with you for the time being. I hope I've introduced you to something new, and if you have any questions, I'd be happy to answer them !&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>frontend</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>Laravel or Symfony: Which to choose for your project? 🤔</title>
      <dc:creator>Patrick Zocli</dc:creator>
      <pubDate>Mon, 09 Oct 2023 12:21:53 +0000</pubDate>
      <link>https://dev.to/patzi275/laravel-or-symfony-which-to-choose-for-your-project-40bl</link>
      <guid>https://dev.to/patzi275/laravel-or-symfony-which-to-choose-for-your-project-40bl</guid>
      <description>&lt;p&gt;Although different, Laravel and Symfony are gaining in popularity 📈 and are proving to be great choices for projects.&lt;/p&gt;

&lt;p&gt;In this article, we'll recap the main differences between the two technologies so you'll have a clear idea of when to use them. If you can't wait to see the end, simply check out the summary 📦 at the end of the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Laravel
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;If Laravel were a woman, it would be both elegant and accessible. Laravel is known for its clear and expressive syntax, which makes web application development fast and enjoyable.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flaravel.com%2Fassets%2Fimg%2Fcomponents%2Flogo-laravel.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flaravel.com%2Fassets%2Fimg%2Fcomponents%2Flogo-laravel.svg" alt="Logo Laravel" width="240" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No matter what your level of programming experience, Laravel will be intuitive for you and you'll certainly learn a lot, and faster, about this framework.&lt;/p&gt;

&lt;p&gt;One of the most admirable aspects ✨ of Laravel is its ease of use for creating web applications. A concrete example is the creation of a simple route that displays "Hello, Laravel!".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Laravel route file (web.php)&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/hello'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&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;return&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Laravel&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, a route is defined using the &lt;code&gt;Route::get()&lt;/code&gt; function, and when you access &lt;code&gt;/hello&lt;/code&gt; in your browser, you get the message "Hello, Laravel!". This simplicity is one of the reasons why Laravel is so popular, especially among novice developers 🔰.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This aspect makes it an interesting choice for inexperienced development teams under time pressure (a bit like startups).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1qmtqde7lluxt9p9tm9i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1qmtqde7lluxt9p9tm9i.jpg" alt="File structure laravel" width="400" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another key aspect of Laravel is its ecosystem of packages 📦 , mainly managed by Composer. You can easily integrate third-party packages to add functionality to your application. For example, to integrate authentication, you can use the &lt;code&gt;laravel/ui&lt;/code&gt; package, which saves you a lot of time and effort.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This makes it particularly suitable for projects where you want to get results fast.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Symfony
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For Symfony, on the other hand, his personality could be compared to a more formal and sophisticated lady.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk71h5rvszvlwrumaisls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk71h5rvszvlwrumaisls.png" alt="Symfony" width="800" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Symfony's focus on &lt;strong&gt;structure and detailed configuration&lt;/strong&gt; makes it ideal for complex projects requiring careful planning and organization. However, its approach can seem more reserved and demanding, requiring a little more time ⌛️ and effort to fully understand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This means you can configure every aspect of your application in detail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An example in Symfony would involve creating a separate route, controller and view to display "Hello, Symfony!".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Symfony controller&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HelloController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Response&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hello/index.html.twig'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="s1"&gt;' =&amp;gt; '&lt;/span&gt;&lt;span class="nc"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Symfony&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Symfony route file (routes.yaml)&lt;/span&gt;
&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;\Controller&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;\HelloController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, a route is configured in a &lt;code&gt;routes.yaml&lt;/code&gt; configuration file, a controller is created to manage the logic, and a Twig view is used to display the message. This requires more detailed configuration than Laravel, which may seem complex at first, but &lt;strong&gt;offers great flexibility for complex projects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another distinctive aspect of Symfony is its use of components. Symfony is built around a large number of independent components (such as the HTTP component, the Routing component, etc.), which you can use in a &lt;strong&gt;modular&lt;/strong&gt; way in your projects. This encourages code reuse and the separation of concerns, which is particularly beneficial for large-scale projects.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Personally, I think Symfony's modularity makes it a good choice for small projects, as it allows you to develop a small, structured project 🪨.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Community comparison&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.valuecoders.com%2Fblog%2Fwp-content%2Fuploads%2F2019%2F03%2Flaravel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.valuecoders.com%2Fblog%2Fwp-content%2Fuploads%2F2019%2F03%2Flaravel.png" alt="Laravel vs symfony trend chart" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When it comes to communities, Laravel and Symfony each have their own unique advantages. Laravel has a very active community and comprehensive documentation. In addition, it offers a tool called "Laravel Forge" that simplifies the deployment of Laravel applications. On the other hand, Symfony has a robust community, world-renowned components, and is often used for large-scale enterprise projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;In terms of performance, Symfony tends to outperform Laravel for large-scale projects, thanks to its more modular architecture and detailed configuration options. Laravel, however, is often considered faster for initial development due to its simplicity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Laravel is best suited to :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rapid development&lt;/li&gt;
&lt;li&gt;Small and medium-sized applications&lt;/li&gt;
&lt;li&gt;Novice developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Symfony is better suited to :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex projects&lt;/li&gt;
&lt;li&gt;Enterprise applications&lt;/li&gt;
&lt;li&gt;Experienced developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you would like to go into more depth, I would recommend the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://wpwebinfotech.com/blog/laravel-vs-symfony/" rel="noopener noreferrer"&gt;Laravel VS Symfony : Choosing the right PHP framework&lt;/a&gt; by Jigar Shah&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cloudways.com/blog/laravel-vs-symfony/#:~:text=Consider%20project%20size%2C%20goals%2C%20and,security%2C%20scalability%2C%20and%20support." rel="noopener noreferrer"&gt;Laravel vs Symfon&lt;/a&gt;y&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;In conclusion&lt;/strong&gt;, Laravel and Symfony are two excellent PHP frameworks, but they differ in their approach to development. Laravel stands out for its simplicity, development speed and package ecosystem. Symfony offers maximum flexibility for complex projects, thanks to its components and detailed configuration.&lt;/p&gt;

&lt;p&gt;If you have any questions, please don't hesitate to ask, and don't forget to leave me a little feedback - it's always a pleasure!&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>symfony</category>
      <category>backend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Key 🔑 Concept of Responsive Interfaces in ReactJS</title>
      <dc:creator>Patrick Zocli</dc:creator>
      <pubDate>Mon, 02 Oct 2023 15:58:06 +0000</pubDate>
      <link>https://dev.to/patzi275/the-key-concept-of-responsive-interfaces-in-reactjs-e91</link>
      <guid>https://dev.to/patzi275/the-key-concept-of-responsive-interfaces-in-reactjs-e91</guid>
      <description>&lt;h2&gt;
  
  
  What is the Virtual DOM?
&lt;/h2&gt;

&lt;p&gt;Well, it’s a representation of the actual DOM, stored and synchronized with it by React through its ReactDOM library.&lt;/p&gt;

&lt;p&gt;In case you briefly know what the DOM is, or not, imagine that when a web page (web document 📄 ) loads in a browser, it generates a kind of tree-like data structure of the page. &lt;br&gt;
This structure is in the form of nodes and objects used to store information about the various elements (more precisely, the tags) on the page. &lt;br&gt;
These objects can represent windows, documents, sentences, or even styles. The generated structure is thus called the DOM (Document Object Model). &lt;br&gt;
The information in this DOM can then be read and modified smoothly by scripting languages like JavaScript with the help of libraries such as React.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwtyy6t83womekmlz2c4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwtyy6t83womekmlz2c4.gif" alt="Image description" width="486" height="266"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Create a Virtual DOM ?
&lt;/h2&gt;

&lt;p&gt;The virtual DOM was created primarily for &lt;strong&gt;optimization&lt;/strong&gt; reasons, let me explain.&lt;/p&gt;

&lt;p&gt;When a modification is made to a web page, the browser updates loops the part of the page affected by that modification and redraws it.&lt;/p&gt;

&lt;p&gt;The problem is that for all modifications, no matter how small they are, the browser performs a new analysis and a new rendering. When many modifications are made frequently, it becomes a whole different story 🔥.&lt;/p&gt;

&lt;p&gt;To optimize these sometimes excessive updates, several approaches are used, including the &lt;strong&gt;&lt;a href="https://fr.legacy.reactjs.org/docs/faq-internals.html" rel="noopener noreferrer"&gt;VDOM (Virtual DOM)&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Lazy_loading" rel="noopener noreferrer"&gt;lazy loading&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Bandwidth_throttling" rel="noopener noreferrer"&gt;throttling&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://www.notion.so/Api-request-in-vanilla-Javascript-119c77f793764161ae2741eb25374015?pvs=21" rel="noopener noreferrer"&gt;debouncing&lt;/a&gt;&lt;/strong&gt;, as well as libraries like &lt;strong&gt;&lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;Redux&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  How Does React Use the VDOM?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibjtgcuz45q7v1fwc720.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibjtgcuz45q7v1fwc720.png" alt="Image description" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During the initial rendering of the application, React creates a tree of the virtual DOM for the web page and stores it in memory.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When the application is updated (with each &lt;strong&gt;&lt;code&gt;setState()&lt;/code&gt;&lt;/strong&gt; call or prop change), React creates a new VDOM tree with all the modifications.&lt;/li&gt;
&lt;li&gt;It detects the elements that have changed and those that need to be updated by comparing the new VDOM tree with the previous one, using a diffing algorithm called "Reconciliation."&lt;/li&gt;
&lt;li&gt;From this, it generates an action plan that details the updates to apply to the actual DOM.&lt;/li&gt;
&lt;li&gt;Finally, React applies the necessary updates to the real DOM, following the action plan generated with ReactDOM.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡  &lt;strong&gt;But how does React manage DOM changes differently from direct manipulation in pure JavaScript?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you make multiple rapid changes to the DOM in pure JavaScript, each change can trigger an immediate update, while React has the ability to group these changes to apply them all at once, thereby avoiding excessive operations.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Going Further 🔎: What Does This Comparison Algorithm Do?
&lt;/h2&gt;

&lt;p&gt;As you might expect, React compares elements of the virtual DOM from the root node to the last node and acts differently depending on the types of elements.&lt;/p&gt;
&lt;h3&gt;
  
  
  Change of Type
&lt;/h3&gt;

&lt;p&gt;When an element changes its type (for example, from &lt;strong&gt;&lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;&lt;/strong&gt; to &lt;strong&gt;&lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;&lt;/strong&gt;), React destroys the current tree and creates a new one by inserting the new elements.&lt;/p&gt;

&lt;p&gt;For example, by comparing these two elements:&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;!-- Initial State --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"javascript:void(0)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Like&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- State After Modification --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Like&lt;span class="nt"&gt;&amp;lt;/button&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;p&gt;React rebuilds the entire VDOM by replacing the &lt;strong&gt;&lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;&lt;/strong&gt; node with the &lt;strong&gt;&lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;&lt;/strong&gt; node.&lt;/p&gt;

&lt;h3&gt;
  
  
  Property Change
&lt;/h3&gt;

&lt;p&gt;However, when it's just a property change, React only updates the property in the VDOM.&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;!-- Initial State --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- State After Modification --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"card card__white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No comment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handling Children
&lt;/h3&gt;

&lt;p&gt;Let's imagine two &lt;strong&gt;&lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;&lt;/strong&gt; lists:&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;!-- Old List --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Cat&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Dog&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- New List with Addition --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Cat&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Dog&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Bird&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By comparing each element in these lists, React notes that the element &lt;strong&gt;&lt;code&gt;&amp;lt;li&amp;gt;Bird&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/strong&gt; has been added by correspondence and simply updates it.&lt;/p&gt;

&lt;p&gt;But, but, but if you add an element to the beginning:&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;!-- Old List --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Cat&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Dog&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- New List with Addition at the Beginning --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Bird&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Cat&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Dog&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When comparing the first children &lt;strong&gt;&lt;code&gt;&amp;lt;li&amp;gt;Cat&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;&amp;lt;li&amp;gt;Bird&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/strong&gt;, React considers this a change of type. It will update each element individually (which is not ideal for performance).&lt;/p&gt;

&lt;p&gt;This is where React's &lt;strong&gt;&lt;code&gt;key&lt;/code&gt;&lt;/strong&gt; attribute comes into play. It uses it to match the children of the initial tree with those of the subsequent tree.&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;!-- Old List --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Dog&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cat&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- New List with KEY --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Bird&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Dog&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cat&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, React knows that the element with key '3' is new, and the elements with keys '1' and '2' have been moved. Thus, React can efficiently rearrange the elements without having to rebuild the entire list.&lt;/p&gt;




&lt;p&gt;In summary, ReactJS stands out as a tool of choice for creating user interfaces. With the virtual DOM explained here, React optimizes performance by minimizing costly updates to the real DOM, contributing to smooth interfaces and efficient development. It is worth noting that while React is recognized for this approach, it is not the only one to adopt it.&lt;/p&gt;

&lt;p&gt;If you have any questions or would like to learn more about, feel free to reach out.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>performance</category>
      <category>frontend</category>
    </item>
    <item>
      <title>5 flutter projects you should build…seriously ⚙️</title>
      <dc:creator>Patrick Zocli</dc:creator>
      <pubDate>Wed, 22 Mar 2023 09:53:52 +0000</pubDate>
      <link>https://dev.to/patzi275/5-flutter-projects-you-should-buildseriously-ga</link>
      <guid>https://dev.to/patzi275/5-flutter-projects-you-should-buildseriously-ga</guid>
      <description>&lt;h2&gt;
  
  
  Introduction 🎬
&lt;/h2&gt;

&lt;p&gt;We know that &lt;strong&gt;flutter&lt;/strong&gt; is an open-source mobile application development framework that is quickly gaining popularity amongst developers. It allows for the development of high-performance applications for both Android and iOS platforms using a single codebase. With Flutter, developers can build beautiful and functional applications with ease.&lt;/p&gt;

&lt;p&gt;In this article, we will explore &lt;strong&gt;5 Flutter projects&lt;/strong&gt; that you should build to improve your skills as a developer. These projects are designed to challenge your skills and provide you with valuable experience in building real-world applications. Let's get started!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Ecommerce App 🛍🏬
&lt;/h2&gt;

&lt;p&gt;The Ecommerce App is an excellent project for anyone who wants to learn more about building an end-to-end e-commerce application. This project will require you to build both the customer and admin sides of the app, including adding real products, their metadata, and all the necessary features for a functioning e-commerce application. You will also learn how to integrate payment systems, such as Stripe, into your application. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Stack&lt;/strong&gt;: Flutter, Postgres, NodelS, Heroku, Stripe, AWS&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;📚 Some resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://m.youtube.com/watch?v=GQJovou6zuE" rel="noopener noreferrer"&gt;Flutter shop app with backend - youtube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@ekosuprastyo15/tutorial-ecommerce-app-using-flutter-96875d814c70" rel="noopener noreferrer"&gt;Tutorial ecommerce app using flutter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flutterawesome.com/tag/ecommerce/" rel="noopener noreferrer"&gt;Ecommerce templates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  2. Social Media App 📱👥
&lt;/h2&gt;

&lt;p&gt;Social media is a ubiquitous part of our daily lives, and building your own social media app is an exciting project. In this project, you will learn how to build a social media application using Flutter, MongoDB, ... . You will also learn how to implement features such as user authentication, messaging, and notifications.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Stack&lt;/strong&gt;: Flutter, MongoDB, NodeJS, SocketlO, AuthO, Heroku, AWS&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;📚 Some resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.toptal.com/flutter/flutter-tutorial" rel="noopener noreferrer"&gt;Build a messaging app using flutter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://phatrabbitapps.com/building-a-social-media-app-with-aws-amplify-and-flutterpart-1" rel="noopener noreferrer"&gt;Build social media app with aws&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  3. Youtube Clone 🎥▶️
&lt;/h2&gt;

&lt;p&gt;Video platforms are the future, and building a YouTube clone is an excellent way to learn more about video streaming applications. In this project, you will build a replica of YouTube with your own custom features.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stack&lt;/strong&gt;: flutter, mongodb, nodes, heroku&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some resources 📚: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://m.youtube.com/watch?v=umhl2hakkcY" rel="noopener noreferrer"&gt;Flutter youtube clone UI tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Aliimam2001/youtube_clone_material_x.git" rel="noopener noreferrer"&gt;Youtube clone material code example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  4. Messenger App 📨📲
&lt;/h2&gt;

&lt;p&gt;Building a messaging application is an excellent way to learn more about real-time communication. In this project, you will build a messaging app with two core features: public and private messaging. You will also learn how to integrate databases such as MongoDB, RedisDB, and SocketlO into your application.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Stack&lt;/strong&gt;: Flutter, MongoDB, NodeJS, Heroku, AWS, RedisDB, SocketlO&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some resources 📚:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://m.youtube.com/watch?v=Qwk5oIAkgnY" rel="noopener noreferrer"&gt;Chat app in flutter and firebas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://supabase.com/blog/flutter-tutorial-building-a-chat-app" rel="noopener noreferrer"&gt;Build a chat app with flutter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/build-a-chat-app-ui-with-flutter/amp/" rel="noopener noreferrer"&gt;FreeCodeCamp - Build a chat app UI with flutter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  5. Notion Clone 📃📊
&lt;/h2&gt;

&lt;p&gt;Notion is an all-in-one tool used for creating notes, timetables, todo lists, and more. Building a Notion clone is an excellent project for anyone who wants to learn more about creating productivity applications. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Stack&lt;/strong&gt;: Flutter, Firebase/Supabase&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;📚 Some resources:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;404 not found&lt;/em&gt; ;)&lt;/p&gt;



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

&lt;p&gt;These five Flutter projects are excellent for improving your skills as a developer. By building these applications, you will learn how to implement various features and integrate different databases and services. Whether you are a beginner or an experienced developer, these projects are an excellent way to improve your skills and build your portfolio. &lt;/p&gt;




&lt;p&gt;If you loved this article, do not hesitate to like, you will make me happy.&lt;/p&gt;

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

</description>
      <category>beginners</category>
      <category>mobile</category>
      <category>flutter</category>
      <category>career</category>
    </item>
    <item>
      <title>Best practices to use Git like a pro</title>
      <dc:creator>Patrick Zocli</dc:creator>
      <pubDate>Sun, 19 Feb 2023 19:44:44 +0000</pubDate>
      <link>https://dev.to/patzi275/best-practices-to-use-git-like-a-pro-2169</link>
      <guid>https://dev.to/patzi275/best-practices-to-use-git-like-a-pro-2169</guid>
      <description>&lt;p&gt;Welcome to the wonderful world of Git 🚀, where we can store versions of our code without the hassle of endless folders named "version1", "version2", "version3", and so on.&lt;/p&gt;

&lt;p&gt;Git is an incredibly useful tool for developers, but it can be intimidating at first. In this article, we'll talk about the best practices to adopt if you want to use it like a pro!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Don't store unnecessary files
&lt;/h2&gt;

&lt;p&gt;Imagine you have a folder full of useless files, like "Untitled-1.txt", "Trying out stuff.txt", "README-copy.md", etc. When you use Git to commit your changes, it will include them in your project history. This means that these useless files will be stored forever in your project history.&lt;/p&gt;

&lt;p&gt;The solution? Add a &lt;code&gt;.gitignore&lt;/code&gt; file to the root of your project and list all the files and folders you don't want to include in the Git history. For the lazy, there are even &lt;code&gt;.gitignore&lt;/code&gt; templates available online for different types of projects.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For example : &lt;a href="https://github.com/github/gitignore" rel="noopener noreferrer"&gt;https://github.com/github/gitignore&lt;/a&gt;, &lt;a href="https://github.com/toptal/gitignore/tree/master/templates" rel="noopener noreferrer"&gt;https://github.com/toptal/gitignore/tree/master/templates&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. Regular and atomic commits
&lt;/h2&gt;

&lt;p&gt;When working on a feature or a bugfix, don't forget to make regular commits. This saves your work and makes it easier to understand by other team members (and/or yourself).&lt;/p&gt;

&lt;p&gt;Atomic commits are commits that contain only one logical change to your code. If you make multiple changes at the same time, it can be difficult to understand which commit caused which change (I've experienced this unfortunately 🥲). Especially when using atomic commits, it's easier to see the history of code changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Use branches
&lt;/h2&gt;

&lt;p&gt;Branches are copies of your code that you can work on without affecting the main branch. This way, you can test features without affecting the main code and merge changes only when you are sure that everything works fine.&lt;/p&gt;

&lt;p&gt;When you create a branch, it's a good idea to name it after the functionality you're developing.&lt;/p&gt;

&lt;p&gt;❌ Avoid generic branch names like &lt;code&gt;branch-1&lt;/code&gt; or &lt;code&gt;branch-2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;✅ Prefer more specific names like &lt;code&gt;feature-payment&lt;/code&gt; or &lt;code&gt;bug-page-connection&lt;/code&gt;. It's easier to find your way through the branch history.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Good to know: &lt;em&gt;Never push directly on the main branch&lt;/em&gt;"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4. Use meaningful commit messages
&lt;/h2&gt;

&lt;p&gt;When you make a commit, the associated message should be clear and precise to explain the change you made.&lt;/p&gt;

&lt;p&gt;❌ Avoid unnecessary commit messages like "modify" or "bug fix." They do not provide enough information to understand the changes made.&lt;/p&gt;

&lt;p&gt;✅ Prefer more specific messages like "Fixed login page bug" or "Added contact form validation". Use action verbs in your commit messages to describe what the change does: add to, remove from, fix, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Make pull requests to merge your branches
&lt;/h2&gt;

&lt;p&gt;A pull request is a branch merge request that allows other developers to see the changes made, test them, and give feedback. It is also a good practice to request a code review before merging a branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Make regular backups
&lt;/h2&gt;

&lt;p&gt;Imagine working hard for hours or even days on a project and losing everything due to a hard drive failure or a branch merge error. This can be devastating to your motivation and productivity. So it's crucial to take the time to make regular backups of your code, whether it's using online storage services like GitHub or GitLab, backing up to external drives, or using cloud backup services.&lt;/p&gt;

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

&lt;p&gt;Now you know the best practices to use Git like a pro! If you follow these tips, you'll avoid common Git pitfalls and be able to develop cleaner, more maintainable projects.&lt;/p&gt;

&lt;p&gt;I hope this article was helpful and gave you some tips on how to use Git well and avoid common problems. If you have any questions, comments, or ideas for improvement, feel free to share them in the comments. And if you liked this article, don't forget to share it with your developer friends to help them use Git better.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>motivation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Save time by using array functions in Javascript</title>
      <dc:creator>Patrick Zocli</dc:creator>
      <pubDate>Sun, 29 Jan 2023 08:08:47 +0000</pubDate>
      <link>https://dev.to/patzi275/save-time-by-using-array-functions-in-javascript-e41</link>
      <guid>https://dev.to/patzi275/save-time-by-using-array-functions-in-javascript-e41</guid>
      <description>&lt;p&gt;Array transformation functions are valuable tools for Javascript developers. They allow us to easily manipulate the elements of an array and transform them according to our needs. In this article, we will explore three of these functions: &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt;, talk about a juicy javascript skill called piping and finally talk about when to use these functions or not for optimal performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The functions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Map
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;map()&lt;/code&gt; function allows to transform each element of an array into another one by executing a function on each element. This function is passed as a parameter and takes as arguments three parameters, the last two of which are optional: the current value, the current index and the original array.&lt;/p&gt;

&lt;p&gt;Here is how to use &lt;code&gt;map()&lt;/code&gt; :&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&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="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to execute on each element &lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say we have an array of characters with their life level and attack power :&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;characters&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mario&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Luigi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;        
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Peach&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;    
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Toad&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;     
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bowser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&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;We want to display a list of characters with their life/attack ratio (i.e. their life divided by their attack). We can use &lt;code&gt;map()&lt;/code&gt; to transform the array of characters into an array of ratios:&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="c1"&gt;// Define the transformation function that calculates the life/attack ratio for each character  &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ratioLifeAttack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   

&lt;span class="c1"&gt;// Use the map() method on the characters array by passing it the transformation function &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ratios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ratioLifeAttack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ratios&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// display [2, 1.5, 1.1428571428571428, 0.875, 0.6666666666666666]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;map()&lt;/code&gt; function traverses each character in the &lt;code&gt;characters&lt;/code&gt; array and calculates its life/attack ratio using the &lt;code&gt;life/attack ratio()&lt;/code&gt; transformation function. The result is a new &lt;code&gt;ratios&lt;/code&gt; array containing the ratios for each character. Here we don't need the other arguments, i.e. the current index and the array being analyzed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Filter
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;filter()&lt;/code&gt; function allows to select the elements of an array that satisfy a given condition. It goes through each element of the array and performs a function on each of them. If the function returns &lt;code&gt;true&lt;/code&gt; for an element, then &lt;code&gt;filter()&lt;/code&gt; adds it to its new array. Otherwise, the element is ignored.&lt;/p&gt;

&lt;p&gt;It is used in the following way:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&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="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;// code to execute on each element &lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go back to our character example. This time we want to get a list of characters that have a life/attack ratio greater than 1. We can use &lt;code&gt;filter()&lt;/code&gt; to select these characters :&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="c1"&gt;// Define the filter function that checks if the life/attack ratio is greater than 1 &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ratioSuperiorAUn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attack&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="c1"&gt;// Use the filter() method on the characters array by passing it the filter function &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charactersFilters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ratioSuperiorAny&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;charactersFilters&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// display [{ name: "Mario", life: 100, attack: 50 }, { name: "Peach", life: 80, attack: 70 }]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our function goes through each character in the &lt;code&gt;characters&lt;/code&gt; array and checks if their life/attack ratio is greater than 1 using the &lt;code&gt;ratioSuperiorAUn()&lt;/code&gt; filter function. In case the function returns &lt;code&gt;false&lt;/code&gt;, the element is ignored and in case it is not, the element is added to the new array. The result is a new array &lt;code&gt;charactersFilters&lt;/code&gt; containing the characters that have a life/attack ratio greater than 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduce
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;reduce()&lt;/code&gt; function allows to reduce an array to a single value by executing a function on each element. This function is passed as a parameter and takes as arguments four parameters: the accumulator (which is initialized with the initial value or the first value of the array), the current value, the current index and the original array.&lt;/p&gt;

&lt;p&gt;It is used as follows:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&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="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;// code to execute on each element &lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;initialvalue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's consider our character example again. Assuming this time that we want to calculate the sum of all the characters' life levels, we can use &lt;code&gt;reduce()&lt;/code&gt; in the following way:&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="c1"&gt;// Define the reduce function that calculates the sum of the life levels&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sumLife&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;accumulator&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Use the reduce() method on the characters array by passing it the sumLife function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lifeTotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lifeSum&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sumLife&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// display 400&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On each element of the array, &lt;code&gt;reduce()&lt;/code&gt; executes the reduce function &lt;code&gt;sumLives()&lt;/code&gt; which takes as arguments the accumulator (which is initialized with the initial value 0) and the current value (which is the current element of the array).&lt;/p&gt;

&lt;p&gt;On the first iteration, the accumulator is 0 and the current value is the first element of the array, which is &lt;code&gt;{ name: "Mario", life: 100, attack: 50 }&lt;/code&gt;. The reduce function then adds the value of &lt;code&gt;life&lt;/code&gt; of the current element to the accumulator and updates its value with the result, giving &lt;code&gt;accumulator = 0 + 100 = 100&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On the second iteration, the accumulator is now 100 and the current value is the second element of the array, which is &lt;code&gt;{ name: "Luigi", life: 90, attack: 60 }&lt;/code&gt;. The reduce function again adds the value of &lt;code&gt;life&lt;/code&gt; of the current element to the accumulator and updates its value with the result, so &lt;code&gt;accumulator = 100 + 90 = 190&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This operation is repeated for each element of the array until all elements have been processed. When all the elements of the array have been processed, the accumulator contains the sum of all the characters' life levels, which is 400 in our example. The final value of the accumulator is then returned by the &lt;code&gt;reduce()&lt;/code&gt; function as the final result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced data processing with the pipe
&lt;/h2&gt;

&lt;p&gt;Among all the features offered by JavaScript, the pipe is probably one of my favorites. This technique of combining array transformation functions allows us to process data in a more complex way and solve complex problems in an efficient way. With the pipe, we can chain multiple transformation functions together in sequence and use the result of each function as input for the next. It's an incredibly powerful and convenient feature that you'll definitely love.&lt;/p&gt;

&lt;p&gt;Here is an example of a pipe using the &lt;code&gt;map()&lt;/code&gt; and &lt;code&gt;filter()&lt;/code&gt; functions:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;characters&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mario&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Luigi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Peach&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Toad&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bowser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// The transformation function "ratioLifeAttack" calculates the life/attack ratio for each character&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ratioLifeAttack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// The filter function "filterRatioHigh" keeps only the characters with a life/attack ratio higher than 1&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterHighRatio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ratioLifeAttack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// We chain the functions "ratioLifeAttack" and "filterRatioHigh" using the pipe&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charactersFilters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ratioLifeAttack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filterHighRatio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;charactersFilters&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// display [{ name: "Mario", life: 100, attack: 50 }, { name: "Peach", life: 80, attack: 70 }]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we created a transformation function &lt;code&gt;LifeAttackRatio&lt;/code&gt; that calculates the life/attack ratio for each character, as well as a filter function &lt;code&gt;HighRatioFilter&lt;/code&gt; that keeps only characters with a life/attack ratio greater than 1. Using the pipe, we chained these two functions together so that we first calculated the life/attack ratio for each character, and then kept only characters with a high ratio. The final result is an array containing only Mario and Peach, who have a life/attack ratio higher than 1.&lt;/p&gt;

&lt;p&gt;It is also possible to combine the &lt;code&gt;reduce()&lt;/code&gt; function with other transformation functions. For example, we can use the pipe to calculate the average of all the characters' life/attack ratios:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;characters&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mario&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Luigi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Peach&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Toad&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bowser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// The transformation function "ratioLifeAttack" calculates the life/attack ratio for each character&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ratioLifeAttack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;character&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// The reduction function "sumRatios" calculates the sum of all the ratios passed as input&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sumRatios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// We chain the functions "ratioLifeAttack", "reduce" and "sumRatios" using the pipe&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;averageRatios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ratioLifeAttack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sumRatios&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="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;characters&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;averageRatios&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// display 1.1428571428571428&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we first transformed each element of the table into its life/attack ratio, then reduced all these ratios into a single value: the sum of all ratios. Finally, we divided this sum by the number of characters to get the average of these ratios.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is important to note that the pipe is not a native JavaScript function, but rather a programming technique that consists of chaining several functions together in order to process data in a more complex way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are various ways to implement a pipe in JavaScript code, but the most common technique is to use the &lt;code&gt;map()&lt;/code&gt;, &lt;code&gt;filter()&lt;/code&gt; and &lt;code&gt;reduce()&lt;/code&gt; function chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's talk about performance
&lt;/h2&gt;

&lt;p&gt;It is important to consider performance when using these functions. Indeed, although they are very convenient and simplify the code a lot, they can be slightly slower than classical loops combined with &lt;code&gt;if&lt;/code&gt; conditions. However, this performance difference is usually negligible for reasonable array sizes. In case you are working with very large arrays, it may be better to use a classic loop to optimize the performance of your code.&lt;/p&gt;

&lt;p&gt;It is also important to note that these functions are very efficient in terms of memory, because they do not create new arrays at each iteration as a classical loop would. Instead, they use the same original array and simply change the values of its elements. This reduces memory usage and improves the performance of your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Array transformation functions are powerful and efficient tools for processing data in Javascript. They allow us to easily transform the elements of an array according to our needs, without using loops or complex conditions. We have seen how to use &lt;code&gt;map()&lt;/code&gt;, &lt;code&gt;filter()&lt;/code&gt; and &lt;code&gt;reduce()&lt;/code&gt; to perform operations on array elements, but there are other array transformation functions such as &lt;code&gt;sort()&lt;/code&gt;, &lt;code&gt;every()&lt;/code&gt;, &lt;code&gt;some()&lt;/code&gt;, and other. It is important to choose the function that best suits your needs to avoid overloading your code and improve its performance.&lt;/p&gt;




&lt;p&gt;Did you like this article? Share it with your friends and enemies (you never know, maybe they need to make up with you). And if you have any questions or comments, don't hesitate to send them to me. I love to talk tech. And if you run out of ideas you can always leave me a little feedback, we never get enough.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Patzi275/examples-code/blob/main/array_functions.js" rel="noopener noreferrer"&gt;Click here to access the code&lt;/a&gt;&lt;/p&gt;

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