What is the equivalent of Array(N).keys().map for Apple products (Safari/iPhones)? [duplicate]

I’m trying to get a list of incremental numbers from N to (N + M) and using Array(M).keys().map(num => num + N) to do so. This works fine on:

  • Windows Chrome
  • Windows Edge
  • Mac Chrome

But I receive a TypeError: Arror(3).keys().map is not a function error on:

  • iPhone Chrome, Safari, and the Inspect Browser app.
  • Mac Safari

Why is it not defined, and what would be an equivalent call?

In the console, Array(n).keys() produces a Array Iterator which holds the array prototype (which defines map), so I’m confused what’s happening on certain Apple products.

Can I prevent Axios from making more than 1 total requests if that first request fails with 401?

My Axios instance has a response interceptor which emits an event if the response is 401 status code, and then I have a listener that executes a function, however my problem is that there are situations where multiple requests are being sent and my listener executes the function more than 1 times because I get multiple 401s in a row.

I’m trying to figure out if there’s a clean way to make sure that Axios stops making requests after the first 401 status code and then resume after my listener function has finished executing.

My interceptor’s error handler looks like this:

async (err) => {
            if (err.response.status === 401) Doorman.lock();

            return Promise.reject(err);
}

How do I refine a webapp’s HTML and JS to work properly? [closed]

I am using a template-driven Node.js drawing webapp, which I have gotten up and running insofar as it presents the app via HTML. However, there are dropdown boxes that don’t dropdown and selecting a tool and trying to draw does nothing. First, here is a snippet of the HTML that drives the toolbar:

<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
    <li class="nav-item">
        <button type="button" class="btn btn-lg btn-light" v-on:click="diagram.clear()" aria-label="clean button">
            <i class="far fa-file"></i>
        </button>
        <button type="button" v-bind:class="{ btn: true, 'btn-lg': true, 'btn-light': true, disabled: !hasUndo }"
                v-on:click="diagram.undo()" aria-label="undo button">
            <i class="fas fa-undo"></i>
        </button>
        <button type="button" v-bind:class="{ btn: true, 'btn-lg': true, 'btn-light': true, disabled: !hasRedo }"
                v-on:click="diagram.redo()" aria-label="redo button">
            <i class="fas fa-redo"></i>
        </button>
        <button type="button" class="btn btn-lg btn-light" v-on:click="zoomIn" aria-label="zoom in button">
            <i class="fas fa-search-plus"></i>
        </button>
        <button type="button" class="btn btn-lg btn-light" v-on:click="zoomOut" aria-label="zoom out button">
            <i class="fas fa-search-minus"></i>
        </button>
        <button type="button" class="btn btn-lg btn-light" v-on:click="tools.pen" aria-label="pen">
            <i class="fas fa-pen"></i>
        </button>
        <button type="button" class="btn btn-lg btn-light" v-on:click="tools.eraser" aria-label="eraser">
            <i class="fas fa-eraser"></i>
        </button>
    </li>
    <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" id="navbarDropdown0" role="button" data-toggle="dropdown" aria-label="line color selector">
            <span class="toolbox selected" v-bind:style="{ 'tool-color': color }"></span>
        </a>
        <div class="dropdown-menu">
            <a v-for="c in colors" v-bind:class="{ active: c === color, 'dropdown-item': true }"
               v-on:click.prevent="color = c" href="#">
                <span class="toolbox" v-bind:style="{ 'tool-color': c }"></span>
            </a>
        </div>
    </li>
    <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" id="navbarDropdown1" role="button" data-toggle="dropdown" aria-label="line style selector">
            <span class="toolbox selected" v-bind:style="{ 'tool-width': width }"></span>
        </a>
        <div class="dropdown-menu">
            <a v-for="w in widths" v-bind:class="{ active: w === width, 'dropdown-item': true }"
               v-on:click.prevent="width = w" href="#">
                <span class="toolbox" v-bind:style="{'tool-width': width}"></span>
            </a>
        </div>
    </li>
</ul>
<form id="uploadForm" method="post" enctype="multipart/form-data">
    <input id="file-selector" v-on:change="upload" type="file" name="file" hidden>
</form>

Where I want to select the tool (pen), color, and line width. I can click the pen, but the color and width dropdowns don’t do anything. Clicking the pen and then trying to draw does nothing, either. The code JS code to create the pen is:

async function initialize() {
let tools = {
    pen: {
        start: (x, y) => [x, y],
        move: (x, y, d) => { d.push(x, y); return [x, y] },
        draw: (b, d) => b.pen(d),
        update: (e, d) => e.plot(d)
    },
    eraser: {
        start: (x, y) => [x, y],
        move: (x, y, d) => { d.push(x, y); return [x, y] },
        draw: (b, d) => b.eraser(d),
        update: (e, d) => e.plot(d)
    }
}

Any ideas on what I am doing wrong? I did make several changes from the template, but the template itself didn’t work.

Example:

async function initialize() {
  let tools = {
    pen: {
      start: (x, y) => [x, y],
      move: (x, y, d) => {
        d.push(x, y)
        return [x, y]
      },
      draw: (b, d) => b.pen(d),
      update: (e, d) => e.plot(d),
    },
    eraser: {
      start: (x, y) => [x, y],
      move: (x, y, d) => {
        d.push(x, y)
        return [x, y]
      },
      draw: (b, d) => b.eraser(d),
      update: (e, d) => e.plot(d),
    },
  }
}
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
    <li class="nav-item">
        <button type="button" class="btn btn-lg btn-light" v-on:click="diagram.clear()" aria-label="clean button">
            <i class="far fa-file"></i>
        </button>
        <button type="button" v-bind:class="{ btn: true, 'btn-lg': true, 'btn-light': true, disabled: !hasUndo }"
                v-on:click="diagram.undo()" aria-label="undo button">
            <i class="fas fa-undo"></i>
        </button>
        <button type="button" v-bind:class="{ btn: true, 'btn-lg': true, 'btn-light': true, disabled: !hasRedo }"
                v-on:click="diagram.redo()" aria-label="redo button">
            <i class="fas fa-redo"></i>
        </button>
        <button type="button" class="btn btn-lg btn-light" v-on:click="zoomIn" aria-label="zoom in button">
            <i class="fas fa-search-plus"></i>
        </button>
        <button type="button" class="btn btn-lg btn-light" v-on:click="zoomOut" aria-label="zoom out button">
            <i class="fas fa-search-minus"></i>
        </button>
        <button type="button" class="btn btn-lg btn-light" v-on:click="tools.pen" aria-label="pen">
            <i class="fas fa-pen"></i>
        </button>
        <button type="button" class="btn btn-lg btn-light" v-on:click="tools.eraser" aria-label="eraser">
            <i class="fas fa-eraser"></i>
        </button>
    </li>
    <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" id="navbarDropdown0" role="button" data-toggle="dropdown" aria-label="line color selector">
            <span class="toolbox selected" v-bind:style="{ 'tool-color': color }"></span>
        </a>
        <div class="dropdown-menu">
            <a v-for="c in colors" v-bind:class="{ active: c === color, 'dropdown-item': true }"
               v-on:click.prevent="color = c" href="#">
                <span class="toolbox" v-bind:style="{ 'tool-color': c }"></span>
            </a>
        </div>
    </li>
    <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" id="navbarDropdown1" role="button" data-toggle="dropdown" aria-label="line style selector">
            <span class="toolbox selected" v-bind:style="{ 'tool-width': width }"></span>
        </a>
        <div class="dropdown-menu">
            <a v-for="w in widths" v-bind:class="{ active: w === width, 'dropdown-item': true }"
               v-on:click.prevent="width = w" href="#">
                <span class="toolbox" v-bind:style="{'tool-width': width}"></span>
            </a>
        </div>
    </li>
</ul>
<form id="uploadForm" method="post" enctype="multipart/form-data">
    <input id="file-selector" v-on:change="upload" type="file" name="file" hidden>
</form>

Next.js upon URL rewrite in middleware.ts text chunk stream is got all at once in client

With proxy rewrite able to retrieve non-stream data as expected,

middleware.ts

const targetUrl = "https://www.externalapi.com/stream-text-data"
    if (pathname.startsWith("/proxy") {
      return NextResponse.rewrite(
        new URL(
          `${targetUrl}${pathname.replace("/proxy", "")}`,
          req.url
        ),
        {
          request: { headers: req.headers },
        }
      );

in the client,

chat.tsx

    "use client"
    const _response: any = await fetch(
      "/proxy/stream-text-data",
      _options
    ).catch((error) => {
      setIsLoading(false);
      setError(error);
    });
    while (loopRunner) {
      try {  
        const { value, done } = await reader?.read();
        if (done) { 
          loopRunner = false; 
          break;
        } else {
          const decodedChunk = decoder.decode(value, { stream: true }); 
          setStreaming(decodedChunk);
        }
      } catch (error) { 
         setError(error);
        break;
      }
    }

streaming works seamlessly (chunk by chunk text receptance from external api) only if direct uri (targetURI) is used in fetch, if proxy is used and if url rewrite happens at middleware.ts api is getting all stream of text chunks at once only at the end of response after a latency.

Please help understand what is missing and how to fix this . thanks!

Interface Extend Issue with storybook react Material UI

Note
Simple Code in the end if anyone wishes to skip the actual problem faced and just focus on the issue

Problem Statement

Working on Storybook components and trying to reuse the MUI TextField, facing problem with creating own custom props that are extended from MUI Text field props

Actual Code

3 Primary files in the project

TextFieldConstants.ts

import { BaseTextFieldProps, TextFieldProps } from "@mui/material/TextField";

export interface CustomTextFieldProps extends BaseTextFieldProps {
    textFieldType: string;
    showDescription?: boolean;
    showLeadingIcon?: boolean,
    showTrailingIcon?: boolean,
}

export const TextFieldTypeOptions: {[key:string] : string} = {
    TextField: "TextField",
    LargeTextField: "LargeTextField",
    EmptyStateHelpText: "EmptyStateHelpText"
}

TextField.ts

import TextField from '@mui/material/TextField';
import { styled } from '@mui/material';
import { TextFieldTypeOptions, CustomTextFieldProps } from "./TextFieldConstants";

const StyledCustomTextField = styled(TextField)({
   
})

const CustomTextField = ({textFieldType, showDescription, ...props}: CustomTextFieldProps) => {
    console.log(props);
    return ( 
        <StyledCustomTextField
            {...props}
            sx={
                textFieldType === TextFieldTypeOptions.EmptyStateHelpText ?
                {
                    "& .MuiOutlinedInput-root" : {
                        "& fieldset" : {
                            border: "none"
                        }
                    }
                } :
                {}
            }
            defaultValue={props.defaultValue}
            helperText={showDescription ? props.helperText : ""}
        />
     );
}
 
export default CustomTextField;

TextFieldStories.tsx

import { useState } from 'react';
import CustomTextField from './TextField';
import { TextFieldTypeOptions, CustomTextFieldProps } from './TextFieldConstants';

const meta = {
    title: "DLSCOMPONENTS/TextField",
    tags: ["autodocs"],
    component: CustomTextField,
    argTypes: {
        textFieldType: {
            control: {type: "select"},
            options: Object.values(TextFieldTypeOptions),
            description: "type of the text field"
        },
        defaultValue: {
            control: {type: "text"},
            description: "Value to show for uncontrolled component"
        },
        showDescription: {
            control: {type: "boolean"},
            description: "Shows helper text if true"
        }
    }
}

export const EmptyStateHelpText = {
    args: {
        textFieldType: TextFieldTypeOptions.EmptyStateHelpText,
        defaultValue: "Title Help Text",
        helperText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore",
        showDescription: true
    }
}

export const TextField = {
    args: {
        textFieldType: TextFieldTypeOptions.TextField,
        showLeadingIcon: false,
        showTrailingIcon: false,
    },
    render: (args: CustomTextFieldProps) => {
        const [value, setValue] = useState("Default");

        const handleChange = (event) => {
            setValue(event.target.value);
        }
        return (
            <CustomTextField {...args} value={value} onChange={handleChange} /> 
        )
    }
}

export default meta;

Error Faced

getting below error on onChange

Type '{ value: string; onChange: (event: any) => void; textFieldType: string; showDescription?: boolean; autoComplete?: string; autoFocus?: boolean; children?: ReactNode; classes?: Partial<TextFieldClasses>; ... 288 more ...; component?: ElementType<...>; }' is not assignable to type 'IntrinsicAttributes & CustomTextFieldProps'.
  Property 'onChange' does not exist on type 'IntrinsicAttributes & CustomTextFieldProps'.ts(2322)

Analysis and Requirement

I understand onChange and other event handlers are declared on derived interfaces and probably need to extend from either of the 3 (StandardTextFieldProps, FilledTextFieldProps, OutlinedTextFieldProps – refer textfield.d.ts for more info) but my primary aim was to extend the functionality of MUI textfield, so basically take all coming from MUI and add own props in it

Note
New to storybook, please also share how the prop types are usually handled here and any other insights in the code if possible

Simple Code for the crux of the problem

import TextField, { BaseTextFieldProps, TextFieldProps } from "@mui/material/TextField";

export interface CustomTextFieldProps extends BaseTextFieldProps {
    textFieldType: string;
    showDescription?: boolean
}

const CustomTextField = ({textFieldType, showDescription, ...props}: CustomTextFieldProps) => {
    return ( 
        <TextField
            {...props}
            defaultValue={props.defaultValue}
            helperText={showDescription ? props.helperText : ""}
        />
     );
}

export const NewComponent = () => {
    
    const handleChange = () => {
        console.log('handle Change')
    }

    return (
        <CustomTextField 
            onChange={handleChange}
        /> 
    )
}
 
export default CustomTextField;

postMessage to iFrame not working through GTM

I’m facing a strange situation. I wrote a code which should send a variable to an iFrame embedded on my page through postMessage().

The parent-page is: “https://www.bestcars.com (example)
The iFrame-page is: “https://info.bestcars.com (example)

I triggered the following code in GTM when the parent-page is loaded:

(function(window) {
     var checkIframe = setInterval(function() {
         var iframe = document.querySelector('.p-form-content'); 
         var urlobject = "Hello";
         iframe.contentWindow.postMessage(urlobject, 'https://info.bestcars.com');
         clearInterval(checkIframe);
      }, 100); 
})(window);

But, that doesn’t work. The console shows the error-message:

VM1359:1 Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘https://info.bestcars.com’) does not match the recipient window’s origin (‘https://www.bestcars.com’).

The strange thing: it works when I’m executing the same code on the same page through the console in Chrome.

Can you help?

Thanks,

Copy to clipboard in production does not work, it works when running app locally [duplicate]

I have built a dynamic web app. As a feature, I have implemented a copy to clipboard functionality. It works when I run the app locally on my machine. However, when deployed on a linux server, it does not work. I get this error in the browser dev tools:

Uncaught TypeError: Cannot read properties of undefined (reading 'writeText')

I know what it means, it cannot get the number from my database. I have no clue why it works locally and not on the Linux server.
I am using the MERN stack. The database is on mognodb atlas. I start the app on the Linux server with pm2 start index.js
Nginx error logs does not show anything when running tail -f /var/log/nginx/error.log
Here is the link to the app:
http://188.166.66.226/
Let me know if I shall provide some code from the app.

Google Maps Places API: Is there a form to retrieve many places based in placeId using a single query?

I’m getting a list of places using service.getDetails(placeId), but this forces me to do a query for each placeId. The Google docs don’t clearly explain if there’s an option to get a list of places based on placeIds, but it doesn’t seem very functional to do a query per place.

Is there an option for that? Or am I doomed to sacrifice the performance of my app?

JQuery UI not showing tooltip (serializing toop tip not working)

I have used Jquery UI before and tooltips without issue… this time for some reason I cant get them to work. I am trying to get a tooltip to show on only 1 element if the mouse is hovered over it. The < head > is:

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.14.1/themes/smoothness/jquery-ui.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.14.1/jquery-ui.min.js"></script>
    <script>
  $("#barracks").tooltip({disabled:true});
    $(document).click(function() {
        if($("#barracks").tooltip("option", "disabled")) {
            $("#barracks").tooltip("enable");
            $("#barracks").tooltip("open");
            $("#barracks").off("mouseleave focusout");
        } else {
            $("#barracks").tooltip("close");
            $("#barracks").tooltip("disable");
        }
    });
    </script>

and in the < body >:

                <div class="col-lg-2 col-md-2 col-xs-2 thumb"> 
                    <img src="https://www. domain .com/adminp/occur/assets/img/soldier.jpg" id="barracks" class="img-thumbnail img-fluid rounded float-start max-width: 100%;" alt="infantry" title="Infantry">
                </div>
                <div class="col-lg-2 col-md-2 col-xs-2 thumb">
                    <img src="https://www. domain .com/adminp/occur/assets/img/gunner.jpg" id="barracks" class="img-thumbnail img-fluid rounded mx-auto d-block max-width: 100%;" alt="gunner" title="Gunner">                                 
                </div>
                <div class="col-lg-2 col-md-2 col-xs-2 thumb">
                    <img src="https://www. domain .com/adminp/occur/assets/img/pilot.jpg" id="barracks" class="img-thumbnail img-fluid rounded mx-auto d-block max-width: 100%;" alt="pilot" title="Pilot">                                 
                </div>                        
                <div class="col-lg-2 col-md-2 col-xs-2 thumb">
                    <img src="https://www. domain .com/adminp/occur/assets/img/astronaut.jpg" id="barracks" class="img-thumbnail img-fluid rounded float-end max-width: 100%;" alt="astronaut" title="Astronaut">    
                </div>

The Infrantry tooltip works, but not the other 3.. no tooltip displaying

Chart.js Streaming Plugin in FilamentPHP: Error: “realtime” is not a registered scale

I’m trying to integrate the chartjs-plugin-streaming plugin with Chart.js in a Laravel project using FilamentPHP for real-time data visualization. My goal is to use the realtime scale provided by chartjs-plugin-streaming in a Filament ChartWidget, but the scale isn’t recognized, and I’m not seeing any streaming updates.

Here’s a summary of my setup and what I’ve tried so far:

  1. Installed the streaming plugin: npm install chartjs-plugin-streaming --save

  2. Configured filament-chart-js-plugins.js: resources/js/filament-chart-js-plugins.js:

import ChartPluginZoom from 'chartjs-plugin-zoom';
import ChartPluginStreaming from 'chartjs-plugin-streaming';

window.filamentChartJsPlugins ??= [];
window.filamentChartJsPlugins.push(ChartPluginZoom);
window.filamentChartJsPlugins.push(ChartPluginStreaming);
  1. Updated vite.config.js to include filament-chart-js-plugins.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
                'resources/css/filament/admin/theme.css',
                'resources/js/filament-chart-js-plugins.js', // Ensuring the plugins file is built
            ],
        }),
    ],
});
  1. Registered the custom asset in Filament: AppServiceProvider.php
FilamentAsset::register([
    Js::make('chart-js-plugins', Vite::asset('resources/js/filament-chart-js-plugins.js'))->module(),
]);
  1. Ran commands:
npm run build
php artisan filament:assets

After performing all the above steps, the plugin doesn’t seem to work correctly: Error: “realtime” is not a registered scale.

If I disable the Streaming Plugin, the Zoom Plugin work’s fine.

My Widget Code for Reference:

protected function getOptions(): RawJs
    {
        return RawJs::make(
            <<<JS
            {
                responsive: true,
                plugins: {
                    title: {
                        display: true,
                    },
                    subtitle: {
                        display: false,
                    },
                    description: {
                        display: false,
                    },
                    legend: {
                        display: true,
                    },
                    zoom: {
                        pan: {
                            enabled: true,
                            mode: 'x',
                        },
                        zoom: {
                            wheel: {
                                enabled: true,
                            },
                            drag: {
                                enabled: false,
                            },
                            pinch: {
                                enabled: true,
                            },
                            mode: 'x',
                            onZoomComplete({chart}) {
                                chart.update('none');
                            }
                        }
                    },                    
                },
                scales: {
                    x: {
                        type: 'realtime',
                        realtime: {
                            delay: 2000,
                            refresh: 1000,
                            delay: 2000,
                            onRefresh: chart => {
                                console.log('Done');
                            }
                        },
                    },
                    y: {
                        type: 'linear',
                        display: true,
                        position: 'left',
                        beginAtZero: true,
                        max: 200,
                    },
                },

            }
            JS
        );
    }

Javascript dual slider: don’t let the right slider push the left one

I have a simple dual slider as seen below.

The left slider can not push the right slider any more to the right as intended, but the right slider pushes the left slider to the left and I don’t know how to prevent this.

What am I missing?

      // Elements for the sliders and display
      const minSlider = document.getElementById("minL");
      const maxSlider = document.getElementById("maxL");
      const rangeDisplay = document.getElementById("rangeDisplay");

      // Update the display and enforce slider constraints
      function updateSliders() {
        let minL = parseInt(minSlider.value);
        let maxL = parseInt(maxSlider.value);

        // Prevent the minSlider from exceeding maxSlider's value
        if (minL > maxL) {
          minSlider.value = maxL;
          minL = maxL;
        }

        // Update the displayed range
        rangeDisplay.textContent = `${minL} - ${maxL}`;
      }

      // Attach input event listeners for live updating
      minSlider.addEventListener("input", updateSliders);
      maxSlider.addEventListener("input", updateSliders);

      // Initial display update
      updateSliders();
  .slider-container {
      position: relative;
      width: 100%;
      max-width: 400px;
      height: 20px;
  }

  #minL, #maxL {
      position: absolute;
      width: 100%;
      pointer-events: none;
  }

  #minL::-webkit-slider-thumb, #maxL::-webkit-slider-thumb {
      pointer-events: auto;
      height: 18px;
      width: 18px;
      background-color: #333;
      cursor: pointer;
  }
    <div id="controls">
      <label>Range: <span id="rangeDisplay">0 - 70</span></label>
      <div class="slider-container">
        <input type="range" id="minL" min="0" max="360" value="0" step="1">
        <input type="range" id="maxL" min="0" max="360" value="70" step="1">
      </div>
    </div>
  </body>
</html>

How to know if there are any deleted keys in Knouckout’s observableKeySet?

self.Items = new keySet.ObservableKeySet();
self.Items.addAll();
Now if any key is deleted from Items, how can I know that?

self.misc = function() {
            if(self.selectedItems().isAddAll()){
                if(self.selectedItems().keys.seletedKeys.size>0)
                    return true;
            } else {
                return false;
            }
};

Cannot read properties of undefined (reading ‘size’) in expression
I’m getting this error from above function. How to solve this?

Getting redirected to dasboard page from all pages when reloading or pasting the url in the browser with my current route protection setup

When I try to reload any protected page or paste the URL in browser I get redirected to dashboard. I understand from my setup that on reload the isAuthenticated sate is false because of which the protectedRoute component redirects to login page and when the user state is finally set from localstorage the publicRoute component wrapping login page redirects to dashboard.

how can I prevent this redirection problem when user is authenticated and still make sure that user can’t visit login pages when he is already authenticated

i have a publicroute component like this which is supposed to prevent a user from visiting login related page when he is already logged in

/* eslint-disable react/jsx-no-useless-fragment */
import { ReactNode, useEffect } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useAppSelector } from '../../redux/hooks';

import { PageLoader } from 'project/spinner';

interface PublicRouteProps {
  children: ReactNode;
}

const PublicRoute: React.FC<PublicRouteProps> = ({ children }) => {
  const navigate = useNavigate();
  const location = useLocation();
  const isAuthenticated = useAppSelector((state) => state.user.isAuthenticated);

  console.log("location.pathname", location.pathname)
  useEffect(() => {
    // Redirect to dashboard or prev page if the user is already authenticated
    if (isAuthenticated) {
      const previousPath = location.state?.from || '/pages/dashboard';
      console.log("****************redirecting to dashboard***************");
      navigate(previousPath, { replace: true });
    }
  }, [isAuthenticated, navigate, location]);

  return !isAuthenticated ? <>{children}</> : <PageLoader />;
};

export default PublicRoute;

and another ProtectedRoute component for protecting routes from unauthenticated users like this

/* eslint-disable react/jsx-no-useless-fragment */
import { ReactNode, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAppSelector } from '../redux/hooks';

import { PageLoader } from 'project/spinner';

interface ProtectedRouteProps {
  children: ReactNode;
}

const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children }) => {
  const navigate = useNavigate();
  const isAuthenticated = useAppSelector((state) => state.user.isAuthenticated);

  console.log('isAuthenticated', isAuthenticated);

  useEffect(() => {
    // Redirect to login if the user is not authenticated
    if (!isAuthenticated) {
      console.log('******************redirecting to login********************');
      navigate('/');
    }
  }, [isAuthenticated, navigate]);

  return isAuthenticated ? <>{children}</> : <PageLoader />;
};

export default ProtectedRoute;

I also have routes setup like this ,where index(“/”) is a login route

const router = createBrowserRouter([
  {
    path: `${import.meta.env.BASE_URL}`,
    element: (
      <Suspense fallback={<PageLoader />}>
        <PublicRoute>
          <Login />
        </PublicRoute>
      </Suspense>
    ),
  },
  {
    path: `${import.meta.env.BASE_URL}/forgot-password`,
    element: (
      <Suspense fallback={<PageLoader />}>
        <PublicRoute>
          <ForgotPassword />
        </PublicRoute>
      </Suspense>
    ),
  },
  {
    path: `${import.meta.env.BASE_URL}/verify-otp`,
    element: (
      <Suspense fallback={<PageLoader />}>
        <PublicRoute>
          <OtpInput />
        </PublicRoute>
      </Suspense>
    ),
  },
  {
    path: `${import.meta.env.BASE_URL}/set-password`,
    element: (
      <Suspense fallback={<DashboardSkeleton />}>
        <SetPassword />
      </Suspense>
    ),
  },
  {
    path: 'pages',
    element: (
      <Suspense fallback={<DashboardSkeleton />}>
        <ProtectedRoute>
          <App />
        </ProtectedRoute>
      </Suspense>
    ),
    errorElement: (
      <Suspense fallback={<DashboardSkeleton />}>
        <ErrorPage />
      </Suspense>
    ),
    children: [/////rest of the routes],
  },
]);

the setup to load user from local storage on app load

//// user state example 
const initialState: UserState = {
  isAuthenticated: false,
  userInfo: undefined,
  currentRole: undefined,
  roles: undefined,
  permissionGroups: undefined,
};

    const AppInitializer = ({ children }: { children: React.ReactNode }) => {
      const dispatch = useAppDispatch();
    
      useEffect(() => {
        dispatch(loadUserFromLocalStorage()); //Load user from local storage and sets the auth and user state
      }, [dispatch]);
    
      return <div>{children}</div>;
    };
    
    const root = ReactDOM.createRoot(
      document.getElementById('root') as HTMLElement
    );
    root.render(
      <StrictMode>
        <Provider store={store}>
          <QueryClientProvider client={queryClient}>
            <AppInitializer>
              <RouterProvider router={router} />
            </AppInitializer>
          </QueryClientProvider>
        </Provider>
      </StrictMode>
    );

Update Livewire property in Javascript code

hello In a Livewire component, I’m going to use the Flowbite tab component by JavaScript code. My problem is that the $requestStandard variable is updated by Livewire and a new tab is created on the page, but the javascript code is not applied to the initial tabs and the new tab does not work. In fact, the livewire hook is executed before the new tab is added to the page. Please guide me what change I need to make in the code so that I can apply the javascript code after inserting the contents of the new tab in the page?
I use Livewire 3.
Component Blade Code:

<div class="mb-10">
    <div class="flex flex-col md:flex-row justify-center md:justify-start items-center mb-3 gap-2">
        <div>Select Cluster:</div>
        <div class="w-full md:w-1/4 flex flex-row items-center">
            <select wire:model.live="cluster" name="cluster" id="cluster"
                    class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                <option value="">Select Cluster</option>
                @if( count($clusters) && isset($clusters[0]['khushecode']) )
                    @foreach($clusters as $c)
                        <option value="{{$c['khushecode']}}">{{$c['khushename']}}</option>
                    @endforeach
                @endif
            </select>
            @if( !count($clusters) )
                <div class="flex flex-row gap-1 mx-2">
                    <a href="#" wire:click="reloadClusters" title="بارگذاری خوشه‌ها">
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
                            <path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"></path>
                            <path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"></path>
                        </svg>
                    </a>
                    <div role="status" wire:loading.delay wire:target="reloadClusters">
                        <svg aria-hidden="true" class="inline w-4 h-4 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
                            <path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/>
                        </svg>
                        <span class="sr-only">Loading...</span>
                    </div>
                </div>
            @endif
        </div>
        <div>Select Group:</div>
        <div class="w-full md:w-1/4 flex flex-row items-center">
            <select wire:model.live="group" name="group" id="group"
                    class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                <option value="">Select Group</option>
                @if($this->cluster && count($groups))
                    @foreach($groups as $g)
                        <option value="{{$g['groupid']}}">{{$g['groupname']}}</option>
                    @endforeach
                @endif
            </select>
            @if( $cluster && !count($groups) )
                <div class="flex flex-row gap-1 mx-2">
                    <a href="#" wire:click="updatedCluster" title="بارگذاری گروه‌ها">
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
                            <path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"></path>
                            <path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"></path>
                        </svg>
                    </a>
                    <div role="status" wire:loading.delay wire:target="reloadGroups">
                        <svg aria-hidden="true" class="inline w-4 h-4 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
                            <path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/>
                        </svg>
                        <span class="sr-only">Loading...</span>
                    </div>
                </div>
            @endif
        </div>
    </div>
    <div class="flex flex-col md:flex-row justify-center md:justify-start items-center mb-3 gap-2">
        <div>Select Standard:</div>
        <div class="w-full md:w-2/3 flex flex-row items-center">
            <select wire:model.live="standard" name="standard" id="standard"
                    class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                <option value="">Select Standard</option>
                @if($this->group && count($standards))
                    @foreach($standards as $s)
                        <option value="{{$s['standardid']}}">{{$s['name']}}</option>
                    @endforeach
                @endif
            </select>
            @if( $group && !count($standards) )
                <div class="flex flex-row gap-1 mx-2">
                    <a href="#" class="text-decoration-none" wire:click="reloadStandards" title="loading standards">
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
                            <path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"></path>
                            <path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"></path>
                        </svg>
                    </a>
                    <div role="status" wire:loading.delay wire:target="updatedGroup">
                        <svg aria-hidden="true" class="inline w-4 h-4 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
                            <path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/>
                        </svg>
                        <span class="sr-only">Loading...</span>
                    </div>
                </div>
            @endif
        </div>
    </div>
    @if( $standard )
        <div class="my-3 p-3 border border-secondary rounded-3 bg-neutral-300/30">
            <div class="mb-3 flex flex-col md:flex-row justify-center md:justify-start">
                <div class="me-4 font-bold">
                    Standard title:
                </div>
                <div>
                    {{$standardInfo['name']}}
                </div>
            </div>
            <div class="mb-3 flex flex-col md:flex-row *:text-center *:md:text-start">
                <div class="pe-4 font-bold">
                    Standard code:
                </div>
                <div class="me-4">
                    {{verta()->enToFaNumbers($standardInfo['ccode'])}}
                </div>
                <div class="pe-4 font-bold">
                    Standard time:
                </div>
                <div class="me-4">
                    {{verta()->enToFaNumbers($standardInfo['jam'])}} Hours
                </div>
            </div>
            <div class="flex justify-center md:justify-start">
                <button wire:click="addStandardToRequest"
                        class="text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg text-sm px-5 py-1.5 me-2 mb-2 dark:bg-purple-600 dark:hover:bg-purple-700 focus:outline-none dark:focus:ring-purple-800">
                    Add Standard
                </button>
            </div>
        </div>
    @endif
<div class="overflow-y-auto max-h-[130px]">
            <ul class="flex flex-wrap" id="tabs-standard" role="tablist">
                @foreach($this->requestStandards as $s)
                    <li class="transition duration-500 ease-in-out rounded-full hover:bg-purple-600 hover:text-purple-50 group text-purple-700"
                         id="standard-{{ $s['standardid'] }}-tab" data-tabs-target="#standard-{{ $s['standardid'] }}"
                         role="tab" aria-controls="standard-{{ $s['standardid'] }}" aria-selected="false">
                        <div class="flex flex-row items-center p-1">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"
                                 wire:click="removeStandardFromRequest('{{ $s['standardid'] }}')" style="cursor: pointer;"
                                 onclick="return confirm('Are you sure?') || event.stopImmediatePropagation()">
                                <title>Delete from list</title>
                                <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/>
                            </svg>
                            <button class="px-1" type="button">
                                <span class="text-truncate d-inline-block align-self-center" style="max-width: 230px;">{{$s['name']}}</span>
                            </button>
                        </div>
                    </li>
                @endforeach
            </ul>
        </div>
        <div class="flex flex-col justify-center md:justify-start py-3">
            @foreach($this->requestStandards as $s)
                <div class="hidden" id="standard-{{ $s['standardid'] }}"
                      role="tabpanel" aria-labelledby="standard-{{ $s['standardid'] }}-tab">
                    <div class="flex-col justify-center border border-gray-500/50 rounded-md p-3 mb-3">
                        <div class="grid gap-4 grid-cols-1 md:grid-cols-3 mb-5">
                            <div>
                                <div class="pe-4 font-bold">
                                    Standard title:
                                </div>
                                <div class="me-4">
                                    {{$s['name']}}
                                </div>
                            </div>
                            <div>
                                <div class="pe-4 font-bold">
                                    Standard code:
                                </div>
                                <div class="me-4">
                                    {{verta()->enToFaNumbers($s['ccode'])}}
                                </div>
                            </div>
                            <div>
                                <div class="pe-4 font-bold">
                                    Standard time:
                                </div>
                                <div class="me-4">
                                    {{verta()->enToFaNumbers($s['jam'])}} Hours
                                </div>
                            </div>
                            <div>
                                <div class="pe-4 font-bold">
                                    Cluster title:
                                </div>
                                <div class="me-4">
                                    {{$s['cluster']}}
                                </div>
                            </div>
                            <div>
                                <div class="pe-4 font-bold">
                                    Group title:
                                </div>
                                <div class="me-4">
                                    {{$s['group']}}
                                </div>
                            </div>
                        </div>
                        <div class="flex justify-center md:justify-end">
                            <button wire:click="removeStandardFromRequest('{{$s['standardid']}}')"
                                    class="bg-red-500 text-white px-5 py-1 rounded-md text-sm"
                                    onclick="return confirm('Are you sure?.') || event.stopImmediatePropagation()">
                                Delete from list
                            </button>
                        </div>
                    </div>
                </div>
            @endforeach
        </div>
    @endif
</div>
@script
<script>
    Livewire.hook('morph.updated', ({ el, component }) => {
        tabElements = [
                @php
                    $item = 0;
                    $first_item = 0;
                @endphp
                @foreach($requestStandards as $s)
                @php
                    if($item == 0) $first_item = $s['standardid'];
                    $item++;
                @endphp

            {
                id: "standard-{{ $s['standardid'] }}",
                triggerEl: document.querySelector("#standard-{{ $s['standardid'] }}-tab"),
                targetEl: document.querySelector("#standard-{{ $s['standardid'] }}"),
            },
            @endforeach

        ];

        tabs = new Tabs(tabsElement, tabElements, options, instanceOptions);
        initFlowbite();
    })
    const tabsElement = document.getElementById('tabs-standard');
    let tabElements = [
        @php
            $item = 0;
            $first_item = 0;
        @endphp
        @foreach($requestStandards as $s)
            @php
                if($item == 0) $first_item = $s['standardid'];
                $item++;
            @endphp

        {
            id: "standard-{{ $s['standardid'] }}",
            triggerEl: document.querySelector("#standard-{{ $s['standardid'] }}-tab"),
            targetEl: document.querySelector("#standard-{{ $s['standardid'] }}"),
        },
        @endforeach

    ];
    const options = {
        defaultTabId: "standard-{{ $first_item }}",
        activeClasses:
            'bg-cyan-600 text-cyan-50',
        inactiveClasses:
            'hover:bg-purple-600 hover:text-purple-50 group text-purple-700',
    };
    const instanceOptions = {
        id: 'tabs-standard',
        override: true
    };
    let tabs = null
    if(tabElements.length)
        tabs = new Tabs(tabsElement, tabElements, options, instanceOptions);

  
</script>
@endscript