Setting up project for developing RxJS app

I am trying to set up VS Code project for developing RxJS apps. I am following this article.

I keep getting Cannot GET / message from the server. My folder structure is:

root:
 index.html
 package.json
 tsconfig.json
 webpack.config.js
dist
 src
  index.js
node_modules
src
 index.ts

index.html:

<!DOCTYPE html>
<html lang="en">

<head>
<meta> charset="UTF-8"   </meta>
<meta name="viewport" > </meta>
    <title> RxJS Demo </title>
</head>

<body>
    <h1>Rx TypeScript</h1>
    <div>
        <ul id="list"> </ul>
    </div>

    <script src="/bundle.js"> </script>
</body>

</html>

package.json:

{
  "name": "rxjs-test",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --mode development"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "rxjs": "^7.8.1",
    "ts-loader": "^9.5.1",
    "typescript": "^5.5.4",
    "webpack": "^5.93.0",
    "webpack-dev-server": "^5.0.4"
  },
  "devDependencies": {
    "webpack-cli": "^5.1.4"
  } 
}

tsconfig.json:

{
    "compilerOptions": {
      "target": "ES6",    
      "lib": [
        "ES2017",
        "DOM"
      ],                                        
      "module": "ES6",   
      "moduleResolution": "Node",
      "allowJs": true, 
      "esModuleInterop": true, 
      "forceConsistentCasingInFileNames": true, 
      "strict": true,                                      
      "noImplicitAny": true,
      "skipLibCheck": true,                                 
      "sourceMap": true,
      "outDir": "./dist/"
    }
  }

webpack.config.js:

const webpack = require("webpack");
const path = require("path");
console.log("__dirname="+__dirname);
module.exports = {
    mode: "development",
    entry: './src/index.ts',
    devtool: 'inline-source-map',
    output: {
      filename: "bundle.js",
      path: path.resolve(__dirname, "dist"),
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js']
    },
    module: {
      rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
          exclude: /node_modules/
      }
     ]
    },
    devServer: {
        //contentBase: path.join(__dirname, 'dist'),
        compress: true,
        port: 9000
    },
    // enable devServer-logging
    infrastructureLogging: {
        debug: [name => name.includes('webpack-dev-server')],
      },
    stats: {
        logging: 'verbose',
      },
      mode: 'development'
  }

index.ts:

import { Observable } from "rxjs";
console.log(__dirname);
var observable = new Observable((observer) => {
    observer.next("Hello world");
})
observable.subscribe(
    (x) => console.log(x)
);

How can I add navigation in guide using Driver.js?

I’m working on an interactive guide for my website to improve user experience, allowing users to navigate through different sections based on a guide displayed in the sidebar. Currently, my guide is designed to be specific to the logged-in user and the currently open page.

However, I need to add navigation functionality so that users can directly open a specific page when they reach the corresponding option in the guide. Despite several attempts, I haven’t been able to achieve this.

Here’s what I’ve done so far:

  1. Created a guide tailored to the logged-in user and their current page.
  2. Implemented the onNextClick() function to attempt navigation.

Below is a snippet of my code. For now I am trying to integrate the navigation functionality in candidate section:

const driver = window.driver.js.driver;

const roleBasedSteps = {
    admin: {
        commonSteps: [
            {
                element: '#dashboardBtn',
                popover: {
                    title: 'Dashboard',
                    description: 'Overview your overall progress in figures, charts and tables.',
                    position: 'auto'
                }
            },
            {
                element: '#emailBtn',
                popover: {
                    title: 'Email',
                    description: 'Email box where you can send, receive and read emails.',
                    position: 'auto'
                }
            },
            {
                element: '#helpBtn',
                popover: {
                    title: 'Help',
                    description: 'Get stuck? Visit here.',
                    position: 'auto'
                }
            },
            {
                element: '#usersDropdown',
                popover: {
                    title: 'Users List',
                    description: 'View all users list to manage them.',
                    position: 'auto'
                }
            }
        ],
        'index.php': [
            {
                element: '#adminDashboardCountStats',
                popover: {
                    title: 'Total Counts',
                    description: 'View all counts of meetings, clients, client interviews and placed clients.',
                    position: 'auto'
                }
            }
        ]
    },
    employee: {
        commonSteps: [
            {
                element: '#dashboardBtn',
                popover: {
                    title: 'Dashboard',
                    description: 'Overview your overall progress in figures, charts and tables.',
                    position: 'auto'
                }
            },
            {
                element: '#emailBtn',
                popover: {
                    title: 'Email',
                    description: 'Email box where you can send, receive and read emails.',
                    position: 'auto'
                }
            },
            {
                element: '#helpBtn',
                popover: {
                    title: 'Help',
                    description: 'Get stuck? Visit here.',
                    position: 'auto'
                }
            },
            {
                element: '#usersDropdown',
                popover: {
                    title: 'Users List',
                    description: 'View all users list to manage them.',
                    position: 'auto'
                }
            }
        ],
        'index.php': [
            {
                element: '#employeeDashboardCountStats',
                popover: {
                    title: 'Total Counts',
                    description: 'View all counts of meetings, clients, client interviews and placed clients.',
                    position: 'auto'
                }
            }
        ]
    },
    candidate: {
        commonSteps: [
            {
                element: '#dashboardBtn',
                popover: {
                    title: 'Dashboard',
                    description: 'The dashboard has an overview to how many jobs have been applied to and any interviews you have upcoming.',
                    position: 'auto'
                },
                onNextClick: () => {
                    window.location.href = 'index.php';
                }
            },
            {
                element: '#emailBtn',
                popover: {
                    title: 'Email',
                    description: 'Email box where you can send, receive and read emails.',
                    position: 'auto'
                },
                onNextClick: () => {
                    window.location.href = 'email.php';
                }
            },
            {
                element: '#kanbanDropdown',
                popover: {
                    title: 'Interviews Board',
                    description: 'On the interviews tab you can track the status of your interviews. If you have manual interviews you can also add them here.',
                    position: 'auto'
                }
            },
            {
                element: '#jobsListBtn',
                popover: {
                    title: 'Jobs List',
                    description: 'On the Jobs List are all the jobs that we have applied for. What is important is to rate 5 to 10 jobs every week so we can get better at applying to jobs and feel free to drop in comments.',
                    position: 'auto'
                }
            },
            {
                element: '#calendarBtn',
                popover: {
                    title: 'Calendar',
                    description: 'When you get an interview request it will be on your calendar.',
                    position: 'auto'
                }
            },
            {
                element: '#accountDropdown',
                popover: {
                    title: 'Account',
                    description: 'Manage your profile.',
                    position: 'auto'
                }
            },
            {
                element: '#helpBtn',
                popover: {
                    title: 'Help',
                    description: 'If you are having any issues please feel free to call support or chat with us.',
                    position: 'auto'
                }
            },
            {
                element: '#collapseBtn',
                popover: {
                    title: 'Collapse Sidebar',
                    description: 'Collapse sidebar menu.',
                    position: 'auto'
                }
            }
        ],
        'index.php': [
            {
                element: '#dashboardTotalCounts',
                popover: {
                    title: 'Total Counts',
                    description: 'View all counts of jobs, interviews and meetings.',
                    position: 'auto'
                }
            },
            {
                element: '#dashboardAppliedJobsCount',
                popover: {
                    title: 'Applied Jobs Graph',
                    description: 'View graphical representation below based on selected date range of applied jobs.',
                    position: 'auto'
                }
            },
            {
                element: '#dashboardInterviewsListTable',
                popover: {
                    title: 'Interviews List Table',
                    description: 'View tabular view of your interviews.',
                    position: 'auto'
                }
            }
        ],
        'email.php': [
            {
                element: '.composeEmailBtn',
                popover: {
                    title: 'Compose Email',
                    description: 'Opens compose emails section.',
                    position: 'auto'
                }
            },
            {
                element: '#emailSidebarSection',
                popover: {
                    title: 'Email Folders',
                    description: 'View emails in each folder.',
                    position: 'auto'
                }
            },
            {
                element: '#load-folder-emails',
                popover: {
                    title: 'Emails List',
                    description: 'View all emails of specific folder.',
                    position: 'auto'
                }
            }
        ],
        'jobs_list.php': [
            {
                element: '#jobsListPageSearch',
                popover: {
                    title: 'Search Job',
                    description: 'Search from jobs list.',
                    position: 'auto'
                }
            },
            {
                element: '#jobsListAction',
                popover: {
                    title: 'Give Rating',
                    description: 'Rate any job by clicking action button against the job.',
                    position: 'auto'
                }
            },
            {
                element: '#jobsListAction',
                popover: {
                    title: 'Give Review',
                    description: 'Review any job by clicking action button against the job.',
                    position: 'auto'
                }
            }
        ],
        'kanban.php': [
            {
                element: '#kanbanInterviews',
                popover: {
                    title: 'Pending Interviews',
                    description: 'Here is the list of all upcoming interviews.',
                    position: 'auto'
                }
            },
            {
                element: '#kanbanStage1',
                popover: {
                    title: 'First Stage',
                    description: 'Here is the list of interviews of first stage.',
                    position: 'auto'
                }
            },
            {
                element: '#kanbanStage2',
                popover: {
                    title: 'Second Stage',
                    description: 'Here is the list of interviews of second stage.',
                    position: 'auto'
                }
            },
            {
                element: '#kanbanRejected',
                popover: {
                    title: 'Rejected',
                    description: 'Here is the list of failed interviews.',
                    position: 'auto'
                }
            },
            {
                element: '#kanbanOffer',
                popover: {
                    title: 'Offer',
                    description: 'Here is the list of passed interviews.',
                    position: 'auto'
                }
            },
            {
                element: '.kanbanAddInterview1',
                popover: {
                    title: 'Add New',
                    description: 'Opens pop up to add new item.',
                    position: 'auto'
                }
            },
            {
                element: '.kanbanAddInterview2',
                popover: {
                    title: 'Add New',
                    description: 'Opens pop up to add new item.',
                    position: 'auto'
                }
            },
            {
                element: '.kanbanAddInterview3',
                popover: {
                    title: 'Add New',
                    description: 'Opens pop up to add new item.',
                    position: 'auto'
                }
            },
            {
                element: '.kanbanAddInterview4',
                popover: {
                    title: 'Add New',
                    description: 'Opens pop up to add new item.',
                    position: 'auto'
                }
            },
            {
                element: '.kanbanAddInterview5',
                popover: {
                    title: 'Add New',
                    description: 'Opens pop up to add new item.',
                    position: 'auto'
                }
            }
        ]
    }
};

function mergeGuideSteps(common, specific) {
    return [...common, ...specific];
}

const steps = mergeGuideSteps(roleBasedSteps[userRole].commonSteps, roleBasedSteps[userRole][currentPage]) || [];

function expandHiddenAreas(steps) {
    steps.forEach(step => {
        const element = document.querySelector(step.element);
        if (element) {
            let parent = element.parentElement;
            while (parent) {
                if (parent.style.display === 'none' || parent.style.visibility === 'hidden') {
                    parent.style.display = '';
                    parent.style.visibility = '';
                }
                if (parent.classList.contains('collapsed')) {
                    parent.classList.remove('collapsed');
                }
                parent = parent.parentElement;
            }
        }
    });
}

function isElementInCommonSteps(commonSteps, element) {
    const result = commonSteps.some(step => step.element === element);
    // console.log(`Checking if element ${element} is in common steps: ${result}`);
    return result;
}

function expandSidebarIfNeeded(commonSteps, currentElement) {
    const sidebar = document.querySelector('#navbarVerticalCollapse');
    const isMobileScreen = window.innerWidth <= 990;
    // console.log(window.innerWidth);

    const cElement = "#" + currentElement;

    if (isMobileScreen && isElementInCommonSteps(commonSteps, cElement)) {
        sidebar.classList.add('show');
    } else {
        sidebar.classList.remove('show');
    }
}

const driverObj = driver({
    showProgress: true,
    steps: steps,
    onHighlightStarted: (element) => {
        expandSidebarIfNeeded(roleBasedSteps[userRole].commonSteps, element.id);
    }
});

document.getElementById('startGuide').addEventListener('click', function () {
    expandHiddenAreas(steps);
    driverObj.drive();
});

I’ve tried various approaches to link the guide steps to specific pages but haven’t succeeded. Can anyone help me figure out how to correctly implement this navigation functionality?

Any assistance or suggestions would be greatly appreciated!

How to find an image inside another image without checking the colours using OpenCV?

I am trying to locate the coordinates of an image inside another image. Currently it works as long as the colours are the same, but I want it to not mind any colours.

I found this example which I tried to use applying a grayscale filter:

import cv from "@u4/opencv4nodejs";

const MIN_ACCURACY = 0.8;

export async function getImageCoordinates(source: Buffer, template: Buffer) {
  const haystack = await cv.imdecodeAsync(source, cv.IMREAD_GRAYSCALE);
  const needle = await cv.imdecodeAsync(template, cv.IMREAD_GRAYSCALE);

  const matched = await haystack.matchTemplateAsync(
    needle,
    cv.TM_CCOEFF_NORMED
  );

  const minMax = await matched.minMaxLocAsync();
  const { x, y } = minMax.maxLoc;
  const accuracy = minMax.maxVal;


  if (accuracy > MIN_ACCURACY) {
    return { x, y };
  }

  return undefined;
}

The shade of gray is of course different when the colours are not the same, so unfortunately this does not work. It should also locate coordinates when the colours are different.

Is there an algorithm to solve a question of ratios that balance inputs and outputs?

I have a list of recipes, with fluid inputs and outputs per second:

const waterSeparation = {
  name: 'water separation',
  h2: 20/3,
  o2: 10
};

const ammonia = {
  name: "ammonia",
  h2: -10,
  n2: -10,
  nh3: 10,
}

In this case, every second, one factory running water separation generates 20/3 units of h2 and 10 units of o2, while a factory making ammonia makes 10 nh3 per second while consuming 10 n2 and 10 h2.

const ratios = [{
  recipe: waterSeparation,
  count: 20 // how do I pick these numbers?
}, {
  recipe: ammonia,
  count: 14
} ...]

const results = ratios.reduce((acc, { recipe, count }) => {
  Object.keys(recipe).filter(ingredient => ingredient !== 'name').forEach((ingredient) => {
    if (ingredient in acc){
      acc[ingredient] += recipe[ingredient] * count;
    } else {
      acc[ingredient] = recipe[ingredient] * count;
    }
  });

  return acc;
}, {});

I know how to calculate the current recipes and their excesses/shortages, but I don’t know how to pick the right number of each factory. I need an algorithm to balance all the recipes to whole number multiples so that all the outputs are consumed with the lowest whole number of factories running each recipe. I would also be okay if I rounded up to the nearest whole number, in case there is no perfect ratio of each recipe. Is there an algorithm for this?

Django modal window

I have a modal window for deleting comments. It looks like this:

<div id="deleteModal" class="modal">
    <div class="modal-content">
        <img class="modal-image" src="{% static 'img/icon-modal-delete.png' %}" alt="DELETE">
        <h1 class="modal-title">Delete comment?</h1>
        <div class="modal-block">
            <form method="POST">
                {% csrf_token %}
                <button class="modal-sucsess" type="submit">Delete</button>
            </form>
            <a class="modal-cancel" onclick="closeModal()">Cancel</a>
        </div>
    </div>
</div>

I include it with the include tag in the django template. There is also a js script for opening and closing the modal window, which looks like this:

function openModal() {
    var modal = document.querySelector('.modal');
    modal.style.display = 'block';
  }

  function closeModal() {
    var modal = document.querySelector('.modal');
    modal.style.display = 'none';
  }

In the django template I have a cycle where I display comments to the publication and each comment has a delete button, which on click calls a modal window, it looks like this:

<a class="main-row-content-comments-users-info-delete" onclick="openModal()" >Delete</a>

I wrote a view to delete a comment, but it needs to pass the comment id. If I were doing this directly via a link in a template tag, I would simply pass comment.pk, but how do I pass the key to the modal so that when I click the delete button in the modal, the delete view is called?

I tried to solve this using Ajax requests, but I don’t understand how.

Seeking Guidance on Choosing the Right Path for Web Development Career

**Seeking Guidance on Advancing My Web Development Career

**

I recently learned HTML and CSS and put in my best effort to master CSS. After learning these skills, I got my first client who wanted a landing page in HTML and CSS. I completed it successfully, exactly as the client wanted. However, someone then requested a single-page website using the Bootstrap CSS framework. At that moment, I turned to ChatGPT and created the single-page website in Bootstrap with its assistance.

Using Bootstrap was a mix of jQuery, JavaScript, and CSS, and I found it manageable with the help of ChatGPT. Now, I’m at a crossroads and very confused about what to do next. When I land a real job, how do I present myself as a web developer?

Some people suggest I should start learning backend development with PHP and its framework Laravel. In fact, I hired someone to create my final year project in Laravel because my SRS report mentioned that I would use Laravel for the project. Unfortunately, due to some issues, I couldn’t manage the time to complete it, and my group lost hope, leading us to outsource the project.

Others recommend starting with JavaScript, then moving on to React, and subsequently Node.js, forming the MERN stack. Another suggestion is to learn the MEAN stack.

I have 10 hours a day to dedicate to learning and development. I want to ensure I invest my time in the right areas to secure a job as quickly as possible. Should I focus on PHP and Laravel, or dive into the JavaScript ecosystem with React and Node.js? Any guidance on this matter would be greatly appreciated.

I started by learning HTML and CSS and successfully created a landing page for a client. I then used ChatGPT to help me build a single-page website using Bootstrap. I expected that mastering these skills would provide a solid foundation for my web development career and make me ready for job opportunities. However, I’m now unsure which path to pursue next—whether to focus on backend development with PHP and Laravel, or to dive into the JavaScript ecosystem with React and Node.js. This uncertainty has left me confused about how to advance my skills and present myself as a competent web developer.

TypeScript Bug : Type ‘null’ is not assignable to type ‘SetStateAction

This is my App.tsx file. So I was following a video with JavaScript, but while writing that in TypeScript VS Code is showing these bugs:

Source Code:

import React, { useEffect, useState } from 'react';
import './output.css'; // Adjust path if necessary
import {auth, provider} from './config' ;
import { signInWithPopup } from 'firebase/auth';
import Home from './Home';

function SignIn(){

  const [value,setValue] = useState('')
  const handleClick = () => {
    signInWithPopup(auth, provider).then((data) => {
      setValue(data.user.email)
      localStorage.setItem("email", data.user.email)
    })
  }

  useEffect(() => {
    setValue(localStorage.getItem('email'))
  })

return (
  <div>
  {value?<Home/>:
    <button onClick={handleClick} className='px-2 bg-blue-600 text-white hover:bg-blue-900 pt-2 pb-2 pl-3 pr-3 rounded-md'>Sign in with Google</button>
  }
  </div>
);
}
export default SignIn;

In line 12: data.user.email Argument of type ‘string | null’ is not assignable to parameter of type ‘SetStateAction’.
Type ‘null’ is not assignable to type ‘SetStateAction’.ts(2345)
(property) UserCredential.user: User

In line 12: data.user.email Argument of type ‘string | null’ is not assignable to parameter of type ‘string’.
Type ‘null’ is not assignable to type ‘string’.ts(2345)

In line 18: localStorage.getItem(’email’) Argument of type ‘string | null’ is not assignable to parameter of type ‘SetStateAction’.
Type ‘null’ is not assignable to type ‘SetStateAction’.ts(2345)

I expected writing js in ts would not make problem but in ts as i need to give certain types to variables may be that’s why these errors are occuring…

How to fix this?

Creating a virtual POS device interface

How should I start creating an interface to a virtual POS device? Just for the interface, I’m a little new to this :))

Since I’m new to this, I haven’t decided how to start yet. I’m sorry, I don’t have much idea about this. Please help…

415 Unsupported Media Type Error When Posting Data to Highlight Tab

I am working on a functionality that moves data from the Catalogue tab to the Description, Cart, and Highlight tabs in my application. The data is successfully copied from Catalogue to Cart and Description, but when I attempt to copy it to Highlight, I encounter a 415 Unsupported Media Type error.

Here are the relevant parts of my code:

Frontend Code:

const handleApplyButton = async () => {
  const updatedDescriptions = [];
  const updatedCarts = [];
  const updatedHighlights = [];

  const formatTime = (deciseconds) => {
    const totalSeconds = deciseconds / 10;
    const hours = Math.floor(totalSeconds / 3600);
    const minutes = Math.floor((totalSeconds % 3600) / 60);
    const seconds = (totalSeconds % 60).toFixed(1);
    return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(4, '0')}`;
  };


  catalogueData.forEach((row) => {
    const selectedFields = selectedRows[row.id];
    const startTime = !isNaN(row.startTime) ? formatTime(row.startTime) : row.startTime;
    const endTime = !isNaN(row.endTime) ? formatTime(row.endTime) : row.endTime;

    if (selectedFields?.description) {
      const dataToCopy = {
        name: row.description,
        start_time: startTime,
        end_time: endTime,
        x_coordinate: row.x,
        y_coordinate: row.y,
        photo: row.photo || "https://via.placeholder.com/50",
        description: row.description || "Product's Description",
        video_id: id,
        link: row.link || "default_link",
        user_id: cookies.auid,
      };
      updatedDescriptions.push(dataToCopy);
      console.log("Copying to Description:", dataToCopy);
    }
    if (selectedFields?.cart) {
      const dataToCopy = {
        id: uuidv4(),
        name: row.description,
        start_time: startTime,
        end_time: endTime,
        x_coordinate: row.x,
        y_coordinate: row.y,
        photo: row.photo || "https://via.placeholder.com/50",
        link: row.link || "default_link",
        product_cta: row.product_cta || "Buy Now",
        video_id: id, 
        price: row.price || 0,
      };
      updatedCarts.push(dataToCopy);
      console.log("Copying to Cart:", dataToCopy);
    }
    if (selectedFields?.highlight) {
      const dataToCopy = {
        name: row.description,
        start_time: startTime,
        end_time: endTime,
        x_coordinate: row.x,
        y_coordinate: row.y,
        video_id: id,
        link: row.link || "default_link",
        user_id: cookies.auid,
      };
      updatedHighlights.push(dataToCopy);
      console.log("Copying to Highlight:", dataToCopy);
    }
  });

  console.log('Updated Descriptions:', updatedDescriptions);
  console.log('Updated Carts:', updatedCarts);
  console.log('Updated Highlights:', updatedHighlights);

  try {
    for (const description of updatedDescriptions) {
      const res = await postFormData('VideoProduct/addProductDescription', description, {}, cookies.t);
      console.log('Updated Description Data:', description);
    }

    for (const cart of updatedCarts) {
      const res = await postFormData('VideoProduct/addProductCard', cart, {}, cookies.t);
      console.log('Updated Cart Data:', cart);
    }

    for (const highlight of updatedHighlights) {
      console.log("Sending highlight data:", highlight);
      const res = await postFormData('VideoProduct/addProductHighlight', highlight, {}, cookies.t);
      console.log('Response from API for Highlight:', res);
      console.log('Updated Highlight Data:', highlight);
    }

    console.log('Data successfully copied and saved to the server.');
  } catch (error) {
    console.error('Error saving data:', error);
  }
};

postFormData method:

export const postFormData = async (endpoint, data, params, token) => {
  try {
    console.log("POST Request Details:", { endpoint, data, params, token });
    const response = await instance.post(endpoint, data, {
      params,
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "multipart/form-data",
      },
    });
    console.log("POST Response:", response.data);
    return response.data;
  } catch (error) {
    console.error("Error posting data:", error);
    throw error;
  }
};
**Backend Method**:

[Authorize]
[HttpPost("addProductHighlight")]
public async Task<ActionResult> AddHighlight(AddProductHighlight request)
{
    try
    {
        var addHiglight = await _productService.AddHighlight(request);
        return Ok(addHiglight);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, ProductConstant.FailedToAddHighlight);
        return StatusCode(500, ex);
    }
}

public class AddProductHighlight
{
    public string? name { get; set; }
    public Guid video_id { get; set; }
    public string? start_time { get; set; }  // in seconds
    public string? end_time { get; set; }
    public double? x_coordinate { get; set; }
    public double? y_coordinate { get; set; }
    public Guid? user_id { get; set; }
    public string? link { get; set; }

}

Here is the screenshot of console output if it helps: Console Output

What I’ve tried:

  • Verified that the data structure matches the expected DTO in the backend.
  • Ensured that the request headers include the Content-Type: multipart/form-data.
  • Checked the API endpoint and method signatures.

Any help or guidance would be greatly appreciated. Thank you!

How to Return Total of the month based on dates in JavaScript(React)

I wrote a hook to calculate sales based on month to set data for chart.

its work fine, but I’m not satisfied.

is there a different or easy way to avoid repeating and make code clean and extendable!

note: I’m not working with companies or team – ( self learning )

i want to calculate the total per day in the month and return new array of objects

Function:



const month = (date) => new Date(date).toLocaleString('default', { month: 'long' });

export const useGetChartData = (orders) => {

  const orderTotal = orders.length
  const orderTotalsArray = orders.map(order => (+order.total) + (+order.total_tax));
  const sumOrders = orderTotalsArray?.reduce((inc, a) => inc + a, 0);
  const getMonthFromDateAndTotals = orders?.map(order => (
    {
      date: (order.date_paid ? month(order.date_paid) : month(order.date_modified)),
      total: +order.total + +order.total_tax
    }));

  const sendToChart = getMonthFromDateAndTotals.filter(o => o.total > 0);
  //filter!
  const January = sendToChart.filter((d) => d.date == 'January')
  const February = sendToChart.filter((d) => d.date == 'February')
  const March = sendToChart.filter((d) => d.date == 'March')
  const April = sendToChart.filter((d) => d.date == 'April')
  const May = sendToChart.filter((d) => d.date == 'May')
  const June = sendToChart.filter((d) => d.date == 'June')
  const July = sendToChart.filter((d) => d.date == 'July')
  const August = sendToChart.filter((d) => d.date == 'August')
  const September = sendToChart.filter((d) => d.date == 'September')
  const October = sendToChart.filter((d) => d.date == 'October')
  const November = sendToChart.filter((d) => d.date == 'November')
  const December = sendToChart.filter((d) => d.date == 'December')
  // 
  const totalsPerMonths = [
    //reduce! 
    { month: 'January', total: January?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'February', total: February?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'March', total: March?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'April', total: April?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'May', total: May?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'June', total: June?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'July', total: July?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'August', total: August?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'September', total: September?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'October', total: October?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'November', total: November?.reduce((inc, a) => inc + a.total, 0) },
    { month: 'December', total: December?.reduce((inc, a) => inc + a.total, 0) },
    // 
  ];

  const dataVisualizationToChart = totalsPerMonths.filter(vd => vd.total > 0);
  return {
    dataVisualizationToChart,
    orderTotal,
    sumOrders
  };
};

usage:

  const { data: orders, isLoading: ordersLoading, errors: orderErrors} = useGetShopData("orders");
  const { dataVisualizationToChart, sumOrders } = useGetChartData(orders)

Return :

{
  "dataVisualizationToChart": [
    {"month": "February","total": 1875.96},
    { "month": "March", "total": 1362.46},
    { "month": "April","total": 66.05000000000004},
  ],
  "orderTotal": 70,
  "sumOrders": 13064
}```



Using Javascript the append didn’t work this is ASP.NET CORE

My problem on this the contact fields is not appending on the modal. Based on the console.log I have 2 values of contacts. What’s wrong in the javascript why the fields is not showing up?

I want to show up the details of the contacts of the user.

The process is i have an table with the list of users then there is a View button of each users to view all the details of that user. Now when the user clicks the view button it displays the details in the modal. Now the problem in the modal the contact details is not appending the contactdetails
User.js

$(document).ready(function () {
    $('#usersModal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget);
        var users = button.data('users');

        $('.view-users-btn').click(function () {
            var usersData = $(this).data('users');
            console.log(usersData);

            // Set resident information
            $('#modalUserID').val(usersData.UserID);
            $('#modalFirstName').val(usersData.FirstName);
            $('#modalMiddleName').val(usersData.MiddleName);
            $('#modalLastName').val(usersData.LastName);
            $('#modalEmail').val(usersData.Email);
            $('#modalPassword').val(usersData.Password);

            // Set dropdown value based on Status
            $('#modalStatus').val(usersData.Status);

            // Handle contacts
            var contacts = usersData.Contacts || [];
            var contactList = $('#modalContacts');
            contactList.empty(); // Clear previous contact inputs

            contacts.forEach(function (contact, index) {
                // Create input fields for each contact

                var contactInput = '<div class="row">';

                // Create dropdown options from ViewBag.AddressTypes
                var contactTypeDropdown = $('#contactType' + index); // This line might not be necessary

                contactInput += '<div class="col-md-6 mb-3">';
                contactInput += '<label for="contactType' + index + '">Contact Type:</label>';
                contactInput += '<select id="contactType' + index + '" class="form-control">';
                ViewBag.ContactTypes.forEach(function (contactType) {
                    var option = $('<option>');
                    option.val(contactType.CODE_VALUE);
                    option.text(contactType.Description);
                    $('#contactType' + index).append(option);
                });
                contactInput += '</select>'; // Added closing tag
                contactInput += '</div>';
                contactInput += '<div class="address-group col-md-6 mb-3">';
                contactInput += '<label for="contactNumber' + index + '">Contact Number:</label>';
                contactInput += '<input id="contactNumber' + index + '" class="form-control" type="text" value="' + contact.ContactNumber + '" readonly>';
                contactInput += '</div>';
                contactInput += '</div>';
                contactList.append(contactInput);
                $('#modalContacts').append(contactInput);

            });
        });
    });
});

This is the form in Modal design

<div class="modal fade" id="usersModal" tabindex="-1" role="dialog" aria-labelledby="usersModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="usersModalLabel">User Details</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <div class="container mt-5">
                    <form id="residentForm" asp-controller="User" asp-action="Update" method="post">
                        @Html.AntiForgeryToken()
                        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                        <div class="row">
                            <div class="col-md-12">
                                <div class="row">
                                    <div class="form-group col-md-2 mb-3">
                                        <label for="modalUserID">User ID:</label>
                                        <input for="modalUserID" type="text" id="modalUserID" class="form-control" readonly>
                                    </div>
                                    </div>
                                <div class="row">
                                   
                                    <div class="form-group col-md-4 mb-3">
                                        <label for="modalFirstName">First Name:</label>
                                        <input for="modalFirstName" type="text" id="modalFirstName" class="form-control" readonly>
                                    </div>
                                    <div class="form-group col-md-4 mb-3">
                                        <label for="modalMiddleName">Middle Name:</label>
                                        <input for="modalMiddleName" type="text" id="modalMiddleName" class="form-control" readonly>
                                    </div>
                                    <div class="form-group col-md-4 mb-3">
                                        <label for="modalLastName">Last Name:</label>
                                        <input for="modalLastName" type="text" id="modalLastName" class="form-control" readonly>
                                    </div>
                                </div>
                                <div class="row">
                                
                                <div class="form-group col-md-4 mb-3">
                                    <label for="modalEmail">Email:</label>
                                    <input for="modalEmail" type="text" id="modalEmail" class="form-control" readonly>
                                </div>
                                <div class="form-group col-md-4 mb-3">
                                    <label for="modalPassword">Password :</label>
                                    <input for="modalPassword" type="text" id="modalPassword" class="form-control" readonly>
                                </div>
                                    <div class="form-group col-md-4 mb-3">
                                        <label for="modalStatus">Status:</label>
                                        <select id="modalStatus" class="form-control">
                                            <option value="1">Unlocked</option>
                                            <option value="2">Locked</option>
                                        </select>
                                    </div>
                                </div>
                               
                            </div>
                        </div>
                        <!-- Contacts -->
                        <h5>Contacts</h5>
                        <div id="modalContacts"></div>
                        <button type="submit" class="btn btn-success" id="submitButton" disabled>Submit</button>
                    </form>
                </div>
            </div>

        </div>
    </div>
</div>

UserController

public async Task<IActionResult> Manage()
{
    //DataTable users =  sqldb.SPCreateTable(allSP.spGetUsers);

    var getAccountStatus = sqldb.SPCreateTable(allSP.sp_GetAccountStatus);
    var additional = new Additional();
    var getContactType = sqldb.SPCreateTable(allSP.sp_getContactType);
    var additionalType = new Additional();

    foreach (DataRow row in getContactType.Rows)
    {
        var contactTypeModel = new ContactTypeModel
        {
            CODE_VALUE = Convert.ToInt32(row.Field<string>("CODE_VALUE")),
            Description = row.Field<string>("Description")
        };

        additionalType.ContactTypes.Add(contactTypeModel);
    }

    // Pass the Additional instance to the view
    ViewBag.ContactTypes = additionalType;

    foreach (DataRow row in getAccountStatus.Rows)
    {
        var accountStatusTypeModel = new AccountStatusTypeModel
        {
            CODE_VALUE = Convert.ToInt32(row.Field<string>("CODE_VALUE")),
            Description = row.Field<string>("Description"),
            IsLockedOut = row.Field<string>("CODE_VALUE") == "2"
        };

        additional.AccountStatus.Add(accountStatusTypeModel);
    }

    // Pass the Additional instance to the view
    ViewBag.AccountStatus = additional;
    var users = await _context.WMS_User
                        .Include(r => r.Contacts)
                        .Include(r => r.UserDetails)
                        .ToListAsync();

    //var viewUserModel = new UserViewModel
    //{
    //    Users = SQLDB.ConvertDataTableToList<UserView>(users)
    //};
    var viewUserModel = users.Select(r => new UserView
    {
        UserID = r.UserID,
        FirstName = r.UserDetails.FirstName,
        MiddleName = r.UserDetails.MiddleName,
        LastName = r.UserDetails.LastName,
        Password = r.Password,
        Role = r.Role,
        Status = r.Status,
        Email = r.UserDetails.Email,
        CreatedDate = r.CreatedDate,
        ModifiedBy = r.ModifiedBy,
        ModifiedDate = r.ModifiedDate,
        Contacts = r.Contacts.Select(c => new UserContact
        {
            UserContactID = c.UserContactID,
            UserID = c.UserID,
            ContactType = c.ContactType,
            ContactNumber = c.ContactNumber,
            CreationDate = c.CreationDate,
            ModifiedBy = c.ModifiedBy,
            ModifiedDate = c.ModifiedDate
        }).ToList()
    }).ToList();

    return View(viewUserModel);
}

enter image description here

How can i mute/desmute a microphone using WebRTC and PeerJs?

I’m trying to get the user to mute their microphone so that the other user on the call can’t hear them, but I’ve failed in every attempt.

I just wish the caller or callee could mute themselves so that one can’t hear the other.

This is my code:

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    navigator.mediaDevices.getUserMedia({ audio: true }).then(function(stream) {
        let currentCall = null;
        let remoteAudioStream = null;
        var localStream = stream;

        // Atender a chamada e fornecer a MediaStream
        peer.on('call', function(call) {
            currentCall = call;
            
            incommingCallToast.show();
            document.getElementById('callerUsername').innerText = call.metadata.callerUsername;

            document.getElementById('acceptCallButton').onclick = function() {
                incommingCallToast.hide();
                call.answer(localStream);  // Use apenas localStream aqui
                call.on('stream', function(remoteStream) {
                    remoteAudioStream = remoteStream;
                    var audioElement = new Audio();
                    audioElement.srcObject = remoteStream;
                    audioElement.play();
                    document.getElementById('endCallButton').style.display = 'flex';
                });

                call.on('close', function() {
                    incommingCallToast.hide();
                    showErrorToast('Chamada encerrada.');
                    document.getElementById('endCallButton').style.display = 'none';
                });
            };

            document.getElementById('rejectCallButton').onclick = function() {
                incommingCallToast.hide();
                call.close();
            };
        });

        // Realizar a chamada ao clicar no botão
        document.getElementById('audioCallButton').addEventListener('click', function() {
            $.ajax({
                url: `/friends/${currentFriendId}`,
                method: 'GET',
                success: function (data) {
                    if (data.friend) {
                        const friend = data.friend;

                        if(!friend.online)
                            return showErrorToast("O seu amigo está offline, portanto não pode receber chamadas.");

                        document.getElementById('calleeUsername').innerText = friend.username;
                        callingToast.show();

                        console.log('Calling peer ID: ' + friend.peerid);

                        var call = peer.call(friend.peerid, localStream, {
                            metadata: { callerUsername: currentUsername }
                        });

                        currentCall = call;

                        call.on('stream', function(remoteStream) {
                            remoteAudioStream = remoteStream;
                            var audioElement = new Audio();
                            audioElement.srcObject = remoteStream;
                            audioElement.play();
                            document.getElementById('endCallButton').style.display = 'flex';
                            callingToast.hide();
                        });


                        document.getElementById('rejectCallButton').onclick = function() {
                            callingToast.hide();
                            call.close();
                        };

                        call.on('close', function(remoteStream) {
                            callingToast.hide();
                            showErrorToast('Chamada encerrada.');
                            document.getElementById('endCallButton').style.display = 'none';
                        });

                    } else {
                        showErrorToast('Dados do amigo não encontrado.');
                    }
                },
                error: function (jqXHR) {
                    const errorMessage = jqXHR.responseJSON ? jqXHR.responseJSON.error : 'Dados do amigo não encontrados.';
                    showErrorToast(errorMessage);
                }
            });
        });

        document.getElementById('endCallButton').onclick = function() {
            callingToast.hide();

            if (currentCall) {
                currentCall.close();
                currentCall = null;
                document.getElementById('endCallButton').style.display = 'none';
                showErrorToast('Chamada encerrada.');
            } else {
                document.getElementById('endCallButton').style.display = 'none';
                showErrorToast('Nenhuma chamada ativa para encerrar.');
            }
        };

        // Controlar volume e mute
        var muteButton = document.getElementById('muteButton');
        var headphoneButton = document.getElementById('headphoneButton');
        var volumeSlider = document.getElementById('volumeSlider');
        var isMuted = false;

        muteButton.addEventListener('click', function() {
            const icon = muteButton.querySelector('i');
            if (remoteAudioStream) {
                remoteAudioStream.getAudioTracks().forEach(track => track.enabled = !track.enabled);
        
                if (isMuted) {
                    isMuted = true;
                    icon.classList.remove('fa-microphone');
                    icon.classList.add('fa-microphone-slash');
                    icon.style.color = '#FF6347'; // Define a cor para '#FF6347' quando o microfone está mutado
                } else {
                    isMuted = false;
                    icon.classList.remove('fa-microphone-slash');
                    icon.classList.add('fa-microphone');
                    icon.style.color = 'white'; // Define a cor para 'white' quando o microfone está desmutado
                }
            }
        });
    }).catch(function(err) {
        showErrorToast('Failed to get local stream', err);
    });
} 
else {
    showErrorToast('Seu navegador não suporta a API getUserMedia.');
}

As you can see, I’m using the getAudioTracks() function to mute the user, but I’m still not successful, what exactly am I doing wrong?

By the way, the user can establish a connection, I can hear and be heard, I can end the call, etc., the only problem is the mute/unmute, besides, am I using good practices in this code?

Element type is invalid: expected a string or a class/function but got: undefined React Native

Here is the error:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it’s defined in, or you might have mixed up default and named imports.

Here is the code:

import React, { useEffect, useState, useCallback } from "react";
import { View, Text, StyleSheet, Image, StatusBar } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { useFocusEffect } from "@react-navigation/native";
import { LinearGradient } from "expo-linear-gradient";
import { FocusAwareStatusBar } from "./_layout";

export default function Home(){
    const [totals, setTotals] = useState({
        Clinical: 0,
        Extracurricular: 0,
        Shadowing: 0,
        Volunteer: 0,
        Research: 0,
      });
      const [userName, setUserName] = useState("");
      const [isDarkMode, setIsDarkMode] = useState(false);
    
      useEffect(() => {
        const fetchUserData = async () => {
          try {
            const jsonValue = await AsyncStorage.getItem("userData");
            const userData = jsonValue != null ? JSON.parse(jsonValue) : null;
            if (userData) {
              setUserName(userData.name);
            }
          } catch (error) {
            console.error("Error fetching user data", error);
          }
        };
    
        const checkDarkModeStatus = async () => {
          try {
            const jsonValue = await AsyncStorage.getItem("isDark");
            if (jsonValue != null) {
              const darkMode = JSON.parse(jsonValue);
              setIsDarkMode(darkMode);
            } else {
              console.log("no theme settings found!");
            }
          } catch (error) {
            console.error("Error checking dark mode status", error);
          }
        };
    
        checkDarkModeStatus();
        fetchUserData();
      }, []);
    
      const calculateTotals = async () => {
        try {
          const jsonValue = await AsyncStorage.getItem("formData");
          const formData = jsonValue != null ? JSON.parse(jsonValue) : [];
    
          const newTotals = {
            Clinical: 0,
            Extracurricular: 0,
            Shadowing: 0,
            Volunteer: 0,
            Research: 0,
          };
    
          formData.forEach((data) => {
            if (data.number && data.category) {
              newTotals[data.category] += parseFloat(data.number);
            }
          });
    
          setTotals(newTotals);
        } catch (error) {
          console.error("Error calculating totals", error);
        }
      };
    
      useFocusEffect(
        useCallback(() => {
          calculateTotals();
        }, [])
      );
    
      const renderItem = (item) => (
        <View
          key={item.category}
          style={isDarkMode ? styles.smallCardDark : styles.smallCard}
        >
          <Text style={styles.value}>{item.value}</Text>
          <Text style={styles.label}>{item.category}</Text>
        </View>
      );
    
      const data = [
        { category: "Clinical", value: totals.Clinical },
        { category: "Extracurricular", value: totals.Extracurricular },
        { category: "Shadowing", value: totals.Shadowing },
        { category: "Volunteer", value: totals.Volunteer },
        { category: "Research", value: totals.Research },
      ];
    
      return (
        <>
          <FocusAwareStatusBar hidden backgroundColor="#ecf0f1" />
    
          {isDarkMode == false && (
            <View style={styles.container}>
              <StatusBar
                barStyle="light-content"
                backgroundColor="transparent"
                translucent
              />
              <View style={styles.bannerContainer}>
                <Image
                  source={require("../../assets/banner.jpeg")} // Local banner image
                  style={styles.bannerImage}
                  resizeMode="cover"
                />
                <LinearGradient
                  colors={["rgba(0,0,0,0)", "#529bbb"]} // Transparent to desired color
                  style={styles.overlay}
                />
              </View>
              <LinearGradient
                colors={["#529bbb", "#eeaeca"]}
                style={styles.backgroundGradient}
              >
                <View style={styles.centralContainer}>
                  <View style={styles.centralCard}>
                    <Text style={styles.greeting}>Hello {userName}</Text>
                    <View style={styles.row}>{data.map(renderItem)}</View>
                  </View>
                </View>
              </LinearGradient>
            </View>
          )}
          {isDarkMode && (
            <View style={styles.container}>
              <StatusBar
                barStyle="light-content"
                backgroundColor="transparent"
                translucent
              />
              <View style={styles.bannerContainer}>
                <Image
                  source={require("../../assets/banner_wb.png")} // Local banner image
                  style={styles.bannerImage}
                  resizeMode="cover"
                />
              </View>
              <LinearGradient
                colors={["#181818", "#181818"]}
                style={styles.backgroundGradient}
              >
                <View style={styles.centralContainer}>
                  <View style={styles.centralCardDark}>
                    <Text style={styles.greeting}>Hello {userName}</Text>
                    <View style={styles.row}>{data.map(renderItem)}</View>
                  </View>
                </View>
              </LinearGradient>
            </View>
          )}
        </>
      );
}

const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: "center",
      alignItems: "center",
      color: "#EEAAEA",
    },
    bannerContainer: {
      position: "relative",
      width: "100%",
      height: 250, // Adjust the height as needed to move the picture down
      overflow: "hidden",
    },
    bannerImage: {
      width: "100%",
      height: "100%",
      backgroundColor: "#232323",
      borderColor: "#EEAAEA",
      borderBottomWidth: 6,
      borderTopWidth: 0,
    },
    overlay: {
      position: "absolute",
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
    },
    backgroundGradient: {
      flex: 1,
      width: "100%",
      justifyContent: "center",
      alignItems: "center",
    },
    centralContainer: {
      width: "90%",
      marginTop: -125, // Adjust the margin top value to move the container higher
      alignItems: "center", // Center horizontally
  
      backgroundColor: "transparent",
    },
    centralCard: {
      backgroundColor: "#ffffff",
  
      padding: 20,
      borderRadius: 10,
      marginTop: 20,
      marginBottom: 20,
      shadowColor: "#000",
      shadowOffset: {
        width: 0,
        height: 2,
      },
      shadowOpacity: 0.1,
      shadowRadius: 4,
      elevation: 5,
      alignItems: "center",
  
      backgroundColor: "transparent",
      borderColor: "white",
      borderWidth: 3,
      color: "white",
    },
    centralCardDark: {
      backgroundColor: "#ffffff",
  
      padding: 20,
      borderRadius: 10,
      marginTop: 20,
      marginBottom: 20,
      shadowColor: "#000",
      shadowOffset: {
        width: 0,
        height: 2,
      },
      shadowOpacity: 0.1,
      shadowRadius: 4,
      elevation: 5,
      alignItems: "center",
  
      backgroundColor: "#232323",
  
      color: "white",
    },
    greeting: {
      fontSize: 24,
      fontWeight: "bold",
      marginBottom: 20,
      color: "white",
    },
    row: {
      flexDirection: "row",
      flexWrap: "wrap",
      justifyContent: "center",
    },
    smallCard: {
      backgroundColor: "#ffffff",
      padding: 10,
      borderRadius: 10,
      margin: 5,
      width: "45%", // Adjust width to fit two columns with margins
      shadowColor: "#000",
      shadowOffset: {
        width: 0,
        height: 2,
      },
  
      shadowOpacity: 0.25,
      shadowRadius: 4,
      elevation: 5,
      alignItems: "center",
      backgroundColor: "transparent",
  
      borderColor: "white",
      borderWidth: 1,
    },
    smallCardDark: {
      padding: 10,
      borderRadius: 10,
      margin: 5,
      width: "45%", // Adjust width to fit two columns with margins
      shadowColor: "#000",
      shadowOffset: {
        width: 0,
        height: 2,
      },
  
      shadowOpacity: 0.25,
      shadowRadius: 4,
      elevation: 5,
      alignItems: "center",
      backgroundColor: "#3E3E3E",
    },
    label: {
      fontWeight: "bold",
      fontSize: 12,
      color: "white",
    },
    value: {
      fontSize: 20,
      color: "white",
      fontWeight: "700",
      marginTop: 5,
    },
  });

This was working before, when I was using Expo Go and React Navigation, but when I switched to a development build and Expo Router, I am encountering this problem. This was a screen that could be navigated to using router.navigate("/home");. Also I used this in a tabbar like this:

    import { Tabs } from "expo-router";
    import { Home } from "lucide-react-native";

    export default function TabLayout() {
      return (
        <Tabs screenOptions={{ tabBarActiveTintColor: 'blue', headerShown: false }}>
          <Tabs.Screen
            name="Home"
            options={{
              title: 'Home',
              tabBarIcon: ({ color }) => <Home size={28} name="home" color={color} />,
            }}
          />
          <Tabs.Screen
            name="index"
            options={{
              title: 'Index',
              tabBarIcon: ({ color }) => <Home size={28} name="cog" color={color} />,
            }}
          />
        </Tabs>
      );
    }

What could be the problem? Any help is appreciated.

How to bind on function of jqury after clling off function of jquery

I have to call same function after clicking a button but not working

After off jquery function trigger event is not calling

How can i call on click function in jquery

Please any one give me suggestion to solve

$(document).ready(function(){
 $("input").on("click",function(){
    $("input").after(" Text marked!");
  });
  $("input").off("click");
  $("button").on("dblclick",function(){
  
    $("input").trigger("click");
  });
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<input type="text" value="Hello World"><br><br>

<button>Trigger the select event for the input field</button>