How to use either this type or another based on props only? React Typescript Discriminating Unions

I have a componenet:

type Base = {
    color: string
}

type Button = {
    to: string
} & Base

type Link = {
    link: string
    linkNewTab: boolean
} & Base

type ComponentProps = Button | Link 

export const Button: React.FC<ComponentProps> = (props) => {
    return (<>
        {props.link ? <Link newTab={props.linkNewTab}>...</Link> : props.to && <Button>...</Button>}
    </>)
}
  • There is a base type with props which both types have in common.
  • The Component should either has Button or Link type based on the given props. But if it has Link, these props are preferred.

Typescript Error:

Property 'link' does not exist on type 'PropsWithChildren<ComponentProps>'.
  Property 'link' does not exist on type '{ to: string; } & Base & { children?: ReactNode; }'.ts(2339)

What I don’t want:

  • I can solve the problem by adding a type to the Base type and decide from their which props are allowed. I would like to automatically decide that based on props.

Information: 4.5.4 TypeScript Version

Use scrollHeight to scroll to the bottom, but doesn’t work for div

I want to make the div always scroll to the bottom of the content, however, I fail to do that, but my solution works for textarea. I don’t know why.

I have the following code:

Use textarea:

var i = 0;
var txt = 'Stack Overflow is a question and answer website for professional and enthusiast programmers. It is the flagship site of the Stack Exchange Network,[4][5][6] created in 2008 by Jeff Atwood and Joel Spolsky.[7][8] It features questions and answers on a wide range of topics in computer programming.[9][10][11] It was created to be a more open alternative to earlier question and answer websites such as Experts-Exchange. Stack Overflow was sold to Prosus, a Netherlands-based consumer internet conglomerate, on 2 June 2021 for $1.8 billion.[12]'
function type(){
  if (i < txt.length) {
    document.querySelector('textarea').scrollTop =  document.querySelector('textarea').scrollHeight
    document.querySelector('textarea').innerHTML += txt.charAt(i);
    i++;
    setTimeout(type,1)
  }
  }
  type()
<textarea ></textarea>

Use div:

var i = 0;
var txt = 'Stack Overflow is a question and answer website for professional and enthusiast programmers. It is the flagship site of the Stack Exchange Network,[4][5][6] created in 2008 by Jeff Atwood and Joel Spolsky.[7][8] It features questions and answers on a wide range of topics in computer programming.[9][10][11] It was created to be a more open alternative to earlier question and answer websites such as Experts-Exchange. Stack Overflow was sold to Prosus, a Netherlands-based consumer internet conglomerate, on 2 June 2021 for $1.8 billion.[12]'
function type(){
if (i < txt.length) {
    document.querySelector('div').scrollTop =  document.querySelector('div').scrollHeight
    document.querySelector('div').innerHTML += txt.charAt(i);
    i++;
    setTimeout(type,1)
  }
  }
  type()
div{
width:100px;
height:100px;
}
<div></div>

I find that if use textarea instead of using div, the scrollTop = scrollHeight will work and will always scroll to the bottom, but if I use div, it won’t work.

Could anyone explain to me why this doesn’t work?

Thanks for any responds!

Hardhat – get latest block number in seconds

How to get the latest block number in seconds (TEST_URL = RPC BSC test) :

const provider = new ethers.providers.JsonRpcProvider(Process.env.TEST_URL);
let timestamp = 0;
// Block Number
provider.getBlockNumber().then(function(blockNumber) {
    timestamp = blockNumber;
});

JAVASCRIPT Modules Access-Control-Allow-Origin Error in Safari [duplicate]

I am not exactly new to javascript but I keep encountering errors when I try to use modules. Here is a snapshot of my html:

<script type= "module" src="scopes.js"></script>
<script type="module" src = "testImport.js" ></script>

Essentially, what I am trying to do is export class in scopes.js as default and then import it in testImport.js. The javascript snapshots:

1.

   constructor(src, type) {
       this.src = src;
       this.type = type;
      this.img = document.createElement('img');
   } 
   ///more stuff below of course
import {Scope} from './scopes.js'

When I try to run my html file, I get the errors:

[Error] Origin null is not allowed by Access-Control-Allow-Origin.
[Error] Failed to load resource: Origin null is not allowed by Access-Control-Allow-Origin. (scopes.js)

I know this has something to do with security and the browser but I am really stuck on this because I thought safari supports modules. I am using safari 15.2.

Thank you in advance to everyone that reads this and answers!

Override JavaScript global native Object() constructor

I’m trying to override Object() calls in JavaScript, in order to intercept and save all the parameters passed to the object constructor.

I don’t have any access to the original code since I am running from an injected code but I do run from the same scope and share the same window of the original code.

I tried this approach:

(function (nativeObject) {
    window.Object = function (value) {
        if (value.magic) {
            window.myMagic = value.magic;
        }
        return nativeObject(value);
    }
})(Object);

as well as saving the original window.Object on window.nativeObject and calling it from within my hook, but in both ways I end up getting:

TypeError: Object.defineProperty is not a function
TypeError: Object.keys is not a function
Uncaught (in promise) TypeError: Object.isExtensible is not a function
Uncaught (in promise) TypeError: Object.create is not a function

Is it because my window.myMagic calls the the Object methods to set the myMagic key in the window object?

Is what I’m trying to do possible?

How do I persuade babel to let me define a Javascript array of consts?

I’m building my first expo/react app. I keep getting an “Unexpected token” error message in App.js:

export default class App extends React.Component {
   const [message, setMessage] = useState("...");

the error being in the [ of the line beginning const.

As best I can tell, this is a babel issue: this syntax was introduced in ES2015. AFAICS, this should be resolvable by adding @babel/preset-env to babel.config.js thus:

module.exports = function(api) {
  api.cache(true);
  return {
      presets: [
          '@babel/react',
          '@babel/env',
      ],
      plugins: [
          '@babel/proposal-class-properties',
      ],
  };
};

Bundling succeeds, but the error remains! What am I missing?

How can I show a modal using an animation with Tailwind and react.js?

I am trying when I click on a modal to have an animation to show the modal but I don’t achieve to do that using Tailwind and react.

Here is my code :

import React, { useState, useCallback } from "react";
import ReactDOM from "react-dom";
import Wrapper from "./Wrapper";
import Input from "./Input";

import "./styles.css";
import Button from "./Button";
import Modal from "./Modal";

function App() {
  const [showModal, setShowModal] = useState(false);
  const handleShowModal = useCallback(() => {
    setShowModal(!showModal);
  }, [showModal]);
  const handleCloseModal = useCallback(() => {
    setShowModal(false);
  }, []);
  return (
    <div className="p-4">
      <h1 className="text-red-500 text-center">PlayGround</h1>
      <Wrapper className="p-2">
        <Input />
      </Wrapper>
      <Wrapper className="p-2">
        <Button onClick={handleShowModal}>Show Modal</Button>
        {showModal && <Modal onCancel={handleCloseModal} />}
      </Wrapper>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

And you can see my full code here :

my full project

I would like something like that :

the goal

How can I do that ?

Thank you very much !

can someone help me please with some Javascript problem

Im very new with javascript and been a little difficult I have a challenge to solve and i tried so many different methods but cant figure it out this is the steps for the challenge I would apreciate some help. thanks


Declare a variable named maxNumber and use a Math method to assign it the largest number from the following numbers: 7, 4, 8, 11, 5, 2
Log the value of maxNumber to the console.
Declare a variable named randomNumber and assign it an expression using the following Math.floor, Math.random and the variable maxNumber so that it outputs a random number between 0 and 10

React JS: Function isn’t returning anything

I have a JS function in my code that is supposed to return a React Component for Each element of my split string, but for some reason, when I call it on my main “return()”, the function isn’t returning anything. I tried to put the function directly inside of the return(), but the same happened. That never happened to me before and I have no idea of what it is.

Here is my code:

import React from 'react';

import DatabaseLiLine from './DatabaseLiLine';

const DatabaseLiSection = ({ className, children, classId }) => {
    const example = "Use,This,As,An,Example";
    const splitLiTitles = example.split(",");

    const returnLines = () => {
        splitLiTitles.forEach(element => {
            return(
                <DatabaseLiLine>
                    {element}
                </DatabaseLiLine>
            );
        })
    }
    return (
        <li className={className}>
            <a href="/">{children}</a>
            <div id={classId} className="consult_box">
                {returnLines()}
            </div>
        </li>
    );
}

export default DatabaseLiSection;

Google Apps Script add month to a date until specific date is reached

I have the following code using Google Apps Script, but when I log it out I get the following results. I want GAS to log the next month and stop once it gets to “lastDateofYear “. For whatever reason, the year doesn’t change in my results, it just keeps repeating the current year. Please help.

var thisDate = "Mon Dec 20 00:00:00 GMT-06:00 2021";
var nextYear = Number(currentYear)+1;
var lastDateofYear = new Date("12-31-"+nextYear);

  for(var i=thisDate; i <= lastDateofYear; ){  
    var currentiDate = new Date(i);     
    var month = currentiDate.getMonth()+1;
    i.setMonth((month) % 12);
    i.setDate(currentiDate.getDate());
    Logger.log(currentiDate);
  }

RESULTS:

Mon Dec 20 00:00:00 GMT-06:00 2021
Wed Jan 20 00:00:00 GMT-06:00 2021
Sat Feb 20 00:00:00 GMT-06:00 2021
Sat Mar 20 00:00:00 GMT-05:00 2021
Tue Apr 20 00:00:00 GMT-05:00 2021
Thu May 20 00:00:00 GMT-05:00 2021
Sun Jun 20 00:00:00 GMT-05:00 2021
Tue Jul 20 00:00:00 GMT-05:00 2021
Fri Aug 20 00:00:00 GMT-05:00 2021
Mon Sep 20 00:00:00 GMT-05:00 2021
Wed Oct 20 00:00:00 GMT-05:00 2021
Sat Nov 20 00:00:00 GMT-06:00 2021
Mon Dec 20 00:00:00 GMT-06:00 2021
Wed Jan 20 00:00:00 GMT-06:00 2021
Sat Feb 20 00:00:00 GMT-06:00 2021
Sat Mar 20 00:00:00 GMT-05:00 2021
Tue Apr 20 00:00:00 GMT-05:00 2021

My DragTarget only receives the image that is listed first. How do I change this?

Both Images are intended to be dragged into the leftbox div. when you drag the blue image, which is listed above the orange image. It successfully drops into the leftbox. When you drag the orange image to the droptarget the blue image replaces it once dropped. This is because it is listed above the orange image. I tested this out by swapping the code orders. Putting the orange image first. And the orange image was then the only recipient of the dropping. Any help is appreciated.

function allowdrag(e) {
  e.preventDefault();
}

function Drop(e) {
  e.preventDefault();
  var texts = e.dataTransfer.getData('image/png')
  var data = document.getElementById(texts);
  e.target.appendChild(data)
}

function drog(e) {
  e.dataTransfer.setData('image/png', e.target.id)
}
#leftbox {
  width: 20%;
  height: 175px;
  border: 5px solid grey;
  border-radius: 0px;
  padding: 0px;
  margin: 75px 15px 0px 100px;
  display: inline-block;
  background-color: white;
  position: relative;
}

#image1 {
  height: 175px;
  width: 138px;
  display: table;
  margin-bottom: 75px;
  display: inline-block
}

#reset {
  height: 0;
  width: 21%;
  padding-bottom: 18%;
  position: absolute;
  right: 0px;
  background-image: url(https://win-conditions.com/wp-content/uploads/2021/12/download-1.png);
  background-size: 100%;
  background-repeat: no-repeat;
}
<div id="leftbox" ondrop="Drop(event)" ondragover="allowdrag(event)">
  <button id="reset" type="button"></button>
</div>

<div id="image">
  <img id="image1" src="https://win-conditions.com/wp-content/uploads/2021/11/electrospirit.png" draggable="true" ondragstart="drog(event)">
  <img id="image1" src="https://win-conditions.com/wp-content/uploads/2021/11/fire_spirits-1.png" draggable="true" ondragstart="drog(event)">
</div>

JSFiddle: https://jsfiddle.net/0h7c45kj/1/

service-worker.js catch updatefound before running other custom functions

Is there a way to check if the service worker found an update before loading custom functions?

i have this function which is working, but it runs the custom functions twice, and seems very untidy..

I’m looking for a way to only run the custom functions once, and not when an update was found and installed. When an update is found, the user || the page will reload automatically and then the custom functions can run normally..

I added the reg.events in this function to determine where to place my custom functions. I hope this question is understandable..

function installApp(path, scope) {
if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register(path, {
            scope: scope
        }).then((reg) => {  
       // event listener to catch the prompt if any and store in
      // an instance for later use with add to homescreen() function.
       getPrompt(); 

       // this is a custom alert type notification      
       makeProgress('System','is ok'); 
                    
      /* THIS IS THE UPDATE FOUND FUNCTION */

        reg.onupdatefound = function() {
    var installingWorker = reg.installing;
    installingWorker.onstatechange = function() {
      switch (installingWorker.state) {
        case 'installed':
          if (navigator.serviceWorker.controller) {
     // the _clear() function removes items from the locaforage db to 
    // force the app to not auto login, but let the user
    // login again to refresh any data when the page reloads
                _clear('uuid');
                _clear('user');
                _clear('token');
                makeProgress('new version','reload app');
          } else {
           // removes any custom notifications
                    clearProgress(); 
            //just go into the app because everything is loaded.
            //We dont need to reinstall the 
            //homescreen or listen for the homescreen because this
           //is an update and the homescreen should already be installed?
               enterApp(); 
          }
          break;
        case 'redundant':
          // removes any custom notifications cause
          //the install is complete
            clearProgress();
               enterApp(); 
          console.log('The installing service worker became redundant.');
          break;
      }
    };
            return;
  };
                         


                  /** Here is the events that fire during the install
                 //  process and where i am currently stuck **/
  
    if (reg.installing) {
       makeProgress('updating','files');
    /* THE SERVICE WORKER IS DOWNLOADING THE CACHE FROM THE SERVER */
    } else if (reg.waiting) {

    /* what message here ?*/
    /* as far as i can tell, THE SERVICE WORKER IS WAITING FOR 
    *//*PREVIOUS SERVICE WORKER TO BEREFRESHED SO A RELOAD */
    /*UI SHOULD COME HERE??*/

    } else if (reg.active) {
    /* what message here ?*/
    /* IS THIS THE BEST PLACE TO RUN THE BELOW CUSTOM
    *//*FUNCTIONS?? WILL //THEY ALWAYS FIRE */
    }
                    


/** AT WHICH OF THE EVENTS ABOVE WILL I ADD THE FUNCTIONS FROM HERE **/

                requestWakeLock();  
       const browserFeatures = detectFeatures(reg);
               setCompatibilityArray(browserFeatures);
         
localforage.ready().then(function() {
                localforage.getItem('homescreen').then(function (value) {
               if(value != 1){           
    if (platform == 'iPhone' || platform == 'iPad') {
installHome();                                      
                                    } else {
     makeProgress('waiting', 'prompt');  
                         waitPrompt();
                         }
                         return;
               } else {
               enterApp();
                         return;        
               }
                         
    }).catch(function (err) {
    alertIt('something went wrong. Please refresh the page to try again.  If the problem persists, try another browser.</br>', 'warning', 0);
                    return;
    });
                
}).catch(function (err) {
  alertIt('Something went wrong.<br>Please refresh the page to restart the installation process.<br>'+err, 'danger', 0);
                return;
});
    
    
    /** TO HERE, WITHOUT RUNNING THESE FUNCTION DURING*/
   /*THE ONUPDATEFOUND EVENT AS THEN THEY WILL    RUN TWICE**/
    
    
    
        }, (err) => {
            alertIt('Something went wrong.<br>Please refresh the page to restart the   installation process.<br>', 'danger', 0);
        })
} else {
           alertIt('This browser is not compatible with this app.<br>Please try to use a   different browser to install this application.<br>', 'danger', 0);
   return;
}
}

I initialize this script like so:

  window.addEventListener("load", () => {
 makeProgress('Checking','system');     
  installApp(appsPath, appScope);
  })