How to display msg received in API response on page in ReactJs

i have one function which checks for user authorization

export const authUser = (rideId,action) => {
  return (dispatch, getState) => {
    const postData = {
      consumer: "Rapi",
      classId: rideId,
      action: action,
    };
    return Api.post(
      '/api/xx/yy/auth',
      postData,
    )
    .then((response) => {
      const authorized = response && response.authorized === true;
      if (authorized) {
        console.log("User is authorized");
        return true;
      } else {
        console.warn("User is NOT authorized");
        return false;
      }
    })
    .catch((error) => {
      console.error(" Authorization failed:", error);
      return false;
    });
    
  };
};

if user is authorized to access this particular ride in that case we are getting this below response from API

{"authorized":true} 

if that particular RideId is not available or he is not authorized to access that ride we are getting below response from API

{
    "message": "Ride not found. rideId: RD23435OPSMSK76772",
    "errorCode": "60000",
    "timestamp": "2025-07-02T08:34:57.241+00:00"
}

as of now i am displaying a common message for user not authorized and ride not found error .
But i want to display this particular message which we are receiving from API response.
so when ride Id is not found i am getting above response and catch block is executing.
We are getting response in ride not found case. so then block should get execute.

Please Help. Thanks in Advance

Input checkboxes change value=”wording” dependent on checked unchecked [closed]

I have multiple inputs:

<input type="checkbox" name="t2" id="t2" value="">
<input type="checkbox" name="t3" id="t3" value="">
<input type="checkbox" name="t4" id="t4" value="">

I would like help with the JavaScript code so that when a user checks the input, the individual input values (value=””) become the word “show”, unchecked, it becomes the word “hide”.

Javascript dynamically load Google auto script to header tags: error c is not defined

I need to dynamically load goolge’s new auto complete script to the head tags of a website. This is the new format of the script.

<script>
  (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
    key: "YOUR_API_KEY",
    v: "weekly",
    // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
    // Add other bootstrap parameters as needed, using camel case.
  });
</script>

The previous format was easy to dynamically load:

<script async
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&loading=async&callback=initMap">
</script>

This is how i previously dynamically loaded it

 let mapScript = document.createElement('script');
 mapScript.async = true;
 mapScript.setAttribute('src', 'https://maps.googleapis.com/maps/api/js?key='MY-Key'&loading=async&libraries=places&callback=initMap');

I am not sure how to dynamically load the new style script.

UPDATE:

Following the helpful advice from @biggujo I tried adding it as a textContent but have an error:

 Uncaught ReferenceError: c is not defined

This is how i tried to add it. I used template literals

const newScript = document.createElement('script');

        newScript.textContent = ` (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
    key: "myKey",
    v: "weekly",
    // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
    // Add other bootstrap parameters as needed, using camel case.
  });`


        newScript.onload = () => console.log(`${file} loaded successfully.`);
        newScript.onerror = () => console.error(`Error loading script: ${file}`);

        document.head.appendChild(newScript);

The ‘C’ the error refers to is within the script tag – its encased within another template literals:

;a.src=`https://maps.${c}apis.com/maps/api/js?` 

Javascript dynamically load a script to header tags

I need to dynamically load goolge’s new auto complete script to the head tags of a website. This is the new format of the script.

<script>
  (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
    key: "YOUR_API_KEY",
    v: "weekly",
    // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
    // Add other bootstrap parameters as needed, using camel case.
  });
</script>

The previous format was easy to dynamically load:

<script async
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&loading=async&callback=initMap">
</script>

This is how i previously dynamically loaded it

 let mapScript = document.createElement('script');
 mapScript.async = true;
 mapScript.setAttribute('src', 'https://maps.googleapis.com/maps/api/js?key='MY-Key'&loading=async&libraries=places&callback=initMap');

I am not sure how to dynamically load the new style script.

Script js in Blazor Web Assembly project not updated in web navigator

I am working on a blazor Web Assembly project. This projects contains javascript file. Some of them are located in wwwroot/js. And others are attached to a razor component in a collocated way (MyComponent.razor and MyComponent.razor.js).

In my index.html, my script located in wwwwroot/js are imported as below :
<script src="js/myScript.js?v={APP_VERSION}"></script>

For The js script attached to my razor component, it is invoked inside the component cs code like this :
_module = await JS.InvokeAsync<IJSObjectReference>("import", "./Pages/PathToMyComponent/MyComponent.razor.js");

When I modify these scripts, my web navigator (Edge or Chrome not tested with Firefox) does not take my modifications in account. The old version of my script are still loaded in the web navigator.

I don’t understand why. Thanks for your help

Can’t get fullcalendar events to show up in asp.net app

I have an asp.net app that is using fullcalendar, and I am trying to use the calendar javascript file to call the API endpoint and retrieve the list of events from the database that way, and then use those list of events to populate the calendar.

import { Calendar } from '@fullcalendar/core';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import listPlugin from '@fullcalendar/list';
import { req } from 'superagent';

let eventsArr = [];


document.addEventListener('DOMContentLoaded', function () {
    const calendarEl = document.getElementById('calendar');

    const calendar = new Calendar(calendarEl, {
        plugins: [dayGridPlugin, timeGridPlugin, listPlugin],
        initialView: 'dayGridMonth',
        headerToolbar: {
            left: 'prev, next today',
            center: 'title',
            right: 'dayGridMonth, timeGridWeek, listWeek'
        },
        events: function (fetchInfo, successCallback, failureCallback) {
            fetch('/HealthCareTeams/patientList/1A0B71B3-61E4-4096-B647-70FAE91590DB', {
                headers: {
                    'Accept': 'application/json'
                }
            })
                .then(response => response.json())
                .then(data => successCallback(data))
                .catch(err => failureCallback(err)),
               }

    });

    calendar.render()
});

Here is the controller method:

 [HttpGet("patientList/{patientID}")]
 public async Task<IActionResult> ReturnPatientApptListAsync(Guid patientID)
 {
     var healthCareTeams = await healthCareTeamRepository.ReturnPatientApptListAsync(patientID);

     var calendarEvents = healthCareTeams.Select(hct => new
     {
         title = hct.Specialty ?? "Appoinment",
         start = hct.Appointment.ToString("s")
     });

     return new JsonResult(calendarEvents);
 }

HEre is the repo method:

public async Task<HealthCareTeam[]> ReturnPatientApptListAsync(Guid patientID)
{
    var healthCareTeams = await planMyMDVisitContext.HealthCareTeams.Where(hct => hct.PatientId == patientID).ToArrayAsync();

    return healthCareTeams;
}

Here is the JavaScript part of the cshtml page placing the calendar:

    <div id="calendar-container">
        <div id="calendar"></div>
    </div>
 </div>

<script type="module" src="~/dist/calendar.js"></script>

When I run the app, and place this URL in the browser…..https://localhost:7189/HealthCareTeams/patientList/1A0B71B3-61E4-4096-B647-70FAE91590DB, it is giving me a JSON array of the data contained in the database. I have looked at the console quite a few times, and no errors are showing up in there, and I have also looked at the network tab of chrome, and have seen this error many times:

(failed) net::ERR_BLOCKED_BY_ORB

I have tried to follow chatgpt suggestions to fix this error, including putting in proper CORS code into Program.cs, and that error still keeps popping up. Part of me thinks that’s the issue, part of me is not sure. But I feel like I have hit a wall.

How do I use custom phone number format with react-phone-input-2

I can add phone number in the input field and get the otp successfully. Issue is when I enter the phone number it display like this “+94 712 345 678”. But I want it to display like this “+94 71 234 5678”. I tried many time but couldn’t fix it.
this is the issue picture

Backend get it “+94712345678” and correct. Issue is frontend input field display format.

Here is the full code – Link

This is mobile number field i want to show like this -“+94 71 237 1234”, but showing “+94 712 371 234”. I want when typing number show like above format.

There are lots of codes. So I put a drive link for all the codes (Link). Can you refer it and help me to finish this? As a intern I don’t know how to solve this.

{
          <div className={`${styles.formGroup} ${styles.phone}`}>
            <label htmlFor="mobile">Phone Number</label>
            <PhoneInput
              country={"lk"}
              //value={displayMobile}
              value={formData.mobile}
              onChange={(value) => {
                setFormData((prev) => ({ ...prev, mobile: "+" + value }))
              }}
              /*onChange={(value) => {
                const digitsOnly = value.replace(/D/g, "").slice(0, 9); // max 9 digits
                setFormData((prev) => ({
                  ...prev,
                  mobile: "+94" + digitsOnly,
                }));
              }}*/
              inputProps={{
                name: "mobile",
                required: true,
                autoFocus: false,
                disabled: isLoading || otpSent,
              }}
              inputClass={`${styles.phoneInput} ${
                errors.mobile ? styles.errorInput : ""
              }`}
              containerStyle={{ width: "100%" }}
              /*enableAreaCodes={true}
              enableSearch={true}
              disableCountryCode={false}
              disableDropdown={false}
              autoFormat={true}*/
            />
            {errors.mobile && (
              <span className={styles.errorText}>{errors.mobile}</span>
            )}
          </div>
        }

JavaScript onload and onscroll nuance

Apologies if this has been asked, I couldn’t find it.

I have a JavaScript function that changes a DIV element’s .innerhtml onload. It basically gets JSON and iterates to build the page, and it works great. I also want to run another function after it that creates the player instance of a video player for each video tag that was created during the first onload function that changes .innerhtml.

When the function that finds video tags is run on onload, it doesn’t find any video tags. If I run it on onscroll then it works as expected.

If the document’s HTML is modified on onload, is there like some sort of internal function I need to run to update it or something that is happening either after onload is successful or before onscroll starts?

I’ve also tried putting my .innerhtml update function to be called by the DOMContentLoaded event, and the video tag function in onload, and I get the same results – which is that it doesn’t find any video tags, but again moving the video tags function to onscroll works just fine.

How to fetch databse in javascript

let usernames = document.querySelector("#usernames");
let clearsave = document.querySelector("#clearSaved");
let remembered = document.querySelector("#remembered");
let arr = JSON.parse(localStorage.getItem("user")) || []

fetch("https://jsonplaceholder.typicode.com/users")
.then(res=>res.json())
.then(users=>{
users.forEach(element => {

    let h1 = document.createElement("h1")
    h1.innerText = element.username
    usernames.appendChild(h1)

    let btn = document.createElement("button")
    btn.innerText = "Remember"
    h1.appendChild(btn)
    btn.addEventListener("click",function(){
        if (arr.includes(element.email)){
            alert("Email is remembered already")
            return
    }
    else{
       let character = document.createElement("li")
       character.innerText = element.email
       remembered.appendChild(character)
       arr.push(element.email)
       localStorage.setItem("user",JSON.stringify(arr))
       }
    })
});
});

   clearsave.addEventListener("click",function(){
localStorage.clear()`enter code here`
remembered.innerHTML = null
remembered.innerHTML = "Remembered: "
arr = []
    })

what is incorrect? I want you guys to review it and suggest any more efficient solution if possible. Also how can I minimze the code, like do the same in the most short code possible.

Add code snippet to textarea inside Jinja2 For-Loop

I’m trying to add a button “add code snippet” inside textarea. I have a working example in this picture 1.

textarea with button to add code snippets

I’, trying to apply the same code but this time the textarea is inside a modal and it’s generated by jinja2 for loop automatically.
It generates an edit form for all posts. In this case I added the specific ‘Id’ into buttons and textareas so when I click ‘add code’ open the correct modal with the correct textarea id to be edited, like this:

<a id="add_code-{{post.Id}}" href="#" class="fp-btn-posts fp-btn-post-view">
    Add Code
</a>  

 <textarea id="text-{{post.Id}}" type="text" name="question" required></textarea> 

The form it’s working. If the user type text or manually add code snippet like “`code here´´´, will save ok.

The problem is that I want to make the ‘add code’ button to work but when I click I get this error from my JS:

const startPosition = textarea.selectionStart; #null is not an object (evaluating ‘textarea.selectionStart’)

And I don’t understand why, since the other form works, I thought since this textarea (since is in a for loop) has unique Id would work fine.

Here is JS code to add code snippet block when the user click add code:

// script to add code snippet into textboxes
    var textarea = document.getElementById('text-{{post.Id}}');
    var insertCode = document.getElementById('add_code-{{post.Id}}');

    insertCode.addEventListener('click', () => {
        const startPosition = textarea.selectionStart;
        const endPosition = textarea.selectionEnd;
        const codeBlock = "n```'code here'´´´n";

        console.log(startPosition);

        const newValue = textarea.value.substring(0, startPosition) +
                    codeBlock + textarea.value.substring(endPosition);
        textarea.value = newValue;

        // Optional:  Place the cursor after the inserted code block
        textarea.selectionStart = startPosition + codeBlock.length;
        textarea.selectionEnd = startPosition + codeBlock.length;
        textarea.focus();
    });

I’m getting error in the line 6 this code (const startPosition = textarea.selectionStart;)

I’m new in front-end so if someone can give a help on that I appreciate.
Thanks in advance.

Change Video on Scroll

I have taken the source code from this codepen page. It changes the image on scroll, but instead of image, I want to change the video on scroll.

Here is the code I have so far. The first video plays but it won’t change on scroll. I added id=”mainImage” in the Video Source tag, so it should work?
What am I doing wrong?

CSS

<style>
.mouse_scroll {
  overflow: visible;
  position: relative;
}
.side_sec {
  display: flex;
}
.img-links div.text-sec {
  text-align: left;
  padding: 10px 20px;
  border-radius: 10px;
  margin: 500px 0px;
  background: transparent;
}
.img-links div.active {
  border: none;
  background: var(--box-bg-color);
}
.featured-img::before {
  content: "";
  position: absolute;
  background-size: 60%;
  background-repeat: no-repeat;
  background-position: left;
  left: 15%;
  right: 0px;
  top: -50px;
  width: 100%;
  height: 100%;
  z-index: 1;
  margin-right: 0px;
}
.featured-img {
  position: sticky;
  top: 140px;
  height: 700px;
}
.featured-img img {
  position: absolute;
  left: 75px;
  top: 35px;
  width: 55%;
  height: auto;
  border-radius: 30px;
}
.side-text {
  display: flex;
}
.side-text h3{
  color:orange;
}
.side-text p{
  color:#000;
}
</style>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"  crossorigin="anonymous"></script>
<section id="videoonscroll">
  <div class="container">
    <div class="row">
      <div class="side-text">
        <div class="col-xl-7 col-lg-7 col-md-12 col-sm-12 col-12">
          <div class="img-links">
            <div data-src="video1.mp4" class="text-sec active">
              <h3 class="margin-10px-bottom">Better writing,<br>better results</h3>
              <p class="text-16 width-90">Be perfectly professional, clear, and convincing in a few clicks, not a few hours.</p>
            </div>
            <div class="text-sec" data-src="video2.mp4">
              <h3 class="margin-10px-bottom">The right text<br>for the context</h3>
              <p class="text-16 width-90">Get personalized suggestions based on what you’re writing and who will read it.</p>
            </div>
            <div class="text-sec" data-src="video3.mp4">
              <h3 class="margin-10px-bottom">Works where<br>you work</h3>
              <p class="text-16 width-90">Grammarly works across all the apps and sites you use. No copying, no pasting, no context switching.</p>
            </div>
            <div class="text-sec" data-src="video4.mp4">
              <h3 class="text-25 font-weight-700 margin-10px-bottom">Never go out of style</h3>
              <p class="text-16 width-90">Grammarly understands both your personal style and your brand style guide to help you find your voice.</p>
            </div>
            <div class="text-sec" data-src="video5.mp4">
              <h3 class="text-25 font-weight-700 margin-10px-bottom">This is responsible AI</h3>
              <p class="text-16 width-90">Don’t compromise on security. We never sell your data, provide it for advertising purposes, or allow third parties to use it to train their models.</p>
            </div>
            <!-- Add more divs as needed -->
          </div>
        </div>
        <div class="col-xl-5 col-lg-5 col-md-12 col-sm-12 col-12 sm-display-none">
          <div class="featured-img">
            <video class="video-player_video__8GR5s" autoplay="" loop="" muted="" playsinline="" poster="video1.png">
              <source src="video1.mp4" type="video/mp4" data-component-name="default-render-source" id="mainImage" />
            </video>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js'></script>

Javascript

<script id="rendered-js" >

  $(document).ready(function () {
    // Function to handle mouse wheel events
    function handleMouseWheel(ele) {
      // Your logic here
      console.log("Mouse wheel event detected!");
      $('.img-links div.text-sec').removeClass('active');
      $(ele).addClass('active');
      // Update the main image based on the active div
      var newImageSrc = $(ele).data('src');
      $('#mainImage').attr('src', newImageSrc);
    }
    const options = { threshold: 0.4 };
    // Set up Intersection Observer
    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          // Add scroll event listener when target element is visible
          $(window).on('wheel', () => handleMouseWheel(entry.target));
        } else {
          // Remove scroll event listener when target element is not visible
          $(window).off('wheel', () => handleMouseWheel(entry.target));
        }
      });
    }, options);
    // Define the target elements you want to observe
    const targetElements = $('.img-links div.text-sec');
    // Start observing each target element
    targetElements.each(function () {observer.observe(this);});
  });
</script>

How to I properly spread a spritesheet in JavaScript

I’m trying to create a mini RPG game and have been following instructions, I got my spritesheet from my gaia profile and images 4-8 are looped with leg movement under the avatar with out feet and the default avatar. The idle one is with shoes, index 5. I’m new to this but I’ve tried adjusting the dimensions of practically everything. Here’s a link to my spritesheet https://ibb.co/HDVVPcYT

<script>
  const canvas = document.getElementById('avatar-canvas');
  const ctx = canvas.getContext('2d');

  const sprite = new Image();
  sprite.src = 'my_avi.png';

  const spriteWidth = 60;
  const spriteHeight = 160;

  const directions = {
    down: 0,
    left: 1,
    right: 2,
    up: 3
  };

  let legFrames = [4, 5, 6, 7]; // footstep animation frames
  let legFrame = 0;

  let frame = 1; // Default idle frame is middle
  let direction = directions.down;

  let x = canvas.width / 2 - spriteWidth / 2;
  let y = canvas.height - spriteHeight - 20;


  let tick = 0;
  let moving = false;
  const keys = {};

  // Draw avatar
  function drawAvatar() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    const col = moving ? legFrames[legFrame % legFrames.length] : frame;
    const row = direction;

    ctx.drawImage(
      sprite,
      col * spriteWidth, row * spriteHeight,
      spriteWidth, spriteHeight,
      x, y,
      spriteWidth, spriteHeight
    );
  }

  // Animation loop
  function update() {
    tick++;

    if (moving && tick % 10 === 0) {
      legFrame++;
    }

    handleMovement();
    drawAvatar();
    requestAnimationFrame(update);
  }

  // Key listeners
  window.addEventListener('keydown', e => {
    keys[e.key.toLowerCase()] = true;
    moving = true;
  });

  window.addEventListener('keyup', e => {
    keys[e.key.toLowerCase()] = false;

    if (!keys['arrowup'] && !keys['arrowdown'] && !keys['arrowleft'] && !keys['arrowright']
        && !keys['w'] && !keys['a'] && !keys['s'] && !keys['d']) {
      moving = false;
      legFrame = 0;
      frame = 4; // Reset to idle frame
    }
  });

// Define world and TV boundary limits
const tvBlockHeight = canvas.height * 0.4; // Approx. top 40% blocked
const padding = 10; // Optional padding from edge

function handleMovement() {
  let nextX = x;
  let nextY = y;

  if (keys['w'] || keys['arrowup']) {
    nextY -= 2;
    direction = directions.up;
  } else if (keys['s'] || keys['arrowdown']) {
    nextY += 2;
    direction = directions.down;
  }

  if (keys['a'] || keys['arrowleft']) {
    nextX -= 2;
    direction = directions.left;
  } else if (keys['d'] || keys['arrowright']) {
    nextX += 2;
    direction = directions.right;
  }

  // World boundary collisions
  const maxX = canvas.width - spriteWidth - padding;
  const maxY = canvas.height - spriteHeight - padding;

  if (nextX >= padding && nextX <= maxX) {
    x = nextX;
  }
  if (nextY >= padding && nextY <= maxY) {
    // TV collision rule
    if (nextY > tvBlockHeight) {
      y = nextY;
    }
  }
}


</script>
<script>
let animationStarted = false;

sprite.onload = () => {
  drawAvatar();
  if (!animationStarted) {
    update();
    animationStarted = true;
  }
};
</script>
<body>
  <div id="container">
    <div id="chat-panel">
      <div id="chat-messages"></div>
      <div class="chat-input">
        <div class="user-icon" style="background-image: url('user-ico/icon_1.jpg');"></div>
        <input type="text" id="chat-input" placeholder="Type a message..." />
      </div>
    </div>

    <div id="canvas-area">
      <canvas id="avatar-canvas" width="800" height="600" style="position:absolute; z-index:100;"></canvas>
      <img id="lounge-canvas" src="video-L.png" alt="Lounge Background" />
      <iframe width="560" height="315" src="https://www.youtube.com/embed/xolgs4-mymQ?si=KgabkxW6n-67L0oM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
    </div>

    <div id="playlist-panel">
      <div class="playlist-item" onclick="loadVideo('43gm3CJePn0')">MCR - Welcome to the Black Parade</div>
      <div class="playlist-item" onclick="loadVideo('zP2rjMx9stw')">Pierce The Veil - King For A Day</div>
      <div class="playlist-item" onclick="loadVideo('K0ibBPhiaG0')">BMTH - Can You Feel My Heart</div>
    </div>
  </div>

Is there a way to have a type-guard which solely checks the type metadata, not any literal properties?

I have a Box component. Box accepts an as prop which extends ElementType. However, as a result, it may or may not accept a className prop

{/** valid, because `a` (HTMLAnchorElement) accepts a className prop */}
<Box as="a" href="/" className="text-purple-500">Link</Box>

{/** Valid, because it doesn't necessarily _require_ a `className` prop */}
<Box as="a" href="/">Link</Box>

{/** Valid, because no `className` prop was specified and the inline element does not accept a className */}
<Box
  as={({ children }: PropsWithChildren<never>) => (
    <blink>{children}</blink>
  )}
>
  The blink tag is deprecated
</Box>

{/** Invalid. The inline element does not accept a className */}
<Box
  className="text-purple-500"
  as={({ children }: PropsWithChildren<never>) => (
    <blink>{children}</blink>
  )}
>
  The blink tag is deprecated
</Box>

I am using this Box to craft other components. Suppose I am crafting a button

function Button<T extends ElementType = "button">(props: ButtonProps<T>) {
  const className = extractClassName(props);
  return <Box {...props} {...className} as={props.as ?? "button"} />;
}

I want to create a function which will attempt to extract the className into an object and spread it into the box, so I did something like this:

type HasClassName<T> =
  T extends Partial<Record<"className", infer U>>
    ? Expand<Partial<Record<"className", U>>>
    : never;

type ExtractClassName<T> =
  T extends Partial<Record<"className", infer U>>
    ? Expand<Partial<Record<"className", U>>>
    : Record<never, never>;

function hasClassName<T extends object>(props: object): props is HasClassName<T> {
  return "className" in props;
}

export function extractClassName<T extends object, U extends string>(
  props: T,
  additionalClassNames: U,
): ExtractClassName<T> {
  return (
    hasClassName(props)
      ? { className: cx(props.className, additionalClassNames) }
      : {}
  ) as ExtractClassName<T>;
}

The problem I’m running into here is this case:

<Box as="a" href="/">Link</Box>

Since the type-guard hasClassName literally checks for the presence of "className", it’s predictably failing. What I really want the type-guard for is to check that the underlying component itself accepts a classname at all.

In the case that the underlying component does accept a className, but no className is specified, it should simply return an object with { className: U }

Is there a way to do this in TypeScript, or am I misunderstanding typeguards?

Video is paused on page mount despite autoplay

Site development is always interesting, even more interesting when such cases happen.

I have a video tag element:

<video
   src={slide.src}
   className={s.video}
   autoPlay
   loop
   muted
   playsInline
   width={400}
   height={713}
   onClick={() => handleSelectVideo(slide.src)}
/>

With this element sometimes when user enters the page, his video renders paused as we can see on the image: (most of the content blurred on purpose)

enter image description here

So as we can see the video has this pause button on the first render despite video element has autoPlay trait.


What I tried

  • The first attempt was to try to add <source> (didn’t know how exactly it should help but anyway), as from the context can be understood – it didn’t help

  • Another variant was to add preload="auto" but it didn’t help either

  • I tried to get refence to the element and manually unpause it:

const videoRef = useRef<HTMLVideoElement>(null);

const [loaded, setLoaded] = useState<boolean>(false);

...

useEffect(() => {
   setLoaded(true);
}, []);

useEffect(() => {
   if (!loaded) return;

   const v = videoRef.current;

   if (!v) return;

   v.muted = true;

   const p = v.play();

   if (p && p.catch) p.catch(() => {});
}, [loaded]);

But as this question appeared to be – all these variants didn’t help me at all.

In general for the majority of the users video starts well without this pause button, but as there still some people who experience it – it should be fixed