<?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: FatimaZahra.Dev</title>
    <description>The latest articles on DEV Community by FatimaZahra.Dev (@j85219826star).</description>
    <link>https://dev.to/j85219826star</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%2F3964853%2Ff01b1088-25f3-432d-a8c4-09c03001f4c6.jpeg</url>
      <title>DEV Community: FatimaZahra.Dev</title>
      <link>https://dev.to/j85219826star</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/j85219826star"/>
    <language>en</language>
    <item>
      <title>How to Handle Secure File Uploads in Node.js and Express Without Memory Bloat:</title>
      <dc:creator>FatimaZahra.Dev</dc:creator>
      <pubDate>Tue, 02 Jun 2026 14:48:51 +0000</pubDate>
      <link>https://dev.to/j85219826star/how-to-handle-secure-file-uploads-in-nodejs-and-express-without-memory-bloat-294i</link>
      <guid>https://dev.to/j85219826star/how-to-handle-secure-file-uploads-in-nodejs-and-express-without-memory-bloat-294i</guid>
      <description>&lt;p&gt;Handling image and file uploads is a core feature of almost every modern web application, especially e-commerce prototypes and dashboards. However, many developers make the mistake of reading entire uploaded files directly into server RAM. If multiple users upload large images simultaneously, your Node.js backend can quickly run out of memory and crash.&lt;/p&gt;

&lt;p&gt;The Problem&lt;br&gt;
Standard file handlers often cache the incoming file buffers completely in memory before writing them to the disk. For a production server, this creates a major bottleneck and leaves your application vulnerable to Denial of Service (DoS) attacks via massive file streams.&lt;/p&gt;

&lt;p&gt;The Solution: Stream-Based Uploads with Multer&lt;br&gt;
By utilizing multer with its diskStorage engine, we can stream files directly to our local directory as they arrive. This ensures that Node.js maintains a tiny memory footprint regardless of whether the file is 10 Kilobytes or 10 Megabytes.&lt;/p&gt;

&lt;p&gt;JavaScript&lt;br&gt;
const express = require('express');&lt;br&gt;
const multer = require('multer');&lt;br&gt;
const path = require('path');&lt;/p&gt;

&lt;p&gt;const app = express();&lt;br&gt;
const PORT = 5000;&lt;/p&gt;

&lt;p&gt;// 1. Configure storage destination and custom file naming&lt;br&gt;
const storage = multer.diskStorage({&lt;br&gt;
  destination: (req, file, cb) =&amp;gt; {&lt;br&gt;
    cb(null, 'uploads/'); // Make sure this folder exists in your project root&lt;br&gt;
  },&lt;br&gt;
  filename: (req, file, cb) =&amp;gt; {&lt;br&gt;
    // Generate a unique suffix using timestamps to avoid overwriting files&lt;br&gt;
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);&lt;br&gt;
    cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));&lt;br&gt;
  }&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// 2. Define strict file filters for security&lt;br&gt;
const fileFilter = (req, file, cb) =&amp;gt; {&lt;br&gt;
  const allowedTypes = /jpeg|jpg|png|webp/;&lt;br&gt;
  const isExtensionValid = allowedTypes.test(path.extname(file.originalname).toLowerCase());&lt;br&gt;
  const isMIMEValid = allowedTypes.test(file.mimetype);&lt;/p&gt;

&lt;p&gt;if (isExtensionValid &amp;amp;&amp;amp; isMIMEValid) {&lt;br&gt;
    return cb(null, true);&lt;br&gt;
  } else {&lt;br&gt;
    cb(new Error('Security Error: Only JPEG, JPG, PNG, and WEBP images are allowed!'));&lt;br&gt;
  }&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;// 3. Initialize multer with strict size limits (Max: 2MB)&lt;br&gt;
const upload = multer({&lt;br&gt;
  storage: storage,&lt;br&gt;
  fileFilter: fileFilter,&lt;br&gt;
  limits: { fileSize: 2 * 1024 * 1024 } // 2MB limit protects your server storage&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// 4. The Upload Endpoint Route&lt;br&gt;
app.post('/api/upload', upload.single('productImage'), (req, file, res) =&amp;gt; {&lt;br&gt;
  try {&lt;br&gt;
    if (!req.file) {&lt;br&gt;
      return res.status(400).json({ success: false, message: 'No file uploaded.' });&lt;br&gt;
    }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File successfully saved via stream processing
res.status(200).json({
  success: true,
  message: 'Image uploaded successfully!',
  filePath: req.file.path
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;} catch (error) {&lt;br&gt;
    res.status(500).json({ success: false, error: error.message });&lt;br&gt;
  }&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// Global Error Handler for Multer limits&lt;br&gt;
app.use((err, req, res, next) =&amp;gt; {&lt;br&gt;
  if (err instanceof multer.MulterError) {&lt;br&gt;
    return res.status(400).json({ success: false, message: &lt;code&gt;Upload error: ${err.message}&lt;/code&gt; });&lt;br&gt;
  }&lt;br&gt;
  if (err) {&lt;br&gt;
    return res.status(400).json({ success: false, message: err.message });&lt;br&gt;
  }&lt;br&gt;
  next();&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;app.listen(PORT, () =&amp;gt; console.log(&lt;code&gt;Backend server running on port ${PORT}&lt;/code&gt;));&lt;br&gt;
Why This Architecture is Production-Ready&lt;br&gt;
Zero-Bloat Disk Streams: multer.diskStorage streams chunks of binary data directly onto the server hard drive instead of gathering the whole file in the V8 engine memory heap first.&lt;/p&gt;

&lt;p&gt;Double-Layer Validation: Checking both the file extension and the browser-reported mimetype prevents attackers from disguising malicious executable scripts as harmless images.&lt;/p&gt;

&lt;p&gt;Proactive Buffer Control: Setting a hard limit of 2MB inside the limits object ensures that the upload process terminates immediately if a file exceeds the budget, saving your network bandwidth.&lt;/p&gt;

&lt;p&gt;Custom Naming Conventions: Combining the current timestamp with a randomized math string ensures that if two users upload an image named avatar.png at the exact same moment, neither file will get overwritten or lost.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>performance</category>
      <category>security</category>
    </item>
    <item>
      <title>How to Create a Dynamic Shopping Cart Total with React useMemo:</title>
      <dc:creator>FatimaZahra.Dev</dc:creator>
      <pubDate>Tue, 02 Jun 2026 14:45:51 +0000</pubDate>
      <link>https://dev.to/j85219826star/how-to-create-a-dynamic-shopping-cart-total-with-react-usememo-4mc2</link>
      <guid>https://dev.to/j85219826star/how-to-create-a-dynamic-shopping-cart-total-with-react-usememo-4mc2</guid>
      <description>&lt;p&gt;Recalculating a shopping cart total on every single page re-render can drastically slow down a React application as the cart grows or as the user interacts with other UI elements. If your component re-renders because of a sidebar toggle or a theme switch, React will completely rebuild that array calculation from scratch, wasting valuable processing power.&lt;/p&gt;

&lt;p&gt;The Solution&lt;br&gt;
By using the useMemo hook, we can tell React to cache (or memoize) the computed total value. The application will only recalculate the total price when the actual items inside the cart change, keeping your e-commerce frontend incredibly fast and responsive.&lt;/p&gt;

&lt;p&gt;JavaScript&lt;br&gt;
import React, { useState, useMemo } from 'react';&lt;/p&gt;

&lt;p&gt;const ShoppingCart = () =&amp;gt; {&lt;br&gt;
  // Sample cart state containing items from our e-commerce catalog&lt;br&gt;
  const [cart, setCart] = useState([&lt;br&gt;
    { id: 1, name: 'Premium Blue Hoodie', price: 45, quantity: 1 },&lt;br&gt;
    { id: 2, name: 'Dark Green Minimalist Watch', price: 120, quantity: 1 },&lt;br&gt;
  ]);&lt;/p&gt;

&lt;p&gt;// useMemo ensures this calculation only runs when the 'cart' array changes&lt;br&gt;
  const cartTotal = useMemo(() =&amp;gt; {&lt;br&gt;
    console.log('Calculating total...'); // This runs only when items change!&lt;br&gt;
    return cart.reduce((total, item) =&amp;gt; total + (item.price * item.quantity), 0);&lt;br&gt;
  }, [cart]);&lt;/p&gt;

&lt;p&gt;return (&lt;br&gt;
    &lt;/p&gt;
&lt;br&gt;
      &lt;h2&gt;Your Shopping Cart&lt;/h2&gt;
&lt;br&gt;
      &lt;ul&gt;

        {cart.map(item =&amp;gt; (
          &lt;li&gt;

            &lt;strong&gt;{item.name}&lt;/strong&gt; 
            Price: ${item.price} | Qty: {item.quantity}
          &lt;/li&gt;

        ))}
      &lt;/ul&gt;
&lt;br&gt;
      
&lt;br&gt;
      &lt;h3&gt;Total Price: ${cartTotal}&lt;/h3&gt;
&lt;br&gt;
    &lt;br&gt;
  );&lt;br&gt;
};

&lt;p&gt;export default ShoppingCart;&lt;br&gt;
How It Works Under the Hood&lt;br&gt;
The Array Reduce Method: Inside the hook, cart.reduce() loops through our items, multiplies each price by its quantity, and adds them up to create a single, clean total number.&lt;/p&gt;

&lt;p&gt;The Dependency Array: The [cart] at the very bottom is the critical trigger. It acts as a guard, telling React to completely skip this calculation on incoming re-renders unless the cart data itself is modified.&lt;/p&gt;

&lt;p&gt;Performance Optimization: By caching the result, if a user clicks other buttons on your e-commerce page that trigger re-renders, React instantly grabs the saved number instead of looping through the array again.&lt;/p&gt;

&lt;p&gt;Cleaner UI Performance: This simple hook prevents layout lag, ensuring that your shopping cart remains seamless and ultra-fast even when handling hundreds of products.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>performance</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
