How to store instance of a class in Redis?

In NestJS framework, I have an array of object, each object contains an instance of my car class, this class have a lot of public and private property and some method. Since my project doesn’t have any database except Redis and sometimes restart unexpectedly; I want to store this array of object into Redis DB every one minute.

My main TypeScript file is like this:

    class car {
        public name ;
        private model;
        constructor(car_name){
            this.name = car_name;
        }
        start() {
            console.log(this.name + ' start the engine');
        }
    }

    let myBMW = new car('bmw');
    let myNISSAN = new car('nissan');

    let arr_of_obj = [
        {
            name : "bmw",
            type : "racing",
            mymethod : myBMW
        },
        {
            name : "nissan",
            type : "sedan",
            mymethod : myNISSAN
        }
    ];

and my Redis service is:

import { Inject, Injectable } from '@nestjs/common';
import Redis from 'ioredis';


@Injectable()
export class RedisDbService {
  constructor(@Inject('REDIS_CLIENT') private readonly redisClient: Redis) {}

  async set(key: string, value: any, ex: number) {
    return await this.redisClient.set(key, JSON.stringify(value), 'EX', ex);
  }

  async get(key: string) {
    const data = await this.redisClient.get(key);
    if(data == null){
      return [];
    }
    return JSON.parse(data);
  }

  async deletekey(key: string) {
    return this.redisClient.del(key);
  }
}

So, when I use this line of codes I get error start() is not a function:

this.redisService.set('car_in_redis', myBMW , 300);
let new_car = await this.redisService.get('car_in_redis');
new_car.start();

I know the JSON.stringify() and JSON.parse() is the reason but how to store an instance completely inside Redis?

Changes in JSON file are not reflecting

I am trying to create API and for client purpose i am using node postman.In delete method client is able to delete the json object but it is not reflecting in json file.

const express = require("express");
const user = require("./data.json");
const fs = require("fs");
const app = express();

app.route("/user/:id").delete((req,res)=>{
    const body = req.params.id;
    console.log(eval(body));
    user.map((obj)=>{
        if(obj.id==eval(body)){
            console.log("matched");
            console.log(user.indexOf(obj));
            delete user[user.indexOf(obj)];
            console.log("successfully removed=>"+obj);
        }
    })
})

enter image description here

enter image description here

enter image description here

enter image description here

JSON file data:

[
    {
        "id": 1,
        "first_name": "Lilah",
        "last_name": "Smitherham",
        "email": "[email protected]",
        "gender": "Female",
        "title": "Accountant I"
    },
    {
        "id": 2,
        "first_name": "Donaugh",
        "last_name": "Zanni",
        "email": "[email protected]",
        "gender": "Male",
        "title": "Quality Control Specialist"
    },
    {
        "id": 3,
        "first_name": "Neila",
        "last_name": "Hillyatt",
        "email": "[email protected]",
        "gender": "Female",
        "title": "Registered Nurse"
    },
    {
        "id": 4,
        "first_name": "Granny",
        "last_name": "Baszkiewicz",
        "email": "[email protected]",
        "gender": "Male",
        "title": "Teacher"
    },
    {
        "id": 5,
        "first_name": "Reinaldos",
        "last_name": "Christophe",
        "email": "[email protected]",
        "gender": "Male",
        "title": "Recruiter"
    },
    {
        "id": 6,
        "first_name": "Zebedee",
        "last_name": "Bulford",
        "email": "[email protected]",
        "gender": "Male",
        "title": "Programmer Analyst II"
    },
    {
        "id": 7,
        "first_name": "Maxie",
        "last_name": "Rudinger",
        "email": "[email protected]",
        "gender": "Female",
        "title": "Geologist I"
    },
    {
        "id": 8,
        "first_name": "Vivi",
        "last_name": "Hiscocks",
        "email": "[email protected]",
        "gender": "Female",
        "title": "Software Consultant"
    },
    {
        "id": 9,
        "first_name": "Adlai",
        "last_name": "Charer",
        "email": "[email protected]",
        "gender": "Male",
        "title": "Senior Cost Accountant"
    },
    {
        "id": 10,
        "first_name": "Loydie",
        "last_name": "Stribling",
        "email": "[email protected]",
        "gender": "Male",
        "title": "VP Product Management"
    },
    {
        "id": 11,
        "first_name": "Farly",
        "last_name": "Champness",
        "email": "[email protected]",
        "gender": "Male",
        "title": "Operator"
    },
    {
        "id": 12,
        "first_name": "Jasper",
        "last_name": "Dollimore",
        "email": "[email protected]",
        "gender": "Male",
        "title": "Media Manager IV"
    }
//so on 1000 users.
]

where is the mistake?

mediaRecorder: removing a chunk before building the Blob does not provide the expected results

The purpose of the test code in the snippet is to build a speech interactively, chunk by chunk.
If you don’t like the last recorded chunk, you can simply remove it from the chunks array (chunks.pop()) and keep recording new chunks.
Then you can build the blob from the resulting chunks array.
The problem is that even when a chunk is removed, it leaves a ‘silence’ in the final audio file that lasts for the entire duration of the removed chunk.
It seems that the chunks have some sort of timestamp and are not simply concatenated.
How can I achieve my goal? Thank you.

PS: the snippets does not work from inside stackoverflow because there is no authorization to record audio.

<!DOCTYPE html>
<html>
<head>
    <title>MediaRecorder Chunks Test</title>
</head>
<body>
    <button id="startRecord">Start Recording</button>
    <button id="pauseRecord" disabled>Pause Recording</button>
    <button id="stopRecord" disabled>Stop Recording</button>
    <button id="playRecording" disabled>Play Recording</button>
    <button id="popChunk" disabled>Pop Last Chunk</button>

    <audio id="audioPlayback" controls></audio>

    <script>
        let mediaRecorder;
        let chunks = [];
        let audioURL;
        let recording = false;

        document.getElementById('startRecord').addEventListener('click', startRecording);
        document.getElementById('pauseRecord').addEventListener('click', pauseRecording);
        document.getElementById('stopRecord').addEventListener('click', stopRecording);
        document.getElementById('playRecording').addEventListener('click', playRecording);
        document.getElementById('popChunk').addEventListener('click', popLastChunk);

        function startRecording() {
            if (!recording) {
                navigator.mediaDevices.getUserMedia({ audio: true })
                    .then(stream => {
                        mediaRecorder = new MediaRecorder(stream);

                        mediaRecorder.ondataavailable = event => {
                            if (event.data.size > 0) {
                                chunks.push(event.data);
                                console.log("Chunk recorded: ", event.data.size, " bytes");
                            }
                        };

                        mediaRecorder.onstop = () => {
                            recreateBlob();
                        };

                        mediaRecorder.start();
                        recording = true;
                        console.log("MediaRecorder started");

                        document.getElementById('startRecord').innerText = 'Resume Recording';
                        document.getElementById('pauseRecord').disabled = false;
                        document.getElementById('stopRecord').disabled = false;
                        document.getElementById('popChunk').disabled = false;
                    })
                    .catch(error => {
                        console.error("getUserMedia error:", error);
                    });
            } else {
                mediaRecorder.resume();
                console.log("MediaRecorder resumed");

                document.getElementById('pauseRecord').disabled = false;
                document.getElementById('startRecord').disabled = true;
            }
        }

        function pauseRecording() {
            mediaRecorder.pause();
            console.log("MediaRecorder paused");
            mediaRecorder.requestData(); //Raise a dataavailable event
            document.getElementById('startRecord').disabled = false;
            document.getElementById('pauseRecord').disabled = true;
        }

        function stopRecording() {
            mediaRecorder.stop();
            console.log("MediaRecorder stopped");

            document.getElementById('stopRecord').disabled = true;
            document.getElementById('playRecording').disabled = false;
            document.getElementById('pauseRecord').disabled = true;
            document.getElementById('startRecord').disabled = true;
        }

        function recreateBlob() {
            const blob = new Blob(chunks, { type: mediaRecorder.mimeType });
            audioURL = window.URL.createObjectURL(blob);
            console.log("Recreated blob URL:", audioURL);

            document.getElementById('audioPlayback').src = audioURL;
        }

        function playRecording() {
            const audio = document.getElementById('audioPlayback');
            audio.play();
            console.log("Playing recording");
        }

        function popLastChunk() {
            if (chunks.length > 0) {
                chunks.pop();
                console.log("Last chunk removed. Remaining chunks:", chunks.length);
                recreateBlob();
            } else {
                console.warn("No chunks to pop.");
            }
        }
    </script>
</body>
</html>

Axis extent option doesn’t set default subchart for timeseries axis

I’m beginner with billboard.js.
I have a big payload of data starting from 1980 and ending to now (2024). I want to first show only the last 10 years of the data and then being able to zoom out or in.
From what I understand on the billboard doc, I have to use the axis.x.extent option to set a default subchart.

But nothing happens, whatever I do with the extent option nothing is changing on my graph.

Any ideas of how I could do what I’m trying to do ?

Here is a code example

// base css
import 'billboard.js/dist/theme/insight.css';
import bb from 'billboard.js';
import * as d3 from 'd3';

// for ESM environment, need to import modules as:
// import bb, {area, zoom} from "billboard.js"

var chart = bb.generate({
  data: {
    x: 'x',
    json: {
      Temperature: [
        '29.39',
        '29.7',
        '29.37',
        '28.87',
        '28.62',
        '27.72',
        '27.61',
        '27.82',
        '27.48',
        '26.78',
        '26.62',
        '26.64',
        '26.29',
        '26.01',
        '25.84',
        '25.07',
        '24.85',
        '24.01',
        '23.83',
        '22.8',
        '23',
        '22.64',
        '22.77',
        '22.64',
        '22.64',
        '22.62',
        '22.51',
        '21.42',
        '21.18',
        '20.93',
        '20.66',
        '20.48',
        '20.7',
        '21.24',
        '22.14',
        '22.78',
        '23.43',
        '23.16',
        '27.48',
        '26.78',
        '26.62',
        '26.64',
        '26.29',
        '26.01',
        '25.84',
        '25.07',
        '24.85',
        '24.01',
      ],
      x: [
        '01-01-2015',
        '02-01-2015',
        '03-01-2015',
        '04-01-2015',
        '05-01-2015',
        '06-01-2015',
        '07-01-2015',
        '08-01-2015',
        '09-01-2015',
        '10-01-2015',
        '11-01-2015',
        '12-01-2015',
        '01-01-2016',
        '02-01-2016',
        '03-01-2016',
        '04-01-2016',
        '05-01-2016',
        '06-01-2016',
        '07-01-2016',
        '08-01-2016',
        '09-01-2016',
        '10-01-2016',
        '11-01-2016',
        '12-01-2016',
        '01-01-2017',
        '02-01-2017',
        '03-01-2017',
        '04-01-2017',
        '05-01-2017',
        '06-01-2017',
        '07-01-2017',
        '08-01-2017',
        '09-01-2017',
        '10-01-2017',
        '11-01-2017',
        '12-01-2017',
        '01-01-2018',
        '02-01-2018',
        '03-01-2018',
        '04-01-2018',
        '05-01-2018',
        '06-01-2018',
        '07-01-2018',
        '08-01-2018',
        '09-01-2018',
        '10-01-2018',
        '11-01-2018',
        '12-01-2018',
      ],
    },
    type: 'area', // for ESM specify as: area()
    xFormat: '%m-%d-%Y',
  },
  axis: {
    x: {
      tick: {
        fit: false,
        count: 5,
      },
      type: 'timeseries',
      extent: ['12-01-2016', '12-01-2018'],
    },
  },
  zoom: {
    enabled: true, // for ESM specify as: zoom()
  },
  tooltip: {
    format: {
      title: function (x) {
        return d3.timeFormat('%Y-%m-%d')(x);
      },
    },
  },
  point: {
    focus: {
      only: true,
    },
  },
  bindto: '#xAxisTickTimeseries',
});

Here is a stackblitz of the example

Thank you

Clearing the browser history and django session

I have an application in django, in it you can add a tourist tour to your cart, the basket is stored in the session. The tour has a model, and the models field is available.It is responsible for the available seats of the tour. When adding a tourist tour to the cart, the available field is reduced by 1 and so on. When I add a tour to the cart, it will be in session, then I will clear the browser history, the session will be deleted, but the number of available seats will not change.How do I catch the history deletion event so that I can call the update_available() function to return free spaces?

I’m thinking of trying to catch the history cleanup event, call fetch, and call the update_available() function in python. but I didn’t find anything about such an event on the Internet.

Is it bad practice to pass block level constants as arguments into a function? [closed]

I’m wondering if it is bad practice or if it makes it harder to read if you define constants outside of a function and then pass them into the function as arguments?

const mainFunction = () => {
    const x = document.getElementById("example");
    y = subFunction1(x);
    z = subFunction2(x);
};

const subFunction1 = (x) => {
    // do something with x
};

const subFunction2 = (x) => {
    // do something else with x
};

I’m defining a constant in mainFunction and passing it into the sub functions. Would this make more sense just being a global constant? I’m in the early stages of learning javascript and I want to make sure I learn the best practices. thanks!

edit: I’m gathering that block level variables are a better practice than global. Would it then make it more readable to move the “const x” statement to each subfunction, or does this come down to personal preference at this point?

What do you mean By IT services?

IT services, short for Information Technology services, encompass a wide range of activities related to the management and utilization of technology to meet the needs of individuals, businesses, and organizations. These services can be broadly categorized into several types, each catering to different aspects of IT infrastructure, software development, support, and maintenance. Here’s a breakdown of some key types of IT services:
** Infrastructure Services:** These services focus on establishing and maintaining the foundational components of IT systems, such as networks, servers, storage, and cloud infrastructure. They involve tasks like network setup, server configuration, data center management, and cloud computing solutions.
Software Development Services: This category encompasses services aimed at designing, developing, and deploying software applications tailored to meet specific business requirements. It includes custom software development, mobile app development, web development, and application integration services.
IT Consulting Services: IT consulting services involve providing expert advice and guidance to businesses and organizations on leveraging technology to achieve their goals. Consultants assess existing IT infrastructure, identify areas for improvement, and recommend solutions to optimize performance, security, and efficiency.
Managed IT Services: Managed IT services involve outsourcing the responsibility for managing and maintaining IT systems to a third-party provider. These services typically include proactive monitoring, maintenance, security, and support for IT infrastructure, allowing businesses to focus on their core activities while ensuring their IT environment remains stable and secure.
Cybersecurity Services: Cybersecurity services are dedicated to protecting IT systems, networks, and data from unauthorized access, breaches, and other security threats. These services include vulnerability assessments, threat detection, incident response, security audits, and implementation of security measures such as firewalls, antivirus software, and encryption.
Data Analytics Services: Data analytics services focus on extracting actionable insights from large volumes of data to support decision-making and strategic planning. These services involve data collection, analysis, visualization, and interpretation using tools and techniques such as data mining, machine learning, and predictive analytics.

Vite build not processing all assets in the /assets folder

Note: I already read other questions related but even trying some workaronds there, I didd’t found a solution.

I have a problem that I’ve been investigating for a couple of days and I can’t seem to resolve it.

In my application, I’m building a <WeatherIcon /> component, which essentially checks a numeric code matrix as keys for a Map and returns the address of the icon to be used.

The problem lies in that I have two types of icons, animated and static, each in its respective folder within /assets. The logic works perfectly in the dev environment, but when I run vite build, it only processes the assets from the /assets/animated folder.

I understand that Vite by default only processes the assets that are explicitly imported/exported and used in /src, and this is exactly what I’m doing. I’ve tried several approaches, such as separating the assets folder by prefixing the files with animated- or static-, importing and exporting the file addresses in helpers, having separate components for animated/static icons, but Vite still doesn’t process the assets the way I want.

I’ve attached the helper code, the folder structure for assets, and the component code. Maybe someone can see something that I’m not seeing.

The assets folder and the dist result

src/assets
├── animated
│   ├── clear-day.svg
│   ├── cloudy.svg
│   ├── dust.svg
│   ├── fog.svg
│   ├── haze-day.svg
│   ├── haze.svg
│   ├── rain-and-sleet-mix.svg
│   ├── rainy-1.svg
│   ├── rainy-2.svg
│   ├── rainy-3.svg
│   ├── severe-thunderstorm.svg
│   ├── snowy-1.svg
│   ├── snowy-2.svg
│   ├── snowy-3.svg
│   └── thunderstorms.svg
└── static
    ├── clear-day.svg
    ├── cloudy.svg
    ├── dust.svg
    ├── fog.svg
    ├── haze-day.svg
    ├── haze.svg
    ├── rain-and-sleet-mix.svg
    ├── rainy-1.svg
    ├── rainy-2.svg
    ├── rainy-3.svg
    ├── severe-thunderstorm.svg
    ├── snowy-1.svg
    ├── snowy-2.svg
    ├── snowy-3.svg
    └── thunderstorms.svg

Those .svg there are only the /animated/, /static are not being processed

dist
├── assets
│   ├── clear-day-xXPM11tY.svg
│   ├── cloudy-ArifDuTp.svg
│   ├── fog-4jp9XWOF.svg
│   ├── haze-9_8ELXPu.svg
│   ├── index-DPDs6ix0.js
│   ├── index-O_dZZa1F.css
│   ├── rain-and-sleet-mix-vDH9vBwd.svg
│   ├── rainy-1-VxaL7Ezf.svg
│   ├── rainy-2-MmKM9EXc.svg
│   ├── rainy-3-IR8EbsFc.svg
│   ├── severe-thunderstorm-4t-lcuIa.svg
│   ├── snowy-1-0VBrX7Fh.svg
│   ├── snowy-2-M57x8x7x.svg
│   ├── snowy-3-eusHMpeb.svg
│   └── thunderstorms-a_zBMSBU.svg
├── index.html
└── vite.svg

The helper

import animatedClear from '@/assets/animated/clear-day.svg';
import animatedCloudy from '@/assets/animated/cloudy.svg';
import animatedDrizzle from '@/assets/animated/rain-and-sleet-mix.svg';
import animatedHaze from '@/assets/animated/haze.svg';
import animatedFog from '@/assets/animated/fog.svg';
import animatedDust from '@/assets/animated/dust.svg';
import animatedRainy1 from '@/assets/animated/rainy-1.svg';
import animatedRainy2 from '@/assets/animated/rainy-2.svg';
import animatedRainy3 from '@/assets/animated/rainy-3.svg';
import animatedSnowy1 from '@/assets/animated/snowy-1.svg';
import animatedSnowy2 from '@/assets/animated/snowy-2.svg';
import animatedSnowy3 from '@/assets/animated/snowy-3.svg';
import animatedThunderstorm from '@/assets/animated/thunderstorms.svg';
import animatedsevereThunderstorm from '@/assets/animated/severe-thunderstorm.svg';

import staticClear from '@/assets/static/static-clear-day.svg';
import staticCloudy from '@/assets/static/cloudy.svg';
import staticDrizzle from '@/assets/static/rain-and-sleet-mix.svg';
import staticHaze from '@/assets/static/haze.svg';
import staticFog from '@/assets/static/fog.svg';
import staticDust from '@/assets/static/dust.svg';
import staticRainy1 from '@/assets/static/rainy-1.svg';
import staticRainy2 from '@/assets/static/rainy-2.svg';
import staticRainy3 from '@/assets/static/rainy-3.svg';
import staticSnowy1 from '@/assets/static/snowy-1.svg';
import staticSnowy2 from '@/assets/static/snowy-2.svg';
import staticSnowy3 from '@/assets/static/snowy-3.svg';
import staticThunderstorm from '@/assets/static/thunderstorms.svg';
import staticsevereThunderstorm from '@/assets/static/severe-thunderstorm.svg';

const lightRain = [500, 501];
const heavyRain = [502, 503, 504];
const moderateRain = [520, 521, 522, 531];
const ligthSnow = [600, 601];
const moderateSnow = [611, 612, 613, 615, 620, 621, 622];
const heavySnow = [602];
const thunderstorm = [200, 201, 202, 210, 221, 230, 231, 232];
const severeStorm = [212];
const drizzle = [300, 301, 302, 310, 311, 312, 313, 314, 321];
const clouds = [801, 802, 803, 804];
const clear = [800];
const atmosphere = [701, 711, 731, 751, 762, 771, 781];
const haze = [721];
const fog = [741];
const dust = [761];

export const codesMatrix = [
  lightRain,
  heavyRain,
  moderateRain,
  ligthSnow,
  moderateSnow,
  heavySnow,
  thunderstorm,
  severeStorm,
  drizzle,
  clouds,
  clear,
  atmosphere,
  haze,
  fog,
  dust,
];

export const AnimatedMap = new Map<number[], string>([
  [clear, animatedClear],
  [clouds, animatedCloudy],
  [drizzle, animatedDrizzle],
  [haze, animatedHaze],
  [fog, animatedFog],
  [dust, animatedDust],
  [lightRain, animatedRainy1],
  [moderateRain, animatedRainy2],
  [heavyRain, animatedRainy3],
  [ligthSnow, animatedSnowy1],
  [moderateSnow, animatedSnowy2],
  [heavySnow, animatedSnowy3],
  [thunderstorm, animatedThunderstorm],
  [severeStorm, animatedsevereThunderstorm],
  [atmosphere, animatedHaze],
]);

export const StaticMap = new Map<number[], string>([
  [clear, staticClear],
  [clouds, staticCloudy],
  [drizzle, staticDrizzle],
  [haze, staticHaze],
  [fog, staticFog],
  [dust, staticDust],
  [lightRain, staticRainy1],
  [moderateRain, staticRainy2],
  [heavyRain, staticRainy3],
  [ligthSnow, staticSnowy1],
  [moderateSnow, staticSnowy2],
  [heavySnow, staticSnowy3],
  [thunderstorm, staticThunderstorm],
  [severeStorm, staticsevereThunderstorm],
  [atmosphere, staticHaze],
]);

Te components

As you can see I have some repeated code, I wanted to make it this way, the more explicit possible just to check if this will force the assets processing, but no

const findRow = (matrix: number[][], code: number) => {
  return matrix.filter((row) => {
    const icon = row.find((i) => i === code);
    if (icon) return row;
  })[0];
};

export const WeatherIcon: FC<Props> = ({ code, tw, description }) => {
  const foundRow = findRow(codesMatrix, code);
  const icon = StaticMap.get(foundRow);
  if (!icon) return <PiWarningCircleLight />;

  return (
    <img
      key={`${icon}-${description}`}
      src={icon}
      alt={description}
      className={twClasses(tw)}
    />
  );
};

export const AnimatedWeatherIcon: FC<Props> = ({ code, tw, description }) => {
  const foundRow = findRow(codesMatrix, code);
  const icon = AnimatedMap.get(foundRow);
  if (!icon) return <PiWarningCircleLight />;

  return (
    <img
      key={`${icon}-${description}`}
      src={icon}
      alt={description}
      className={twClasses(tw)}
    />
  );
};

In this javascript code something wrong my image not storing

In this javascript code something wrong my image not storing I am using laravel and when i add multiple image. I make input via javascipt but when i sumbit and store image not storing to datebase i think smth wrong in javascript code


                    <div class="col-6" id="imageCol">
                        <div class="row flex-nowrap align-items-center" id="imageCard">
                            <div class="card image-card mb-2" style="height: 425px; width: 80%">
                                <div class="card-body">
                                    <i class="bi bi-plus-circle" style="font-size: 60px"></i> <!-- Placeholder icon -->
                                </div>
                            </div>
                            <div class="d-block">
                                <div class="card image-card mb-2" style="width: 15%">
                                    <div class="card-body">
                                        <i class="bi bi-plus-circle"></i> <!-- Placeholder icon -->
                                    </div>
                                </div>
                                <div class="card image-card mb-2" style="width: 15%">
                                    <div class="card-body">
                                        <i class="bi bi-plus-circle"></i> <!-- Placeholder icon -->
                                    </div>
                                </div>
                                <div class="card image-card mb-2" style="width: 15%">
                                    <div class="card-body">
                                        <i class="bi bi-plus-circle"></i> <!-- Placeholder icon -->
                                    </div>
                                </div>
                                <div class="card image-card mb-2" style="width: 15%">
                                    <div class="card-body">
                                        <i class="bi bi-plus-circle"></i> <!-- Placeholder icon -->
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="image-container">
                            <div class="col-8" id="firstImageContainer"></div>
                            <div class="col-3" id="smallImagesContainer"></div>
                            <span class="col-8 text-danger">Bellik: Surat ýüklenenden soň 400x400 bolýandyr suratlaryňyzy şoňa görä goýuň!</span>
                        </div>
                    </div>
                    <script>
                        const imageCardClickHandler = () => {
                            const imageInput = document.createElement('input');
                            Object.assign(imageInput, {
                                type: 'file',
                                accept: 'image/*',
                                name: 'image[]',
                                multiple: true,
                            });
                            document.body.appendChild(imageInput);
                            imageInput.click();
                            imageInput.addEventListener('change', function handleImageChange(event) {
                                const files = event.target.files;
                                const [firstImageContainer, smallImagesContainer] = ['firstImageContainer', 'smallImagesContainer'].map(id => document.getElementById(id));
                                if (!firstImageContainer || !smallImagesContainer) {
                                    console.error('Image containers not found.');
                                    return;
                                }
                                const existingImagesCount = firstImageContainer.children.length + smallImagesContainer.children.length;
                                const maxImagesAllowed = 6;
                                const imagesToAdd = Math.min(files.length, maxImagesAllowed - existingImagesCount);
                                const imageCard = document.getElementById('imageCard');
                                imageCard.parentNode.removeChild(imageCard);
                                for (let i = 0; i < imagesToAdd; i++) {
                                    const file = files[i];
                                    const reader = new FileReader();
                                    reader.onload = function (e) {
                                        const image = document.createElement('img');
                                        Object.assign(image, { src: e.target.result, classList: 'img-thumbnail' });
                                        const imageWrapper = document.createElement('div');
                                        imageWrapper.classList.add('image-wrapper');
                                        imageWrapper.appendChild(image);
                                        const removeIcon = document.createElement('i');
                                        Object.assign(removeIcon, { classList: 'bi bi-trash-fill remove-icon' });
                                        removeIcon.addEventListener('click', function () {
                                            imageWrapper.parentNode.removeChild(imageWrapper);
                                        });
                                        imageWrapper.appendChild(removeIcon);
                                        (firstImageContainer.children.length === 0 ? firstImageContainer : smallImagesContainer).appendChild(imageWrapper);
                                    };
                                    reader.onerror = error => console.error('Error reading image:', error);
                                    reader.readAsDataURL(file);
                                }
                                if (existingImagesCount + imagesToAdd > maxImagesAllowed) {
                                    alert(`You can only add up to ${maxImagesAllowed} images.`);
                                }
                                document.body.removeChild(imageInput);
                            });
                        };

                        document.getElementById('imageCard').addEventListener('click', imageCardClickHandler);

                        document.getElementById('imageForm').addEventListener('submit', function handleSubmit(event) {
                            event.preventDefault();
                            const formData = new FormData(this);
                            const [firstImageContainer, smallImagesContainer] = ['firstImageContainer', 'smallImagesContainer'].map(id => document.getElementById(id));
                            if (!firstImageContainer || !smallImagesContainer) {
                                console.error('Image containers not found.');
                                return;
                            }
                            [...firstImageContainer.querySelectorAll('img'), ...smallImagesContainer.querySelectorAll('img')].forEach(img => {
                                formData.append('image[]', img.src);
                            });
                            fetch('/post/store', {
                                method: 'POST',
                                body: formData
                            })
                                .then(response => {
                                    if (!response.ok) throw new Error('Network response was not ok');
                                    return response.text();
                                })
                                .then(data => console.log(data))
                                .catch(error => console.error('There was a problem with your fetch operation:', error));
                        });
                    </script>

Something wrong my code when i submit image not sumbiting smth wrong javascript code i can not find it

Firefox Browser blocking execution of asynchronous JavaScript?

I wrote simple Tests for my webapplication in the Selenium Framework, which works completly fine for Chrome and Edge.

But only in Firefox the asynchronous Script gets timeouted, could be an issue with the security settings of Firefox itself, i couldn’t find any related settings in about:config.

Also i have already installed the lastet geckodriver version.

changing text of element only when condition is fullfiled

I need to change text of <span data-testid="recapItemPrice">ZADARMO</span> from ‘ZADARMO’ to ‘DOHODOU’ only when there is text in parental element ‘INDIVIDUÁLNA CENA PREPRAVY na vyžiadanie’

HTML is like this:

<strong data-testid="recapDeliveryMethod">                                                            
<span data-testid="recapItemPrice">ZADARMO</span>
INDIVIDUÁLNA CENA PREPRAVY na vyžiadanie</strong>

I tried this:

<script>
$(document).ready(function(){
if ( $("[data-testid=recapDeliveryMethod]").text() === "INDIVIDUÁLNA CENA PREPRAVY na vyžiadanie" ) {
    $("[data-testid=recapItemPrice]").text("DOHODOU");
}
});
</script>

I’m new to JavaScript / jQuery and will appreciate every advice.

JavaScript incorrect calculations

Calculations are performed incorrectly

c=1,6
D=800
Q=149
f=1
s=6
console.log(Q,D,s,c,f)
var p=(((2*Q*f*(s-c))/(D+c-s)))
console.log(((2*Q*f*(s-c))/(D+c-s)))

Return 1.8742138364779874 instead of the correct answer, about 1.630034809

How to delay rendering of Open Graph meta tags until API call completes in Vue.js?

I’m working on a Vue.js application where I need to dynamically set Open Graph (OG) meta tags based on data fetched from an API. The OG tags are necessary for social media sharing (e.g., Facebook, WhatsApp). The issue I’m facing is that the meta tags, particularly og:image, are set before the API call completes, resulting in an empty image URL initially. When the page is shared, the meta tags with the empty image URL are used, instead of the updated ones.

Here is my current code:

<template>
  <div v-if="dataFetched">
    <div class="m-5 md:mx-28">
//template code continues here



//vue main script
<script setup>
import { ref, onMounted, watch, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useSeoMeta } from '@vueuse/head';

import DetailHeader from "~/components/listing-detail/DetailHeader.vue";
import DetailPictures from "~/components/listing-detail/DetailPictures.vue";
import DetailOverview from "~/components/listing-detail/DetailOverview.vue";
import DetailProperty from "~/components/listing-detail/DetailProperty.vue";
import DetailMap from "~/components/listing-detail/DetailMap.vue";
import DetailLocation from "~/components/listing-detail/DetailLocation.vue";
import DetailNearby from "~/components/listing-detail/DetailNearby.vue";
import DetailCalculator from "~/components/listing-detail/DetailCalculator.vue";

const axios = useNuxtApp().$axios;

defineProps({ id: String });

// Initialize data
const dataItem = ref([]);
const currentItem = ref(null);
const nearby_places = ref([]);
const dataFetched = ref(false);

const route = useRoute();
const router = useRouter();

const { nametitle } = route.params;
const nametitleValues = nametitle.split('-').map(value => value.replace(/-/g, ' '));
const title = nametitleValues.join(' ') + ' | A-plus Property Consultants';
const ogTitle = title;
const description = 'Discover ' + title + ', available on A-plus Property Consultants. Explore this property today!';
const ogDescription = description;
const ogImageUrl = ref('');
const currentUrl = 'https://aplus2.vercel.app' + route.fullPath;
const ogImageWidth = ref(32);
const ogImageHeight = ref(32);

const fetchData = async () => {
  let url = `${apiEndpoint}?propertySEF=${nametitle}`;
  try {
    const response = await axios.get(url);
    dataItem.value = response.data.listing;
    currentItem.value = response.data.listing;

    if (dataItem.value[0]?.property_nearby_place) {
      nearby_places.value = JSON.parse(dataItem.value[0].property_nearby_place);
    }

    if (dataItem.value[0]?.photo?.[0]?.photo_file) {
      ogImageUrl.value = `https://staging.aplussharing.com/storage/uploads/property/${dataItem.value[0].photo[0].photo_file}`;
    }
    
    dataFetched.value = true;
  } catch (error) {
    router.push({ name: "404" });
  }
};

onMounted(() => {
        fetchData();

    });

watch(dataFetched, (newValue) => {
  if (newValue) {
    useSeoMeta({
      title,
      ogTitle,
      description,
      ogDescription,
      ogImage: ogImageUrl.value,
      ogUrl: currentUrl,
      ogImageWidth: ogImageWidth.value,
      ogImageHeight: ogImageHeight.value,
      ogType: 'website',
    });
  }
},{immediate:true});
</script>



Problem:
The OG meta tags, particularly og:image, are rendered before the API call completes, resulting in an empty og:image URL. When sharing the page on social media, the initial (empty) meta tags are used.

Goal:
I want to block the rendering of meta tags until the API call completes and the og:image URL is available. How can I ensure that the meta tags are only set after the data has been fetched?

Any help or suggestions would be greatly appreciated!

Need to implement the search Bar functionality and want to Render the Filtered Data on UI

Hi I was working on this project and I was assigned some task where I have to fetch the data from an external Api and I have to implement a Search Bar where we can search on the basis of Title and Render it on the Ui. So I thought I should make an onclick event on the button and when it hits I will take the value from search Bar and filter it on the basis of title and I will render it on the UI but the functionality is not working. Help me to filter it out.

I want to implement a Search Bar Functionality and I have rendered the data on the UI and I want to implement the Search Functionality.

let originalDataa = [];

function sort_by_price_asc() {
  return function(elem1, elem2) {
    if (elem1.price < elem2.price) {
      return -1;
    } else if (elem1.price > elem2.price) {
      return 1;
    } else {
      return 0;
    }
  };
}

function sort_by_price_dsc() {
  return function(elem1, elem2) {
    if (elem1.price > elem2.price) {
      return -1;
    } else if (elem1.price < elem2.price) {
      return 1;
    } else {
      return 0;
    }
  };
}


const postsUrl = `https://dummyjson.com/products/`;

async function getPosts() {
  let originalData = []
  const res = await fetch(postsUrl);
  const posts = await res.json();
  originalData = posts
  originalDataa = posts.products;
  console.log(originalDataa)
  return originalData;
}

function renderPost(post) {
  const section = document.querySelector('.posts');
  const postDiv = document.createElement('div');
  const postTitle = document.createElement('h1');
  const PostPrice = document.createElement('h3');
  const PostBrand = document.createElement('h1');
  const postDesc = document.createElement('div');
  postDesc.innerText = post.description;
  postDesc.style.color = "black"
  postTitle.innerText = post.title;
  PostPrice.innerText = post.price;
  // console.log(postTitle);
  postDiv.appendChild(postTitle);
  postDiv.appendChild(postDesc);
  postDiv.appendChild(PostPrice, "price")
  section.appendChild(postDiv);
  PostBrand.innerText = post.brand
  section.appendChild(PostBrand)

  const button = document.createElement('button');
  button.innerHTML = "Favourite";

  section.appendChild(button)
}


async function renderPosts(type) {
  const posts = await getPosts();
  const temp = posts.products;

  if (type === "asc") {
    temp.sort(sort_by_price_asc());
    for (let x = 0; x < temp.length; x++) {
      renderPost(temp[x]);
    }
    // console.log(temp);
  } else {
    temp.sort(sort_by_price_dsc());
    for (let x = 0; x < temp.length; x++) {
      renderPost(temp[x])
    }
    //  console.log(temp)
  }
}

function sortData(type) {
  renderPosts(type)
}



function fetchdata() {
  let x = document.getElementById("search-box")
  console.log(x);
  const answer = originalDataa;

  for (let i = 0; i < answer.length; i++) {
    if (answer[i].title === x) {
      renderPost(answer[i]);
    }
  }
}
<header>
  <nav>
    <div class="left">
      <div class="dropdown">
        <button class="dropbtn">Sort</button>
        <div class="dropdown-content">
          <button id="as" onclick="sortData('asc')">Ascending</button>
          <button id="ds" onclick="sortData('desc')">Descending</button>
        </div>
      </div>
    </div>
    <div class="center">
      <form id="search-form">
        <input type="text" id="search-box" placeholder="Search...">
        <button type="submit" id="search-btn" onclick="fetchdata()">Search</button>
      </form>
    </div>
    <div class="right">
      <button id="fav-btn" onclick="toggleFavorite()">Favorite</button>
    </div>
  </nav>
</header>
<main>
  <div class="posts" id="data-container"></div>
</main>
<footer>
  <div class="pagination" id="pagination">
    <button onclick="changePage('prev')" id="prev-btn" disabled>Previous</button>
    <span id="page-numbers">
      <button onclick="renderPosts()">1</button>
      <button onclick="goToPage(2)">2</button>
      <button onclick="goToPage(3)">3</button>
      <!-- Add more buttons for additional pages as needed -->
    </span>
    <button onclick="changePage('next')" id="next-btn">Next</button>
  </div>
</footer>