Please help to add a smoth slider [closed]

so i cant add smoth slider, i have a slider and it’s working good but i need it to work with swipe too, chatgpt and copilot are not helping so please help me,my js knowledge is not good

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Галерея фильмов</title>
    <link rel="stylesheet" href="style.css">
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            overflow-x: hidden;
        }
        
        .slider-container {
            position: relative;
            /* width: 100%; */
            overflow: hidden;
            max-width: 100%; /* 3 x 240px например */
            margin: 0 auto;
            overflow: hidden;
            scroll-behavior: smooth;
            cursor: grab;
        }
        .slider-container:active {
        cursor: grabbing;
      }

        .slider-track {
        display: flex;
        /* gap: 0; Убирает промежутки между элементами */
        transition: transform 0.3s ease-in-out;
        cursor: pointer;
        width: max-content;
    }

    .slide {
        /* flex: 0 0 calc(100% / 3); Показывать 3 изображения одновременно */
        box-sizing: border-box;
        padding: 0; /* Убираем внутренние отступы */
        margin: 0; /* Убираем внешние отступы */
        text-align: center;
        flex: 0 0 220px; /* фиксированная ширина */
        text-align: center;
    }

    .slide img {
        width: 200px;
        height: 120px;
        margin: 0; /* Убираем отступы вокруг изображений */
        border-radius: 13px;
    }

        .slider-buttons {
            position: absolute;
            top: 50%;
            width: 100%;
            display: flex;
            justify-content: space-between;
            transform: translateY(-50%);
        }

        .slider-buttons button {
            border: none;
            padding: 10px 20px;
            cursor: pointer;
            width: 50px;
            height: 50px;
            margin-top: -45px;
            background-color: none;
            color: none;
            background: none;
        }

        .slider-buttons button:hover {
            /* background-color: rgba(190, 190, 190, 0.8); */
        }
        .slider-buttons button img {
            width: 50px;
            height: 50px;
            margin-top: -45px;
            background-color: none;
            color: none;
            margin-left: -28px;
            margin-top: -14px;

        }
    </style>
</head>
<body>
    <div class="slider-container">
        <div class="slider-track">
            <div class="slide">
                <img src="img/a1.jpg" alt="img1">
                <h5>Թթենի 1980</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img2">
                <h5>Фильм 2</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img3">
                <h5>Фильм 3</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img4">
                <h5>Фильм 4</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img5">
                <h5>Фильм 5</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img6">
                <h5>Фильм 6</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img7">
                <h5>Фильм 7</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img8">
                <h5>Фильм 8</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img9">
                <h5>Фильм 9</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img10">
                <h5>Фильм 10</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img11">
                <h5>Фильм 11</h5>
            </div>
            <div class="slide">
                <img src="img/a1.jpg" alt="img12">
                <h5>Фильм 12</h5>
            </div>
        </div>
        <div class="slider-buttons">
            <button id="prev"><img src="img/left.png" alt="left"></button>
            <button id="next"><img src="img/right.png" alt="right"></button>
        </div>
    </div>

    <script>
        const track = document.querySelector('.slider-track');
        const slides = Array.from(track.children);
        const prevButton = document.getElementById('prev');
        const nextButton = document.getElementById('next');
    
        let currentIndex = 0;
        const slidesToShow = 3; // Количество видимых слайдов
        const slideWidth = slides[0].getBoundingClientRect().width;
        let startX = 0;
        let currentTranslate = 0;
        let prevTranslate = 0;
        let animationID = 0;
        let isDragging = false;
    
        function updateSliderPosition() {
            track.style.transition = 'transform 0.3s ease-in-out';
            track.style.transform = `translateX(-${currentIndex * slideWidth}px)`;
        }
    
        function setSliderPosition() {
            track.style.transition = 'none';
            track.style.transform = `translateX(${currentTranslate}px)`;
        }
    
        function animation() {
            setSliderPosition();
            if (isDragging) requestAnimationFrame(animation);
        }
    
        nextButton.addEventListener('click', () => {
            if (currentIndex < slides.length - slidesToShow) {
                currentIndex++;
                updateSliderPosition();
            }
        });
    
        prevButton.addEventListener('click', () => {
            if (currentIndex > 0) {
                currentIndex--;
                updateSliderPosition();
            }
        });
    
        // Mouse and touch events
        track.addEventListener('mousedown', startDrag);
        track.addEventListener('touchstart', startDrag);
    
        track.addEventListener('mousemove', drag);
        track.addEventListener('touchmove', drag);
    
        track.addEventListener('mouseup', endDrag);
        track.addEventListener('touchend', endDrag);
    
        track.addEventListener('mouseleave', () => {
            if (isDragging) endDrag();
        });
    
        function startDrag(e) {
            isDragging = true;
            startX = getPositionX(e);
            prevTranslate = currentTranslate;
            animationID = requestAnimationFrame(animation);
    
            // Убираем переход, чтобы не было задержки при перетаскивании
            track.style.transition = 'none';
        }
    
        function drag(e) {
            if (!isDragging) return;
            const currentPosition = getPositionX(e);
            currentTranslate = prevTranslate + currentPosition - startX;
    
            // Ограничение перемещения
            const maxTranslate = -(slides.length - slidesToShow) * slideWidth;
            if (currentTranslate > 0) {
                currentTranslate = 0;
            } else if (currentTranslate < maxTranslate) {
                currentTranslate = maxTranslate;
            }
        }
    
        function endDrag() {
            isDragging = false;
            cancelAnimationFrame(animationID);
    
            const movedBy = currentTranslate - prevTranslate;
    
            if (movedBy < -slideWidth / 4 && currentIndex < slides.length - slidesToShow) {
                currentIndex++;
            }
    
            if (movedBy > slideWidth / 4 && currentIndex > 0) {
                currentIndex--;
            }
    
            updateSliderPosition();
        }
    
        function getPositionX(e) {
            return e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
        }
    
        window.addEventListener('resize', () => {
            updateSliderPosition();
        });
    </script>
</body>
</html>

i need it to be smooth swipe,like when i grab it it need to allow me to swipe what positioon i want it to be, and when i drop it it stop to work,i hope you understand i am bad at explaining

i tried chatgpt and copilot but they didin’t help

Can you use Ionic Angular Capacitor with Angular SSR?

I just started implementing Angular SSR with Angular Ionic Capacitor. However I am becoming skeptic if this even works, after running into some issues like:

ERROR ReferenceError: window is not defined
    at impl (./node_modules/@capacitor/preferences/dist/esm/web.js:59:9)
    at <anonymous> (./node_modules/@capacitor/preferences/dist/esm/web.js:13:28)
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:3:1)
    at _next (./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:22:1)
    at executor (./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:27:1)
    at constructor (./node_modules/zone.js/fesm2015/zone-node.js:1385:25)
    at <anonymous> (./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:19:1)
    at get (./node_modules/@capacitor/preferences/dist/esm/web.js:14:26)
    at impl (./node_modules/@capacitor/core/dist/index.js:197:35)

And even more skpetic after reading answers like this one:

“I don’t think Ionic Angular & SSR are a great fit. There are some
older posts here including responses from the team. So I don’t think
that will be resolved soon

Seeing the same when trying to integrate with SvelteKit. So, have to
disable ssr.”

So now my question is, if the two are compatible in general and if anyone managed to combine the two, without issues like the one with the preferences plugin above.

input text change avatar

I have a chat where the user changes their avatar using a library, but it overwrites the name and changes the gif to a static image.

I thought of adding an input so that the user can change their avatar by uploading it to another page and changing it using the URL, like this:

<input type="text" class="upload-image" name="avatar" value="{{USER.avatar_url}}">

The problem here is that I don’t know how to proceed so that the URL is saved and the avatar is changed. My English is not good enough so I’ll use google translate, hopefully someone will understand and help.

<input type="file" class="upload-image" name="avatar" value="Upload Photo">
// profile image upload
$(document).on("change", ".upload-image", function() {
  var uploadFile = $(this);
  var files = !!this.files ? this.files : [];#

  if (!files.length || !window.FileReader) return; // no file selected, or no FileReader support

  if (/^image/.test(files[0].type)) { // only image file
    var reader = new FileReader(); // instance of the FileReader
    reader.readAsDataURL(files[0]); // read the local file
    reader.onloadend = function() { // set image data as background of div
      uploadFile.closest(".imgUp").find('img').remove();
      uploadFile.closest(".imgUp").find('.imagePreview').css("background-image", "url(" + this.result + ")");
    }
  }
});

How to integrate a custom search option with dynamic filelds using CodeIgniter 4 master data listing UI?

Can anyone suggest a best way for integrating search/filter options for master data UI ?

I have around 20 fields/columns to search. I do not want to show 20 separate fields for this. Instead I want to provide a common field for choosing the search column and another field for entering the value.

I am not using any grid libraries for the table data listing.

I am using codeIgniter4 with MySQL in the backend and jQuery in the frontend side.

It will be a great help if someone can suggest a suitable method.

Instant response of the Like/Dislike buttons using Alpine.js in Livewire 3

I have logic for like/dislike button in two separate livewire components (LikeButton.php/DislikeButton.php)

The problem is I want like/dislike buttons react immediately after clicking

Currently, button looks like this:

<div>
    <button wire:click="toggleLike()">Like recipe</button>
    {{ $recipe->countLikes() }}
</div>

And now after clicking I need to wait and If my user will have slow internet he’ll be waiting more way longer.

LikeButton.php:

class LikeButton extends Component
{
    public Recipe $recipe;

    public function toggleLike()
    {
        $this->dispatch('refresh-dislikes');

        // Check if user is authenticated
        // if so, get the user
        if (! $user = auth()->user()){
            return $this->redirect(route('login-page'));
        }

        // Check if user has already liked recipe
        // if true, then return unlike()
        $hasLiked = $user->likes()->where([
            'recipe_id' => $this->recipe->id,
            'liked' => true
        ])->exists();

        if ($hasLiked){
            return $this->recipe->unlikeBy($user);
        }

        // return like()
        return $this->recipe->likeBy($user);
    }

    #[On('refresh-likes')]
    public function render()
    {
        return view('livewire.like-button');
    }
}

Is there any solution to fix it by using Alpine.js?

Reading from firestore in PHP not working with non-GRPC Firebase client

I’m using this firestore client that doesnt require GRPC and it is made by bensontrent
GITHUB REPO: https://github.com/bensontrent/firestore-php

The problem I have is that my index.php is not working and I think I initialized the firebase client correctly, I am logging the errors in a file but there is no error showing up in the file and I get this errors only in the website when i load it.

HTTP ERROR 500
This page isn’t working
e-barter.x10.bz is currently unable to handle this request.

I tried initializing the firebase like this, just how the repo documentation said:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/error_log.txt'); // Log errors to a file
// Database connection
require 'db_connect.php';

require '../vendor/autoload.php';

use bensontrentfirestore-phpFirestoreClient;

// Initialize variables with default values
$topRanked = $topRated = $topPosters = [];
$totalUsers = $totalItems = 0;
$recentItems = [];

try {
    // Initialize Firestore client
    $firestore = new FirestoreClient(
        'ebarter-f3229',
        'AIzaSyB2rf5zxpvwUc7U8UZZ3TqujAycg62av8Q', (here in the API key, I'm not sure if its the firebase webapi key or i need to generate another key in the google cloud???)
        ['database' => '(default)']
    );

this is the queries i’m trying to do:

// Function to calculate user rankings
    function calculateUserRankings($firestore) {
        $userStats = [];
        
        try {
            // Get all users
            $users = $firestore->listDocuments('users');
            foreach ($users as $userDoc) {
                $userId = $userDoc->id();
                $userData = $userDoc->data();
                
                $userStats[$userId] = [
                    'fullName' => $userData['fullName'] ?? 'Anonymous',
                    'postedItemsCount' => 0,
                    'completedTradesCount' => 0,
                    'totalRatings' => 0,
                    'sumRatings' => 0,
                    'averageRating' => 0,
                    'totalScore' => 0
                ];
            }
            
            // Get items
            $items = $firestore->listDocuments('items');
            foreach ($items as $item) {
                $itemData = $item->data();
                $userId = $itemData['userId'] ?? '';
                if ($userId && isset($userStats[$userId])) {
                    $userStats[$userId]['postedItemsCount']++;
                }
            }
            
            // Get completed trades
            $completedTrades = $firestore->query('barterOffers')
                ->where('status', '=', 'completed')
                ->get();
                
            foreach ($completedTrades as $trade) {
                $tradeData = $trade->data();
                $itemOwnerId = $tradeData['itemOwnerId'] ?? '';
                $likerId = $tradeData['likerId'] ?? '';
                
                if ($itemOwnerId && isset($userStats[$itemOwnerId])) {
                    $userStats[$itemOwnerId]['completedTradesCount']++;
                }
                if ($likerId && isset($userStats[$likerId])) {
                    $userStats[$likerId]['completedTradesCount']++;
                }
            }
            
            // Get ratings
            $ratings = $firestore->listDocuments('ratings');
            foreach ($ratings as $rating) {
                $ratingData = $rating->data();
                $ratedUserId = $ratingData['ratedUserId'] ?? '';
                $ratingValue = $ratingData['rating'] ?? 0;
                
                if ($ratedUserId && isset($userStats[$ratedUserId])) {
                    $userStats[$ratedUserId]['totalRatings']++;
                    $userStats[$ratedUserId]['sumRatings'] += $ratingValue;
                }
            }
            
            // Calculate scores
            foreach ($userStats as $userId => &$stats) {
                if ($stats['totalRatings'] > 0) {
                    $stats['averageRating'] = $stats['sumRatings'] / $stats['totalRatings'];
                }
                
                $ratingScore = $stats['averageRating'] * 2 * $stats['totalRatings'];
                $tradesBonus = min($stats['completedTradesCount'], 10);
                $itemsBonus = min($stats['postedItemsCount'] * 0.5, 10);
                $stats['totalScore'] = (int) round($ratingScore + $tradesBonus + $itemsBonus);
            }
            
            // Sort and return results
            $topRanked = $userStats;
            usort($topRanked, fn($a, $b) => $b['totalScore'] <=> $a['totalScore']);
            
            $topRated = $userStats;
            usort($topRated, fn($a, $b) => 
                $b['averageRating'] <=> $a['averageRating'] ?: 
                $b['totalRatings'] <=> $a['totalRatings']);
            
            $topPosters = $userStats;
            usort($topPosters, fn($a, $b) => $b['postedItemsCount'] <=> $a['postedItemsCount']);
            
            return [
                'topRanked' => array_slice($topRanked, 0, 5),
                'topRated' => array_slice($topRated, 0, 5),
                'topPosters' => array_slice($topPosters, 0, 5)
            ];
            
        } catch (Exception $e) {
            error_log("Firestore Query Error: " . $e->getMessage());
            return ['topRanked' => [], 'topRated' => [], 'topPosters' => []];
        }
    }

    // Get rankings
    $rankings = calculateUserRankings($firestore);
    $topRanked = $rankings['topRanked'];
    $topRated = $rankings['topRated'];
    $topPosters = $rankings['topPosters'];

} catch (Exception $e) {
    error_log("Firestore Init Error: " . $e->getMessage());
}

// Get database counts (this is from my domain's database and not part of firebase)
try {
    $userCountResult = $conn->query("SELECT COUNT(*) as total_users FROM users");
    $totalUsers = $userCountResult ? $userCountResult->fetch_assoc()['total_users'] : 0;
    
    $itemCountResult = $conn->query("SELECT COUNT(*) as total_items FROM items");
    $totalItems = $itemCountResult ? $itemCountResult->fetch_assoc()['total_items'] : 0;
    
    $itemsResult = $conn->query("SELECT i.*, u.username, u.city FROM items i JOIN users u ON i.userId = u.userId ORDER BY i.created_at DESC LIMIT 12");
    $recentItems = $itemsResult ? $itemsResult->fetch_all(MYSQLI_ASSOC) : [];
    
} catch (Exception $e) {
    error_log("MAIN ERROR: " . $e->getMessage());
    // Display user-friendly error message
    die("<div class='alert alert-danger'>An error occurred while loading the page. Please try again later. Technical details have been logged.</div>");
}
?>

Error before a $_Post is sent to the mysql query [duplicate]

I have the following code for a multiple dropdown menu, which takes the data from mysql database, then depending on the choice, displays a another dropdown menu.

I have done this with php, javascript and MySQL.

The problem I come across is that the first time I load the page I get the error that the array, that comes from $_Post, is not created. Such array enables the mysql query and following chart to appear.

The error is:
“Warning: Undefined array key “titulos” … “

After I do one submission with the dropdown menu, everything works fine.

How can I create a default result for this variable?

Dropdown menu and Chart Query

<form style="text-align:center;margin-top:2%;" name="myform" action="" method="post"><select style="font-size:16px;" name="magazines"   onclick="getSeries(this.value)">
    <option value="">Choose a Magazine</option>
    <?php
        $magazines = getMagazines();
        foreach($magazines as $magazine){
               <option value="<?php echo $magazine['magazine_code'] ?>">
              <?php echo $magazine['Magazine_name']?></option>
    <?php
    }
    ?>
    </select>
    <select style="font-size:16px;" name="titulos">
    <option value="">Choose a Series</option>
    </select>
    <input style="font-size:16px;" value="Send"  type="submit">


     $series_tit =$_POST['titulos'];
     $query = "SELECT * FROM chartdata WHERE Serie_name = '$series_tit'";

PHP functions

function getMagazines(){
    $conn = databaseConnection();
    $res = $conn->query("SELECT * FROM categorias");
    while($row = $res->fetch_assoc()){
        $data[] = $row;
    }
    return $data;


}

if(isset($_GET["magazine_code"])){
echo getSeries($_GET["magazine_code"]);
}

function getSeries($magazine_code){
$conn = databaseConnection();
if(!$conn){
return false;
}
$magazine_code = htmlspecialchars($magazine_code);
$res = $conn->query("SELECT * FROM chartdata WHERE magazine_code ='$magazine_code'");
while($row = $res->fetch_assoc()){
$data[] = $row;
}
return json_encode($data);

}

And Javascript

function getSeries(magazineCode){
    let seriesDropDown = document.forms["myform"].titulos;

    if (magazineCode.trim() === ""){
        seriesDropDown.disabled = true;
        seriesDropDown.selectedIndex = 0;
        return false;
    }

    fetch(`functions_sales.php?magazine_code=${magazineCode}`)
    .then (response => response.json())
    .then(function(series){
        let out = "";
        out += `<option value="">Choose a Series</option>`;
        for (let sery of series){
            out += `<option value="${sery['Serie_name']}">${sery['Serie_name']}</option>`;
        }
        seriesDropDown.innerHTML = out;
        seriesDropDown.disabled = false;


    });

}

I’ve tried making a selected option into the form but the response continue being the same.

Is there a way to check if an animation is playing on an SVG

I have an issue with an SVG that shows an ugly default state prior to the anim starting.

I had hoped I could set the visibility of the SVG to hidden then check the SVG anim status is playing using js or css and set the visibility to visible.

Unfortunately I have no idea how to do this and I’m struggling to find any helpful documentation.

How to traverse between children of transportationOptions in json? [closed]

This is my JSON

"location" : {
    "address" : "St Katharine's & Wapping",
    "coordinates" : {
      "latitude" : 51.5081,
      "longitude" : -0.0759
    },
    "city" : "London",
    "country" : "United Kingdom",
    "neighborhood" : "Tower Hamlets",
    "transportationOptions" : "[{"_children":{"type":{"_value":"tube"},"details":{"_value":"Tower Hill Station (District and Circle lines)"},"distance":{"_value":"0.3"}},"_nodeFactory":{"_cfgBigDecimalExact":false}},{"_children":{"type":{"_value":"river"},"details":{"_value":"Tower Pier (Thames Clipper)"},"distance":{"_value":"0.1"}},"_nodeFactory":{"_cfgBigDecimalExact":false}}]"
  }
} 

This code is returning undefined, so how do I loop through to print???

const jsonString = JSON.stringify(location);
//console.log(jsonString);

//To convert a JSON string to a JavaScript object, use JSON.parse() method
const parsedJSONObject = JSON.parse(jsonString);
console.log(parsedJSONObject.location);

document.getElementById("address").innerHTML      =   parsedJSONObject.location.address;
document.getElementById("city").innerHTML         =   parsedJSONObject.location.city;
document.getElementById("country").innerHTML      =   parsedJSONObject.location.country;
document.getElementById("neighborhood").innerHTML =   parsedJSONObject.location.neighborhood;

//coordinates
document.getElementById("latitude").innerHTML     =   parsedJSONObject.location.coordinates.latitude;
document.getElementById("longitude").innerHTML    =   parsedJSONObject.location.coordinates.longitude;

//Transportation options
console.log(parsedJSONObject.location.TransportationOptions.children[1].nodeValue);

Google Apps Script isn’t appending paragraphs / tables and is throwing an error that document cannot be found

I am trying to build a quote generator where data is taken from a spreadsheet and put into a document. Multiple items may be chosen, so I want to put one page per spreadsheet item. Therefore I was trying to copy elements from a template document to a new document then change the text. However, no matter which method I try the paragraphs / tables are not appended, and the final message in Apps Script is “Document is missing (perhaps it was deleted, or you don’t have read access?).” No other information, no line noted, nothing.
I’ve tried using SWTICH() and IF() chains and neither work.

function test() {
  const tempDoc = DocumentApp.openById(<ID_1>).getBody();
  const newDoc = DocumentApp.openById(<ID_2>);

  let numEl = tempDoc.getNumChildren();
  let outBody = newDoc.getBody();

  console.log(outBody);

  let el, type;
  for (let j = 0; j < numEl; j++) {
    el = tempDoc.getChild(j).copy();
    type = el.getType();

    switch (type) {
      case DocumentApp.ElementType.PARAGRAPH:
        outBody.appendParagraph(el.asParagraph());
        break;
      case DocumentApp.ElementType.TABLE:
        outBody.appendTable(el.asTable());
        break;
      default:
        console.log("end");
        break;
    }
  }
}

How do I use trim with Vietnamese [closed]

I have a list with Vietnamese words which have some whitespace in front and the back, e.g.: quá .

I’m trying to use the trim function to remove all the whitespace.
Expected result should be quá. But in fact the result is qu only.

I’ve also tested with some other words ending with á and the same problem occurs:

  • " Lá ".trim() => return L;
  • " Má ".trim() => return M

Is this error of this function or I miss something?

console.log("   quá   ".trim());

Is there a way we can get a unique primitive for a given unique object in JavaScript?

This question appears to have been asked 8 years ago, but I’m hoping things have changed since then.

Is there a unique identifier for an object in javascript?

I have a situation relating to data caching/memoization, (specifically using the graphql/dataloader) library where I’ve got some code like this:

const request = new Request('http://example.com'); 
const someObject = {}; 

function myFunction() {

    const result = someOtherFunction({
         request, 
         someObject
    });
    console.log(result); 
}

function myFunction2() {

    const result = someOtherFunction({
         request, 
         someObject
    }, () => {
      return "xyz"; 
    });
    
    console.log(result); 
}


const memoMap = new Map(); 
function someOtherFunction(args, cacheKeyFn) {

    const key = cacheKeyFn ? cacheKeyFn(args) : args; 
    const existingResult = memoMap.get(key); 
    if(existingResult){
        return existingResult; 
    }

    const value = Math.random(); 
    memoMap.set(key, value); 
    return value; 
}

console.log("myFunction"); 
myFunction();
myFunction();
myFunction();
console.log("myFunction2");
myFunction2();
myFunction2();
myFunction2();

The purpose of this someOtherFunction is to memoize the result of this call. However, it determines uniques of the function parameters by shallow compare.

So in this case, although both request and someObject will be the same objects in the repeated calls of myFunction, I’m declaring a new object when I pass them into someOtherFunction and so the result is not memoized.

someOtherFunction does accept a cacheKeyFn, which we can use generate uniqueness another way.

So I’m looking for a way I can create a single primitive, such as a string, from multiple multiple objects.

The best I’ve got is something like this:

const weakMap = new WeakMap(); 
let weakMapCounter = 0; 
function getKeyForUniqueObject(value) {
   if(weakMap.has(value)) {
        return weakMap.get(value); 
   }
   
   const key = `unique-key-for-object-${weakMapCounter++}`; 
   weakMap.set(value, key); 
   return key; 
}


const req = new Request("https://example.com"); 
const obj1 = {}; 
const obj2 = {}; 

console.log(getKeyForUniqueObject(req));
console.log(getKeyForUniqueObject(obj1));
console.log(getKeyForUniqueObject(obj2));
console.log(getKeyForUniqueObject(req));

The use of WeakMap means that I don’t need to worry about the object’s presence in the map preventing its garbage collection.

Is there a much nicer way to do this?

I’ve looked at:

  • Symbol. Both the Symbol constructor, and Symbol.for. But they don’t do what I want.

Zod validation for array of objects

assuming there’s a form with a repeater component so there could be 1, 2, or any number of subforms, like a form of vehicles that could have many vehicles defined.
I want to generate a schema to validate each vehicles’ data.
Issue is that 1 field is mandatory boolean, 2nd field is optional string.

currently generated schema is:

validator = function (formData, validationContext) {
    return Zod.z.object({
        'vehicles': Zod.z.array(Zod.z.object({
            'garageAddressSameAsMailingAddress': Zod.z.boolean().nullish(),
            'garageAddress': Zod.validateIfVisible(Zod.z.any().nullish().refine((value) => {
                if (Zod.evaluateFeel('it.garageAddressSameAsMailingAddress != true', validationContext) === true) {
                    return Zod.z.object({
                        'value': Zod.z.any(),
                        'label': Zod.z.string(),
                        'optionLabel': Zod.z.string().nullish()
                    }).strict().safeParse(value).success
                } else {
                    return true
                }
            }, {message: '$validation_text.mandatory$'}), 'not((it.garageAddressSameAsMailingAddress = true))', validationContext, "$validation_text.field_not_visible$", "$validation_text.feel_not_executable$"),
        }))
    }).strict().safeParse(formData);
}

formData structure:

{
“vehicles” : {garageAddressSameAsMailingAddress: Boolean, garageAddress: String?}[]
}

validationContext is a superset of formData containing more data which is irrelevant

I have tried to use superRefine as well, but failed – the main challenge is having kind of iterator or a reference to the current vehicle object that is being evaluated.

Invalid hook call error in production but working in development

I would like to ask. I am using react ^18.3.1 and also react-redux ^9.2.0 for my project. After deploying the project to production, I am getting some “hooks” error as follows:

useFilterByPermission.js:5 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

useFilterByPermission.js:5 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

chunk-I773Y2XN.js?v=2aedf8be:1062 Uncaught TypeError: Cannot read properties of null (reading 'useContext')
    at useFilterByPermission (useFilterByPermission.js:5:27)
    at AppointmentCalendar (AppointmentCalendar.jsx:20:29)
useFilterByPermission.js:5 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

useFilterByPermission.js:5 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

chunk-I773Y2XN.js?v=2aedf8be:1062 Uncaught TypeError: Cannot read properties of null (reading 'useContext')
    at useFilterByPermission (useFilterByPermission.js:5:27)
    at AppointmentCalendar (AppointmentCalendar.jsx:20:29)

I created a custom hook that uses useSelector fromRedux:

useFilterByPermission.js

import { useSelector } from "react-redux";

const useFilterByPermission = () => {
  const { currentUser } = useSelector((state) => state.auth);

  const hasPermission = (permission) => {
    return currentUser?.permissions?.includes(permission);
  };

  const filterItemsByPermission = (items) => {
    return items.filter(
      (item) => !item.permission || hasPermission(item.permission)
    );
  };

  return { hasPermission, filterItemsByPermission };
};

export default useFilterByPermission;

And I am calling the custom hooks inside a React Component:

import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
// import getIcon from "@/utils/getIcon";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from "@fullcalendar/interaction";
import { useDispatch, useSelector } from "react-redux";
import { fetchAllAppointments } from "@/store/slice/appointmentSlice";
import { format } from "date-fns";
import { PERMISSIONS } from "../../../shared/permissionsConstant";
import useFilterByPermission from "@/hooks/useFilterByPermission";

const AppointmentCalendar = () => {
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const { appointments } = useSelector((state) => state.appointments)
  const { hasPermission } = useFilterByPermission();

  useEffect(() => {
    dispatch(fetchAllAppointments())
  }, [])
  return (
    <>
      {hasPermission(PERMISSIONS.APPOINTMENTS.VIEW) &&
              <div className="card">
                <div className="card-body">
                  <div className="card-body custom-card-action p-0">
                    <FullCalendar
                      height={'auto'}
                      plugins={[timeGridPlugin, dayGridPlugin, interactionPlugin]}
                      initialView="timeGridDay"
                      eventDisplay="auto"
                      firstDay={1}
                      hiddenDays={[7]}
                      eventMaxStack={1}
                      slotMinTime={"10:00:00"}
                      eventClick={(info) => navigate(`/appointments/${info.event.id}`)}
                      eventTimeFormat={{
                        hour: 'numeric',
                        minute: '2-digit',
                        hour12: false,
                      }}
                      eventBackgroundColor="red"
                      headerToolbar={{
                        left: 'prev,next',
                        center: 'title',
                        right: 'timeGridDay,timeGridWeek,dayGridMonth'
                      }}
                      events={appointments.map(item => ({
                        id: item.id,
                        title: item.title,
                        start: `${format(item.appointmentDate, 'yyyy-MM-dd')} ${item.appointmentTime.split(' - ')[0]}`,
                        end: `${format(item.appointmentDate, 'yyyy-MM-dd')} ${item.appointmentTime.split(' - ')[1]}`,
                      }))}
                  />
              </div>
          </div>
      </div>}
    </>
  );
};

export default AppointmentCalendar;

As what I have read, I think I am not breaking the React hooks rules but I keep on getting this error.