Why is my stopwatch adding fixed amount of time when I refresh?

I have a Vue.js Script is Adding time to my stopwatch once I refresh the page – Always adds an additional 6 hours. The script is simply a button that tracks time when clicked, and post the time to a django model once stopped. I am able to track time fine, but when I refresh the page, I come back to seeing 6 hours added to my stopwatch:

Vue.js Script:

var NavbarApp = {
            data() {
                return {
                    seconds: {{ active_entry_seconds }},
                    trackingTime: false,
                    showTrackingModal: false,
                    timer: null,
                    entryID: 0,
                    startTime: '{{ start_time }}'
                }
            },
            delimiters: ['[[', ']]'],
            methods: {
                startTimer() {
                    fetch('/apps/api/start_timer/', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-CSRFToken': '{{ csrf_token }}'
                        }
                    })
                    .then((response) => {
                        return response.json()
                    })
                    .then((result) => {
                        this.startTime = new Date()
                        this.trackingTime = true

                        this.timer = setInterval(() => {
                            this.seconds = (new Date() - this.startTime) / 1000
                        }, 1000)
                    })
                },
                stopTimer() {
                    fetch('/apps/api/stop_timer/', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-CSRFToken': '{{ csrf_token }}'
                        }
                    })
                    .then((response) => {
                        return response.json()
                    })
                    .then((result) => {
                        this.entryID = result.entryID
                        this.showTrackingModal = true
                        this.trackingTime = false

                        window.clearTimeout(this.timer)
                    })
                },
                discardTimer() {
                    fetch('/apps/api/discard_timer/', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-CSRFToken': '{{ csrf_token }}'
                        }
                    })
                    .then((response) => {
                        this.seconds = 0
                        this.showTrackingModal = false
                    })
                },
                addLater() {
                    this.seconds = 0
                    this.showTrackingModal = false
                },
                addToTask() {
                    console.log('addToTask')
                    window.location.href = '/apps/track_entry/' + this.entryID + '/'
                }
            },
            mounted() {
                if (this.seconds !== 0) {
                    this.trackingTime = true
                    this.timer = setInterval(() => {
                        this.seconds = (new Date() - new Date(this.startTime)) / 1000
                    }, 1000)
                }
            },
            computed: {
                readableSeconds() {
                    const d = Number(this.seconds);
                    const h = Math.floor(d / 3600);
                    const m = Math.floor(d % 3600 / 60);
                    const s = Math.floor(d % 3600 % 60);

                    const hDisplay = h > 0 ? h + (h == 1 ? "h, " : "h, ") : "";
                    const mDisplay = m > 0 ? m + (m == 1 ? "m, " : "m, ") : "";
                    const sDisplay = s >= 0 ? s + (s == 1 ? "s" : "s") : "";

                    return hDisplay + mDisplay + sDisplay; 
                }
            }
        }

        Vue.createApp(NavbarApp).mount('#navbar-app')

HTML:

                                                <div class="col-md-auto mt-md-0 mt-4" id="navbar-app">
                                                    <div class="hstack gap-1 flex-wrap">
                                                        <div class="navbar-item" v-if="!trackingTime">
                                                            <div class="buttons">
                                                                <button class="btn btn-success add-btn" @click="startTimer()">
                                                                   Start Timer
                                                                </button>
                                                            </div>
                                                        </div>
                            
                                                        <div class="navbar-item" v-else>
                                                            <div class="buttons">
                                                                <div class="buttons">
                                                                    <button class="btn btn-warning add-btn" @click="stopTimer()">
                                                                        [[ readableSeconds ]] (stop)
                                                                    </button>
                                                                </div>
                                                            </div>
                                                        </div>

When I click the button – time is tracking:
enter image description here

When I refresh the page, 6 additional hours have been added:
enter image description here

Let me know if I am missing any information or code you may need

PDF.js v4-Open findBar by default

I embedded a PDF using pdfjs-4.0.379, and in the previous version (version 2) I had something similar to this:

...
key: "setHash",
    value: function setHash(hash) {
        //aqui
      var pageNumber, dest;      

      if (hash.includes("=")) {
        var params = (0, _ui_utils.parseQueryString)(hash);
        
        if ("search" in params) {
          this.eventBus.dispatch("findfromurlhash", {
            source: this,
            query: params.search.replace(/"/g, ""),
            phraseSearch: params.phrase === "true"
          });
        }
        
         if ('search' in params) { 
              PDFViewerApplication.findBar.open(); 
              PDFViewerApplication.findBar.findField.value = params.search; 
              PDFViewerApplication.findBar.highlightAll.checked = true; 
              PDFViewerApplication.findBar.findNextButton.click(); 
        }
...

But how can i implement that in the current version?

I found a similar answer in this link, but it didn’t really answer my question.

NextJs Unhandled Runtime Error TypeError: Cannot read properties of null (reading ‘removeChild’) on using third party blog post library

I am trying to use https://dropinblog.com/ with nextjs, the page works fine and loads perfectly with no error the problem is when I click the navigation links to navigate to some other pages using Next Link it throws this error:
enter image description here

my page is /blog which the code is:

import Script from "next/script";

export default function Blog() {
  return (
    <div>
      <Script
        src="your-dropin-blog-source"
        strategy="lazyOnload"
      ></Script>
      <div id="dib-posts"></div>
    </div>
  );
}

Application using Python and Javascript

I am creating a project that uses Electron to create the application interface (HTML, CSS, Javascript) and I am also using Selenium (Python) for the backend.

Question 1) How would I create a virtual environment for these 2 technologies? Since they are different.

Question 2) How would I communicate between these two? Basically I would need to send a string from Python to Javascript and vice versa.

Question 3) How would I transform this application that uses Python and Javascript into an executable? Since they are different.

NOTE: I want to use Selenium from Python, because I know more Python than Javascript.

Sandboxed JavaScript for CMP (Consent Mode v2) cannot write to dataLayer

I have set up a custom template using code from my CMP provider, which works fine for consent setting. We have had to make several additions and edits to the CMP as provided. I want to send a custom event when consent is updated to use as a trigger for certain tags, but I keep getting “‘dataLayer’ is not defined” errors. It seems that I can’t get the sandboxed javascript to talk to my dataLayer at all, as any reference to it or the window creates issues.

I assume this is an issue with the custom template limitations. I want to understand why it’s not working and how to be able to send custom events to the dataLayer in sandboxed javascript.

I have tried different methods of trying to make this work, but everything I tried results in either a ‘window is not defined’ or ‘dataLayer’ is not defined error. My provider is unwilling to help as they believe it’s a Google issue. Note: the script works fine if I remove the references to window and dataLayer and does update consent as it should. However, I need to send custom events as part of ‘updateConsentState’ too to trigger other tags.

Please see my code below:

// Initialize dataLayer
window.dataLayer = window.dataLayer || [];

// Enter your template code here.
const log = require('logToConsole');
const setDefaultConsentState = require('setDefaultConsentState');
const updateConsentState = require('updateConsentState');
const injectScript = require('injectScript');
const queryPermission = require('queryPermission');
const copyFromWindow = require('copyFromWindow');
log('data =', data);

// set default consent
setDefaultConsentState({
    'ad_storage': 'denied',
    'analytics_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization':'denied',
    'functionality_storage': data.functional,
    'personalization_storage': data.functional,
    'security_storage': 'granted'
});

// start of config
var config = {
    apiKey: data.apiKey,
    logConsent: true,
    product: data.product,
    optionalCookies: [
        {
            name : 'Analytics',
            label: "<strong>Analytics cookies</strong>",
            description: "<p>Analytics cookies help us to improve our website by collecting data about how you use it.</p>",
            cookies: ['_gid', '_ga*', 'nmstat', '__utma', '__utmc', '__utmz', '__utmt', '__utmb', '_hj*', 'CLID', 'SRM_B', 'uid', '_vwo*', '_gat',],
            onAccept : function(){
                updateConsentState({
                    'analytics_storage': 'granted',
                });
                // Push event to dataLayer
                window.dataLayer.push({
                    'event': 'analytics_granted',
                    'category': 'Analytics',
                    'action': 'Granted'
                });
            },
            onRevoke: function(){
                updateConsentState({
                    'analytics_storage': 'denied',
                });
            }
        },
        {
            name : 'marketing',
            label: "<strong>Marketing cookies</strong>",
            description: "<p>Marketing cookies help us show you adverts that are more relevant to you.</p>",
            cookies: ['X-AB', '_gcl*', 'uid', 'test_cookie', 'YSC', 'VISITOR_INFO1*', '_ttp', '_scid', '_scid_r', '_scid*', '_uet*', 'muc_ads', 'li_sugr', 'bcookie', 'lidc', 'personaliza*', 'MUID', 'UserMatch*', 'AnalyticsSync*', '_fbp*', '_tt_enable*', 'bscookie', 'li_gc', 'MR', 'SM', 'ANONCHK', 'MSPTC', 'IDE', 'suid', 'uid*', 'TapAd*', 'XANDR*', 'receive-cookie*', 'uuid2', '_rxuuid', 'ab', 'anHistory', 'anj', 'anProfile', 'u', 'bku', 'bkpa', '__141_cid', '__io_cid', 'A3', 'utm_*', 'NID', 'cf_clearance', '_cfuvid', '_fbc'],
            onAccept : function(){
                updateConsentState({
                    'ad_storage': 'granted',
                    'ad_user_data': 'granted',
                    'ad_personalization':'granted',
                });
                // Push event to dataLayer
                window.dataLayer.push({
                    'event': 'marketing_granted',
                    'category': 'Marketing',
                    'action': 'Granted'
                });
            },
            onRevoke: function(){
                updateConsentState({
                    'ad_storage': 'denied',
                    'ad_user_data': 'denied',
                    'ad_personalization': 'denied',
                });
            }
        }
    ],
    text: {
        title: "<div class='u-text-h4 u-font-bold u-font-serif u-mb-1'>Control your cookies</div>",
        notifyTitle: "<div class='u-text-h4 u-font-bold u-font-serif u-mb-1'>Control your cookies</div>",
        notifyText: "<p>We need some essential cookies to make this website work. We want to set other cookies to understand how you use the site and give you the best experience. If you change your mind, you can change your settings.</p>",
        acceptSettings: "Accept all",
        rejectSettings: "Reject non-essential",
        accept: "Accept all",
        reject: "Reject non-essential",
        settings: "More options",
        necessaryTitle:"<strong>Essential cookies</strong>",
        necessaryDescription:"<p>We need some essential cookies to make this website work. They help you move between pages, interact with the website and access secure areas. You can only reject essential cookies in your browser settings. Some parts of the site may not work if you do.</p>",
        closeLabel: "<span>Save and close cookie control</span>",
        notifyDescription : "<p>We need some essential cookies to make this website work. We want to set other cookies to understand how you use the site and give you the best experience.</p>",
    },
    consentCookieExpiry: 365,
    theme: 'light',
    subDomains: true,
    statement: {
        description: 'For more detailed information, please check our',
        name: 'Cookie Policy',
        url: 'https://www.mmu.ac.uk/cookie-policy',
        updated: '04/03/2024',
    },
    excludedCountries: 'all',
    position: 'left',
    layout: 'popup',
    toggleType: 'slider',
    branding: {
        'backgroundColor': '#ffffff',
        'fontColor': '#000000',
        'acceptBackground':'#ffcd00',
        'rejectBackground':'#ffffff',
        'acceptText':'#000000',
        'rejectText':'#000000',
        'removeAbout': true,
        'removeIcon': true,
        'toggleBackground':'#A9A3AD',
        'toggleText':'#ffffff',
    }
};

// end of config

const onSuccess = () => {
    const CookieControl = copyFromWindow('CookieControl');
    log(config);
    CookieControl.load(config);
    data.gtmOnSuccess();
};

const onFailure = () => {
    log("fail");
    data.gtmOnFailure();
};

injectScript('https://cc.cdn.civiccomputing.com/9/cookieControl-9.x.min.js', onSuccess, onFailure);

// Call data.gtmOnSuccess when the tag is finished.
data.gtmOnSuccess();

How to add the chart in excel using handlebars?

I need to add the chart in excel. From table data ,need a chart to be drawn in the excel.I have add xlsxAdd to append chart in excel, but its throwing *Missing helper: “xlsxAdd*
error. So table is already there in the excel but chart is not rendering using this handlebars.This is the correct way to add chart in excel ?


<!DOCTYPE html>
<html>

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Report</title>
    <link rel="stylesheet" href="/stylesheets/style.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
</head>
<style>
    table, th, td {
        border: 1px solid black;
        border-collapse: collapse;
    }

    table {
        width: 100%
    }

    td {
        text-align: center
    }
</style>
<body>
     <div>
        <img src="https://icicipruamcdev.azureedge.net/static/media/logo.86f7e0e9.svg" style="height: 150px;">
    </div>


    <canvas id="canvas" style="width:90vw"></canvas>
    <script>
         document.addEventListener('DOMContentLoaded', function() {
            // Extract data from the table
            const table = document.getElementById('report-table');
            const rows = table.querySelectorAll('tr');
            const labels = [];
            const navData = [];
            rows.forEach((row, index) => {
                if (index > 0) { // Skip header row
                    const cells = row.querySelectorAll('td');
                    labels.push(cells[1].textContent); // Assuming date is in the second column
                    navData.push(parseFloat(cells[0].textContent)); // Assuming nav is in the first column
                }
            });
            
            // Chart data
            const chartData = {
                labels: labels,
                datasets: [{
                    label: "NAV_HISTORY",
                    type: 'line',
                    data: navData,
                    backgroundColor: 'transparent',
                    borderColor: 'blue',
                    borderWidth: 1,
                    lineTension: 0,
                    pointBackgroundColor: 'blue',
                    pointBackgroundColor: 'transparent',
                    borderColor: 'navy',
                    pointRadius: 3
                }]
            };

            // Chart initialization
            const ctx = document.getElementById('canvas').getContext('2d');
            const chart = new Chart(ctx, {
                type: 'line',
                data: chartData,
                options: {
                    responsive: false,
                    animation: false,
                    maintainAspectRatio: false,
                    devicePixelRatio: 1,
                    scales: {
                        yAxes: [{
                            ticks: {
                                beginAtZero: true,
                                stepSize: 20
                            }
                        }],
                        xAxes: [{
                            ticks: {
                                autoSkip: true,
                                maxTicksLimit: 8,
                                maxRotation: 0,
                                minRotation: 0
                            }
                        }]
                    }
                }
            });
        });
    </script>   
    <div><br/></div>
    <div class="invoice-box">
       <!-- Assuming you have a table structure like this -->
<table>
    <thead>
        <tr>
            <th>NAV</th>
            <th>Date</th>
        </tr>
    </thead>
    <tbody>
        {{#each data}}
        <tr>
            <td>{{this.Name}}</td>
            <td>{{this.Amount}}</td>
        </tr>
        {{/each}}
    </tbody>
</table>

<!-- Now, let's add the xlsxAdd functionality -->
{{#xlsxAdd "xl/drawings/drawing1.xml" "xdr:wsDr.twoCellAnchor"}}
{{#each data}}
<row>
    <c t="inlineStr"><is><t>{{this.Name}}</t></is></c>
    <c><v>{{this.Amount}}</v></c>
</row>
{{/each}}
{{/xlsxAdd}}

    </div>
</body>

</html>

Adding new object to mongoDB changes the previously added object

I’m using AWS S3 and MongoDB in a full-stack react application.

When I add a new recept in front-end it works normally. But once in a while it changes the rndImageName which I create on back-end. Images uploads to S3 fine.

Is there better way to do this?

multer.js

const randomImageName = (bytes = 32) => crypto.randomBytes(bytes).toString('hex')
let rndImageName = randomImageName();

awsRouter.post('/recipeImages', upload.single('file'), async (req, res) => {

  const buffer = await sharp(req.file.buffer).resize({ height: 1920, width: 1080, fit: 'contain' }).toBuffer()

  const params = {
    Bucket: bucketName,
    Key: 'recipeImages/' + rndImageName, 
    Body: buffer,
    ContentType: req.file.mimetype
  }

  const command = new PutObjectCommand(params)

  await s3.send(command)

})


recipes.js 

const { rndImageName } = require('./multer')

recipesRouter.post('/', async (request, response, next) => {

  const body = request.body

  const decodedToken = jwt.verify(getTokenFrom(request), process.env.SECRET)

  if (!decodedToken.id) {
    return response.status(401).json({ error: 'token invalid' })
  }
  const user = await User.findById(decodedToken.id)


  const recipe = new Recipe({
    id: body.id,
    recipe_name: body.recipe_name,
    ingredients: body.ingredients,
    instructions: body.instructions,
    speed: body.speed,
    category: body.category,
    main_ingredient: body.main_ingredient,
    diet: body.diet,
    likes: body.likes || 0,
    comments: body.comments || [],
    created: new Date(),
    imageName: rndImageName,
    user: user._id
  })

  const savedRecipe = await recipe.save()
  user.recipes = user.recipes.concat(savedRecipe._id)
  await user.save()

})

I want to insert the rndImageName (which I set up for S3 file name) to mongoDB objects so I can create signedUrl for a specific recipe.

Now it seems to use the same randomImageName again. Also changing the previously added recipe’s imageName.

Why some functions not working when navigate to the payment gateway?

I am developing website to navigate a sample Mastercard payment gateway and I want detect order id after the payment. In my code I set functions (callbacks) beforeRedirect , afterRedirect and completeCallback (Javascript functions) mentioned in documentation. I add js alerts for all functions to check they are working. But afterRedirect function is not working (other call backs are working) .The code seems to be correct. I have doubt that its because of security issues or running on localhost. Have you any idea why afterRidirect not working? Please help to solve this problem.

Here is the sample code.
This method is specifically for the full payment page option. Because we leave this page and return to it, we need to preserve the
state of successIndicator and orderId using the beforeRedirect/afterRedirect option

function afterRedirect(data) {
console.log("afterRedirect", data);
// Compare with the resultIndicator saved in the completeCallback() method
if(resultIndicator === "CANCELED"){
    return;
}    
else if (resultIndicator) {
    var result = (resultIndicator === data.successIndicator) ? "SUCCESS" : "ERROR";
    window.location.href = "/hostedCheckout/" + data.orderId + "/" + result;
}
else {
    successIndicator = data.successIndicator;
    orderId = data.orderId;
    sessionId = data.sessionId;
    sessionVersion = data.sessionVersion;
    merchantId = data.merchantId;

    window.location.href = "/hostedCheckout/" + data.orderId + "/" + data.successIndicator + "/" + data.sessionId;
}

This method preserves the current state of successIndicator and orderId, so they’re not overwritten when we return to this page after redirect

function beforeRedirect() { console.log("beforeRedirect");
return {
    successIndicator: successIndicator,
    orderId: orderId
};

}

Geoblocking; How to limit access to a website to within a physical establishment only?

We have created a website whose users must be limited to within the confines of a physical establishment or building. If they leave the building they should not be able to load and interact with the website.

We are at an impasse as to what solution to use to solve this issue with.

We’ve explored doing this with bluetooth low energy by having a desktop computer configured as a beacon to send out signals to visitors of the website whose mobile devices will have javascript code scanning for this particular bleutooth beacon device. ble web API is marked as experimental so users must go to chrome flags to enable to feature before javascript ble code will run, though – the flow of navigating away and enabling the flag, then relaunching chrome is not a good user experience at all. This messing with flags is not something everyday users should be doing all the time anyways.

Another option is to have the website’s javascript scan wifi and somehow check if the wifi is the one at the establishment, maybe?

My proposal was this option; to use navigator.geolocation to get the coordinates of the user and the reading’s accuracy rating, and checking if this is within the coordinates of the establishment. I’ve been told that the accuracy is too low for this use case by another engineer on the team. I don’t know enough about its accuracy to refute this. Can someone more experienced weigh in on this assessment?

Another option is checking user IP as mentioned in (Is it possible/feasible to limit website access to a geographic area?) this post but if the accuracy is city-level, that would be too inaccurate for this use case.

What’s the best path forward? Any other options we haven’t considered? Thoughts on options we have considered?

Can’t open more than one Modal

Different modals not opening on my website.

I copied one of the above responses (Manjunath Prabhakar) into an empty php file. This works perfectly. All 3 buttons open a different modal but when I incorporate the exact code into my website the only modal button that works is id=myBtn. What reasons would prevent the other modals from opening?

Why am I getting ‘MODULE_NOT_FOUND’ error?

I’m making a guilded bot and this error appears each time I’m running it. Here’s what Node.JS prints out:

node:internal/modules/cjs/loader:452
      throw err;
      ^

Error: Cannot find module 'C:UsersasusDesktopAppsCodingsPROJECTSGUILDED BOTindex.js'. Please verify that the package.json has a valid "main" entry
    at tryPackage (node:internal/modules/cjs/loader:444:19)
    at Module._findPath (node:internal/modules/cjs/loader:715:18)
    at resolveMainPath (node:internal/modules/run_main:26:23)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:24)
    at node:internal/main/run_main_module:28:49 {
  code: 'MODULE_NOT_FOUND',
  path: 'C:\Users\asus\Desktop\Apps\Codings\PROJECTS\GUILDED BOT\package.json',
  requestPath: 'C:\Users\asus\Desktop\Apps\Codings\PROJECTS\GUILDED BOT'
}

Node.js v20.11.1

I tried the steps from this link to fix it but to no avail: https://www.freecodecamp.org/news/error-cannot-find-module-node-npm-error-solved/

get region and continent names by code in JS?

Using Intl object in js, I can get localized country names with iso code. That’s great, but I need also region names and continents; like Europe, South Asia, Northern Afrika etc.

All this regions have UN M49 codes that are supposed to supported in Intl object, but they are not or maybe I’m doing something wrong. Some codes work, and some don’t. So I’m confused.

Is there a way to check all available region names in Intl?

Or does enyone know an alternative to get localized region and continent names by code?

const regions = new Intl.DisplayNames(['en'], { type: 'region' })

console.log(regions.of('150'))
console.log(regions.of('419'))


I would expect code ‘150’ to log Europe – because that’s the code for Europe – but it doesn’t. While for example, if I try ‘419’, it logs Latin America, as it should.

react-testing-library test optimization – screen.findByText vs expect(screen.findByText).toBeInTheDocument()

In our project we do a lot of

expect(await screen.findByText('sample text')).toBeInTheDocument()

expect(await screen.findByTestId('sample test id')).toBeInTheDocument()

And recently an argument was made that we can do this instead

await screen.findByText('sample text')

await screen.findByTestId('sample test id')

because if there is no element found the test will fail anyway. We also found a small and possibly inconsistent and irrelevant improvement of run speed of a test with this change

My question is: will our tests be faster and more resource efficient if we remove all those expect calls wherever possible?