Steps for generating a signal that postpones the primary signal and promptly resets

I am looking to create a signal that will automatically switch to an underlying signal or memo after a specific delay, and reset immediately if the primary signal is cleared. The code snippet below illustrates my desired functionality.

import { render } from "solid-js/web";
import { For, createSignal, createEffect } from "solid-js";

function Counter() {
   const [s, setS] = createSignal(undefined)
   const [delayedS, delayedSetS] = createSignal(undefined)


   setTimeout(() => {
     setS(10)
   }, 1000)

   setTimeout(() => {
     setS(undefined)
   }, 3000)

   createEffect(() => {
      let res = s()
      if (res !== undefined) {
         setTimeout(() => delayedSetS(res), 1000)
      } else {
         delayedSetS(undefined)
      }
   })

  return (<>
    <span> S {s()} </span>
    <span> Delayed S {delayedS()}</span>
    </>)
}

render(() => <Counter />, document.getElementById("app"));

The above implementation works fine, but I'm wondering if this is the best approach. I haven't explored using createDeferred for this function as it involves a scheduler that I'm not familiar with.

Answer №1

Your approach was completely valid.

While the createDeferred function may seem suitable for a similar purpose, it would not produce the desired outcome in this scenario due to the following reasons:

  1. The timeout specified in createDeferred does not represent an exact waiting period before triggering updates; rather, it serves as a maximum idle time for the browser.
  2. The timeout would occur prior to updating the signal to undefined and other values.
const delayedS = createDeferred(s)

For manipulating signals, a more favorable option is to use createComputed. This method involves pure computation similar to createMemo, ensuring immediate execution before applying effects. Although in straightforward cases there might not be a noticeable distinction compared to using effects, utilizing an effect for signal manipulation could potentially lead to excessive updates.

  createComputed(
    on(s, (v) => {
      if (v) setTimeout(() => setDelayedS(v), 1000);
      else setDelayedS();
    })
  );

In addition, cancelling the timeout upon setting to

undefined</code instantly can help mitigate timing inconsistencies.</p>
<pre class="lang-js"><code>  let timeoutId = 0;
  createComputed(
    on(s, (v) => {
      if (v) timeoutId = setTimeout(() => setDelayedS(v), 1000);
      else {
        setDelayedS();
        clearTimeout(timeoutId);
      }
    })
  );
  onCleanup(() => clearTimeout(timeoutId));

Answer №2

If you're looking to add delayed reactive functionality, consider utilizing the @solid-primitives/scheduled package.

import {createMemo, createSignal} from 'solid-js';
import {createScheduled, throttle} from '@solid-primitives/scheduled';

const [count, setCount] = createSignal(0);
const scheduled = createScheduled(callback => throttle(callback, 1000)); // introducing a delay of 1000 ms

const debouncedCount = createMemo(
  (previousCount) => scheduled() ? count() : previousCount,
  0
);

createEffect(() => {
  // The output of debouncedCount will only change every second, no matter how many times setCount is called.
  console.log(debouncedCount());
});

In this setup, calling setCount multiple times will result in updates to debouncedCount occurring at intervals of one second. Additionally, there are other scheduling functions like debounce, as well as modifiers such as leading.

To see these concepts in action, visit the demo on the mentioned page showcasing the various scheduling options available.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guidelines on utilizing map varieties for creating a type definition for `Object.keys`

Exploring a stricter definition of the Object.keys function using mapped types in TypeScript. An Illustrative Example: To begin, consider an object defined using const: const myObj = { a: 'some value', b: 5 }; Typically, when utilizing Ob ...

Make sure to confirm that 'tables-basic' is an Angular component within the module before proceeding

In my table-basic.component.ts file, I declared 'tables-basic' as a selector and included this template in dashboard.html. Despite following the steps outlined below, I encountered an error which is also highlighted. Snippet from my dashboard.te ...

Tips for updating the secure route with TypeScript and React-Router versions 4, 5, or 6

I've been attempting to create a <PrivateRoute> based on the example in the react-router documentation using TypeScript. Can someone provide assistance? The PrivateRoute from the react-router documentation: const PrivateRoute = ({ component: Co ...

Dealing with React and Firebase Authentication Errors: How to Handle Errors for Existing Accounts with Different Credentials

According to the documentation at https://firebase.google.com/docs/auth/web/google-signin#expandable-1, when error.code === 'auth/account-exists-with-different-credential', signInWithPopup() should return an error.email. However, in my specific c ...

What is the best way to retrieve an accurately matched array?

I am working on a function that analyzes a string of DNA and should return an accurately matched DNA array. Here is the code snippet I have experimented with: function checkDNA(dna) { var dnaarr = []; for(var i = 0; i < dna.length; i++) { ...

Creating a personalized theme for Material UI 5.0 using Typescript with React

Having some trouble customizing a theme in Material UI 5.0 with typescript. theme.ts import { createTheme } from '@mui/material'; declare module '@mui/material/styles' { interface Theme { custom: { buttonWi ...

I'm in need of someone who can listen and detect any changes in my notifications table (node) in order to perform real-time data

Seeking a listener in Firebase to track changes in my notifications table for real-time data monitoring. My project is utilizing Angular 2 with TypeScript and Firebase. ...

Unable to alter fxFlex property within Component using "setAttribute('fxFlex', '25%')" does not function properly in Angular 6

Currently, I am utilizing the flexLayout module to create responsive divs in my Angular application. You can find more information about flexLayout at https://github.com/angular/flex-layout and also at https://alligator.io/angular/flex-layout/. const nav ...

Tips for sending just the updated section of the form

I am working with a form group where I map the values from the form to an object type in order to make a request to edit the item. This is my form structure: public companyForm = new FormGroup( { generalInfo: new FormGroup({ name: new ...

Is there a way to dynamically change an icon based on certain conditions using typescript?

I am struggling with displaying icons in my TypeScript code using Material Icons. I need to dynamically change the icon based on a condition, for example if the power is false I want to display 'power_off', but if it's true then I want to di ...

Identifying Typescript argument types

The given code is functional, but I am looking to refactor it for better clarity using Typescript syntax if possible. class Actions { actions: string[] } type Argument = object | Actions; export class GetFilesContext implements IExecutable { execute( ...

What is the method for opening the image gallery in a Progressive Web App (PWA)?

I am struggling to figure out how to access the image gallery from a Progressive Web App (PWA). The PWA allows me to take pictures and upload them on a desktop, but when it comes to a mobile device, I can only access the camera to take photos. I have tried ...

Steps for opening standalone angular2 and TypeScript project in visual studio: A guide to launching your project

What is the process for accessing an Angular2 and TypeScript project in Visual Studio without needing npm or Node.js? I require the ability to open the project on a computer that is not connected to a network. Many thanks ...

Closing a modal using the Enter key in Angular 6

I was able to replicate the issue on StackBlitz using minimal code. To reproduce: Step 1: Input a word in the text field and press Enter on the keyboard. Step 2: A modal will pop up. Step 3: Hit Enter again on the keyboard. During Step 2, I encou ...

This component is not compatible with JSX syntax and cannot be used as a JSX component. The type '() => Element' is not suitable for JSX element rendering

My Nextjs seems to be malfunctioning as I encountered the following error in a Parent component. Interestingly, the Spinner Component remains error-free Spinner.tsx export default function Spinner() { return ( <div className='flex ...

Is it feasible to incorporate a method into a prototype and ensure that 'this' is associated with the appropriate type in TypeScript?

I have a scenario where I need to add a new method to a prototype, specifically to a class created using TypeScript. Here is an example: declare module "./MyClass" { interface MyClass { myNewMethod(); } } MyClass.prototype.myNewM ...

What is the solution to the strict mode issue in ANGULAR when it comes to declaring a variable without initializing it?

Hi everyone! I'm currently learning Angular and I've encountered an issue when trying to declare a new object type or a simple string variable. An error keeps appearing. this_is_variable:string; recipe : Recipe; The error messages are as follows ...

Testing attributes and props with React Testing Library

Currently, I am in the process of developing a React application using TypeScript. For creating components, I rely on material-ui and for unit testing, I make use of react-testing-library. Specifically, I am working on designing a wrapper for the Grid com ...

Dynamic Route Matching in NextJS Middleware

Currently, I am in the process of developing a website that incorporates subdomains. Each subdomain is linked to a file-based page using middleware. Take a look at how the subdomains are being mapped to specific pages: app.com corresponds to /home app.com ...

Error: Unhandled promise rejection: Trying to access a property of null (specifically 'branch') causing a TypeError

While developing a dashboard for an Angular application, I encountered an error when trying to access the dashboard: ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of null (reading 'branch') TypeError: Cannot read propert ...