Angular CanDeactivate + Browser Back Button causes double navigation or skips route

Problem

I’m using a CanDeactivate guard in Angular to prompt the user before navigating away from a form with unsaved changes. It works fine for normal route changes (e.g., clicking a link), but it breaks when the user presses the browser back button.

Scenario

Let’s say my routing flow is:

/home → /user → /edit

  • User is on /edit with unsaved changes.
  • Presses the browser back button.
  • A confirmation dialog is shown via CanDeactivate.
  • If user cancels, the route stays the same (correct).
  • But when they press back again and confirm, it navigates two steps back to /home, skipping /user.

What I Tried

I implemented a CanDeactivate guard like this:

export class YourFormComponent implements CanComponentDeactivate, OnInit, AfterViewInit {
    hasUnsavedChanges = false;

    // Implement the canDeactivate method
    canDeactivate(): Observable<boolean> | boolean {
      if (!this.hasUnsavedChanges) {
        return true;
      }

      const confirmLeave = window.confirm('You have unsaved changes. Leave anyway?');
      return confirmLeave;
    }
}

route.ts

import { Routes } from '@angular/router';
import { YourFormComponent } from './your-form.component';
import { ConfirmLeaveGuard } from './confirm-leave.guard';

const routes: Routes = [
  {
    path: 'form',
    component: YourFormComponent,
    canDeactivate: [ConfirmLeaveGuard]
  }
];

confrim-leave.guard.ts

import { inject } from '@angular/core';
import { CanDeactivateFn } from '@angular/router';
import { Observable } from 'rxjs';
import { Location } from '@angular/common';
export interface CanComponentDeactivate {
  canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}

export const ConfirmLeaveGuard: CanDeactivateFn<CanComponentDeactivate> = (component: any, currentRoute, currentState, nextState) => {
  const location = inject(Location);
  const result = component.canDeactivate();

  // If it's a boolean value
  if (typeof result === 'boolean') {
    if (!result) {
      location.replaceState(window.location.pathname); // Restore URL
    }
    return result;
  }

  // If it's an Observable or Promise
  if (result instanceof Observable || result instanceof Promise) {
    return new Promise(resolve => {
      Promise.resolve(result).then(confirmed => {
        if (!confirmed) {
          location.replaceState(window.location.pathname); // Restore URL
        }
        resolve(confirmed);
      });
    });
  }

  return true;
};

I also tried using Location.replaceState() or Location.go() inside the guard to restore the history stack, but it still misbehaves when using the back button.

Question
How can I correctly handle the browser back button with CanDeactivate to prevent double navigation or skipped routes?

Any advice or examples would be appreciated.

Use Custom UI for google translate in WKWebView in iOS

I want to translate any webpage opened in WKWebView of my application using google translate. For this I have found this code. This code basically injects a JS in my webView which creates a div of Google translate in the opened page from where I can select language and the webpage is translated.
The problem is I dont want to use the Native Google translator UI to update the language of the webpage.

Also, I have looked into this answer
Adding Google Translate to a web site

Here is the code:

func translatePage(to languageCode: String) {
        // Add a container for Google Translate UI (ensuring no return value)
        let addTranslateElement = """
        (function() {
            if (!document.getElementById('google_translate_element')) {
                var translateDiv = document.createElement('div');
                translateDiv.id = 'google_translate_element';
                document.body.insertBefore(translateDiv, document.body.firstChild);
            }
        })();
        """
        
        // Add Google Translate script and initialize translation
        let jsCode = """
        (function() {
            if (!window.googleTranslateElementInit) {
                window.googleTranslateElementInit = function() {
                    new google.translate.TranslateElement({
                        pageLanguage: 'auto',
                        includedLanguages: '(languageCode)',
                        layout: google.translate.TranslateElement.InlineLayout.SIMPLE
                    }, 'google_translate_element');
                };
                
                var script = document.createElement('script');
                script.type = 'text/javascript';
                script.src = 'https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit';
                document.head.appendChild(script);
            } else {
                googleTranslateElementInit();
            }
        })();
        """
        
        // Execute JavaScript to add the translation element
        webView.evaluateJavaScript(addTranslateElement) { _, error in
            if let error = error {
                print("Error adding translate element: (error.localizedDescription)")
            } else {
                // Execute JavaScript to load and initialize Google Translate
                self.webView.evaluateJavaScript(jsCode) { _, error in
                    if let error = error {
                        print("Translation Error: (error.localizedDescription)")
                    } else {
                        print("Translation script executed successfully.")
                    }
                }
            }
        }
    }

This function takes in language code and translates the page.

What I want is to use this google translator without using its UI.
First thing I want to know, is this possible?
Secondly, How can I use my native UI (e.g UIAlertController) to select the language and upon language selection I can translate the page using this google translate module without showing the UI of google translator.

Error : could not find react-redux context value; please ensure the component is wrapped in a

I have search all over the internet and in SO also, but couldn’t found my related issue. Below is my code:

index.js:

import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { store, persistor } from "./app/store";
import App from "./root";
import "./styles/global.css";

import { setupStore } from './store'

const store = setupStore()

const reactRoot = ReactDOM.createRoot(
  document.getElementById('root')
) 
reactRoot.render(
  <React.StrictMode>
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <App />
      </PersistGate>
    </Provider>
  </React.StrictMode>
);

root.jsx:

import React from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router';
import { useSelector } from 'react-redux';
import {HomePage} from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import ProfilePage from './pages/ProfilePage';
import {ProtectedRoute} from './components/common/ProtectedRoute';
import Header from './components/common/Header';
import Footer from './components/common/Footer';

function App() {
  const { darkMode } = useSelector((state) => state.theme);
  
  return (
    <div className={`min-h-screen flex flex-col`}>
      <Router>
        <Header />
        <main className="flex-1 w-full max-w-3xl mx-auto p-4">
          <Routes>
            <Route path="/login" element={<LoginPage />} />
            <Route 
              path="/" 
              element={
                <ProtectedRoute>
                  <HomePage />
                </ProtectedRoute>
              } 
            />
            <Route 
              path="/profile" 
              element={
                <ProtectedRoute>
                  <ProfilePage />
                </ProtectedRoute>
              } 
            />
            <Route path="*" element={<Navigate to="/" replace />} />
          </Routes>
        </main>
        <Footer />
      </Router>
    </div>
  );
}

export default App;

route.ts:

import { type RouteConfig, index } from "@react-router/dev/routes";

export default [index("routes/home.tsx")] satisfies RouteConfig;

store.ts:

const persistConfig = {
      key: 'root',
      storage,
      whitelist: ['auth', 'posts', 'theme'], // what to persist
    };
    
const rootReducer = combineReducers({
      auth: authReducer,
      posts: postsReducer,
      theme: themeReducer,
    });
    //reducer file
const persistedReducer = persistReducer(persistConfig, rootReducer);
    

//store exporting
export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false, // needed for redux-persist
}),
});

export const persistor = persistStore(store);

How can i set the Y-Axis of a Rangeslider in Plotly to a fixed Range

I’m working with Plotly in JavaScript and came across an issue related to auto-scaling the Y-axis.

I managed to prevent the main Y-axis from rescaling by using Plotly.relayout, which works well. However, that brings me to another problem: now the Y-axis of the range slider is auto-scaling, and I can’t seem to fix it.

According to the documentation, it should be possible to set the Y-axis of the range slider to a fixed range — but it doesn’t seem to have any effect in my case.

Has anyone faced the same issue or maybe spotted something I might have missed in the code?

const x_h = JSON.parse(document.getElementById('x_h').textContent);
const y_h = JSON.parse(document.getElementById('y_h').textContent);
const x_l = JSON.parse(document.getElementById('x_l').textContent);
const y_l = JSON.parse(document.getElementById('y_l').textContent);
const y_laser_inverted = y_l.map(val => -val);

const y_h_min = Math.min(...y_h);
const y_h_max = Math.max(...y_h);


const data = [
    // Laser
    {
        x: x_l,
        y: y_laser_inverted,
        // type: 'scatter',
        mode: 'lines',
        line: { color: 'red', width: 3 },
        name: 'Laser',
        xaxis: 'x',
        yaxis: 'y'
    },
    // Hitran
    {
        x: x_h,
        y: y_h,
        // type: 'scatter',
        mode: 'lines',
        line: { color: 'yellow', width: 2 },
        name: 'Hitran',
        xaxis: 'x2',
        yaxis: 'y2'
    }
];

const layout = {
    grid: {
        rows: 2,
        columns: 1,
        subplots: [['xy'], ['x2y2']],
        roworder: 'top to bottom'
    },
    height: 900,
    plot_bgcolor: 'rgba(0,0,0,0)',
    paper_bgcolor: 'rgba(0,0,0,0.5)',
    font: { color: 'white', size: 14 },

    xaxis: { visible: false },
    yaxis: { title: 'Laser' },

    xaxis2: {
        title: 'Wellenlänge (Hitran)',
        rangeslider: {
            visible: true,
            yaxis: {
                range: [y_h_min, y_h_max],
                rangemode: 'fixed'
            }
        }
    },
    
    yaxis2: {
        title: 'Hitran',
    }
};


Plotly.newPlot('graph', data, layout);


function updateYRange(currentRange) {
    const x_start = currentRange[0];
    const x_end = currentRange[1];

    const y_values_in_range = y_h.filter((value, index) => x_h[index] >= x_start && x_h[index] <= x_end);

    const y_min = Math.min(...y_values_in_range);
    const y_max = Math.max(...y_values_in_range);
    console.log("Y-Achsenbereich aktualisiert: ", y_min, y_max);
    Plotly.relayout('graph', {
        'yaxis2.range': [y_min, y_max]
    });
}

graph.on('plotly_relayout', function(eventData) {
    if (eventData['xaxis2.range']) {
        updateYRange(eventData['xaxis2.range']);
    }
});

React error: browserRouter cannot be used as a JSX component [duplicate]

I am getting this error React error: browserRouter cannot be used as a JSX component. when trying to run something like the following:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css';
import BrowserRouter from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);

root.render(
    <BrowserRouter>
      <App />
    </BrowserRouter>
);

My purpose is to punch multiple strings into a single (shortest) string that will contain all the character of each string in a forward direc [duplicate]

So, to explain the problem:

Let’s consider I have few strings

[“jack”, “apple”, “maven”, “hold”, “solid”, “mark”, “moon”, “poor”, “spark”, “live”]
The Resultant string should be something like:

“sjmachppoalidveonrk”
jack: sjmachppoalidveonrk

apple: sjmachppoalidveonrk

solid: sjmachppoalidveonrk

====================================>>>> all in the forward direction

These all are manual evaluation and the output may not 100% perfect in the example.

So, the point is all the letters of each string have to exist in the output in FORWARD DIRECTION (here the actual problem belongs), and possibly the server will send the final strings and numbers like 27594 will be generated and passed to extract the token, in the required end. If I have to punch it in a minimal possible string it would have much easier (That case only unique chars are enough). But in this case there are some points:

Letters can be present multiple time, though I have to reuse any letter if possible, eg: for solid and hold o > l > d can be reused as forward direction but for apple (a > p) and spark (p > a) we have to repeat a as in one case it appears before p for apple, and after p for sparks so either we need to repeat a or p. Even, we cannot do p > a > p as it will not cover both the case because we need two p after a for apple
We directly have no option to place a single p and use the same index twice in a time of extract, we need multiple p with no option left as the input string contains that
I am (not) sure, that there is multiple outputs possible for a set of strings. but the concern is it should be minimal in length, the combination doesn’t matter if its cover all the tokens in a forward direction. all (or one ) outputs of minimal possible length need to trace.
Adding this point as an EDIT to this post. After reading the comments and knowing that it’s already an existing problem is known as shortest common supersequence problem we can define that the resultant string will be the shortest possible string from which we can re generate any input string by simply removing some (0 to N) chars, this is same as all inputs can be found in a forward direction in the resultant string.
I have tried, by starting with an arbitrary string, and then made an analysis of next string and splitting all the letters, and place them accordingly, but after some times, it seems that current string letters can be placed in a better way, If the last string’s (or a previous string’s) letters were placed according to the current string. But again that string was analysed and placed based on something (multiple) what was processed, and placing something in the favor of something that is not processed seems difficult because to that we need to process that. Or might me maintaining a tree of all processed/unprocessed tree will help, building the building the final string? Any better way than it, it seems a brute force?

Note: I know there are a lot of other transformation possible, please try not to suggest anything else to use, we are doing a bit research on it.
javascriptnode.jsalgorithmemphasized text

Position Fixed – Near to the element, while we have scrolling option

// JS Code:

document.addEventListener("DOMContentLoaded", function () {
    const container = document.getElementById("autoToggleContainer");
    const leftArrow = document.getElementById("left-arrow");
    const rightArrow = document.getElementById("right-arrow");

    // Scroll 200px left/right
    leftArrow.addEventListener("click", () => {
        container.scrollBy({ left: -200, behavior: "smooth" });
    });

    rightArrow.addEventListener("click", () => {
        container.scrollBy({ left: 200, behavior: "smooth" });
    });

    // Tooltip behavior
    $(".autoToggle__switch").hover(function () {
        const tooltip = $(this).find(".auto-toggleTooltip");
        const offset = $(this).offset();
        const height = $(this).outerHeight();

        tooltip.css({
            top: offset.top + height + 10,
            left: offset.left,
            display: "block"
        });
    }, function () {
        $(this).find(".auto-toggleTooltip").hide();
    });

    // Optional: scroll active button into view on load
    const activeBtn = container.querySelector(".autoToggle__switch.active");
    if (activeBtn) {
        activeBtn.scrollIntoView({ behavior: "smooth", inline: "center" });
    }
});
document.getElementById("left-arrow").addEventListener("click", function () {
    document.getElementById("autoToggleContainer").scrollBy({ left: -200, behavior: "smooth" });
});

document.getElementById("right-arrow").addEventListener("click", function () {
    document.getElementById("autoToggleContainer").scrollBy({ left: 200, behavior: "smooth" });
});
// HTML Code:

<div class="autoToggle__wrapper">
    <button class="arrow left" id="left-arrow"><img src="~/Images/AdminPlus/white-prev-arrow.svg" /></button>

    <div class="app__autoToggleswitches" id="autoToggleContainer">
        @foreach (var item in Model.PastYearInfo)
        {
            <button id="[email protected]" class="autoToggle__switch app-text-white app-mr-15" data-idstring="@item.IdString"
                    data-name="@item.Name">
                @item.Name
                <span class="auto-toggleTooltip">Year @item.IdString</span>
            </button>
        }
    </div>

    <button class="arrow right" id="right-arrow"><img src="~/Images/AdminPlus/white-next-arrow.svg" /></button>
</div>

This is the screenshot of output

  • Here we are using postion:fixed; for tooltip because parent element has arrow icons so using overflow hidden.

  • tooltip are showing properly but after clicking next button tooltip position showing same location when loading the page Screenshot added

  • I have tried many ways but not working

Express.js: What does it mean to use body-parser as path parameter of router handler in express.js? [duplicate]

I’m trying to analyze and rebuild some code written by someone that currently consists of an older version of express.js (4.18.2) to a current version of express.js.

const express = require('express');
const bodyParser = require('body-parser');

const app = express();
const onem2mParser = bodyParser.text(
    {
        limit: '5mb',
        type: 'application/onem2m-resource+xml;application/xml;application/json;application/vnd.onem2m-res+xml;application/vnd.onem2m-res+json'
    }
);

app.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, X-M2M-RI, X-M2M-RVI, X-M2M-RSC, Accept, X-M2M-Origin, Locale');
    res.header('Access-Control-Expose-Headers', 'Origin, X-Requested-With, Content-Type, X-M2M-RI, X-M2M-RVI, X-M2M-RSC, Accept, X-M2M-Origin, Locale');
    (req.method == 'OPTIONS') ? res.sendStatus(200) : next();
});

# Where The error occurs
app.post(onem2mParser, function (request, response) {
...
}

I have trouble with app.post() above, and the current version of express.js is throwing the following error:

ERROR   Uncaught Exception  
{
    "errorType": "TypeError",
    "errorMessage": "path must be a string, array of strings, or regular expression",
    "stack": [
        "TypeError: path must be a string, array of strings, or regular expression",
        "    at pathToRegexp (/var/task/node_modules/path-to-regexp/index.js:69:11)",
        "    at new Layer (/var/task/node_modules/express/lib/router/layer.js:45:17)",
        "    at Function.route (/var/task/node_modules/express/lib/router/index.js:505:15)",
        "    at app.<computed> [as get] (/var/task/node_modules/express/lib/application.js:498:30)",
        "    at Object.<anonymous> (/var/task/src/get.js:80:5)",
        "    at Module._compile (node:internal/modules/cjs/loader:1554:14)",
        "    at Object..js (node:internal/modules/cjs/loader:1706:10)",
        "    at Module.load (node:internal/modules/cjs/loader:1289:32)",
        "    at Function._load (node:internal/modules/cjs/loader:1108:12)",
        "    at TracingChannel.traceSync (node:diagnostics_channel:322:14)"
    ]
}

In this part, I used the parser as a middleware with the help of chatgpt, but an error is occuring in another module that is using the code in this part.

const router = express.Router();
router.use(onem2mParser);
router.post('/', function(req, res) => ...);
app.use('/', router);
ERROR   TypeError: ee.on is not a function
    at first (/var/task/node_modules/ee-first/index.js:43:10)
    at onSocket (/var/task/node_modules/on-finished/index.js:115:16)
    at attachFinishedListener (/var/task/node_modules/on-finished/index.js:120:5)
    at attachListener (/var/task/node_modules/on-finished/index.js:147:5)
    at onFinished (/var/task/node_modules/on-finished/index.js:53:3)
    at send (/var/task/node_modules/finalhandler/index.js:314:3)
    at /var/task/node_modules/finalhandler/index.js:133:5
    at /var/task/node_modules/express/lib/router/index.js:646:15
    at next (/var/task/node_modules/express/lib/router/index.js:265:14)
    at textParser (/var/task/node_modules/express/node_modules/body-parser/lib/types/text.js:78:7)

Finally, I have two questions.

  1. What does it mean to insert bodyParser instead of string type into path parameter in app.post()? Is the path then ‘/’?
  2. How do I fix the code to work well with the same logic in the latest 4.x version of express.js?

How to use cache busting with WebOptimizer?

I am using the LigerShark WebOptimizer library (GitHub link) in a .NET 9.0 MVC application. I want to enable cache busting, but whenever I do so, I encounter some difficulties. I find that the documentation is lacking in this department, so i’m hoping that someone out there has this working.

Setup / code configuration

_ViewImports.cshtml:

  @addTagHelper *, WebOptimizer.Core
  @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Program.cs:

  // Bundling tasks abstracted into static method...
  static IAssetPipeline AddBundles(IAssetPipeline pipeline)
  {
      pipeline.AddJavaScriptBundle("~/bundles/jquery",
          "Scripts/jquery-2.1.1.js",
          "Scripts/jquery-ui-1.11.4.js",
          "Scripts/jquery.unobtrusive-ajax.js",
          "Scripts/jquery.ticker.js"
      );

      return pipeline;
  }

  // Call to the bundler
  services.AddWebOptimizer(pipeline =>
  {
      AddBundles(pipeline);
  }, opt => // I have to explicitly state a default opt...otherwise minification does not work.
  {
  });

  app.UseWebOptimizer();
  app.UseStaticFiles();   

_Layout.cshtml (referenced on all views):

  <script src="~/bundles/jquery"></script>

Issues

  1. Scripts are no longer in a bundle (e.g. /bundles/jquery), but are referenced directly. Here is the output from Firefox Developer Tools:
  GET https://localhost:7063/Scripts/jquery-2.1.1.js?v=CPMzgO5SHQa9XMvzKiSCYj6ECb0Edy0rHFl04JXlkY0 
  GET https://localhost:7063/Scripts/jquery-ui-1.11.4.js?v=R9bDu_ZQj9QsBSatxVF1s40Ckf5e7NJDAg-CYP1ZcZM
  1. The framework appears to look for the scripts in the current directory. For instance, if I navigate to https://localhost:7063/Account then the following happens:
  GET https://localhost:7063/Account/Scripts/jquery-2.1.1.js?v=CPMzgO5SHQa9XMvzKiSCYj6ECb0Edy0rHFl04JXlkY0
  GET https://localhost:7063/Account/Scripts/jquery-ui-1.11.4.js?v=R9bDu_ZQj9QsBSatxVF1s40Ckf5e7NJDAg-CYP1ZcZM

(Note the Account sub directory) The result (as expected) is a bunch of 404 errors as my scripts exist at the application root level.

Woocommerce Error preventing me from adding custom fields to checkout

Long shot, but I’m hoping someone can help. I’m trying to add some custom checkout fields to my checkout page, but either doing it manually in the functions.php file, or by using a plugin, the checkout page doesn’t change whatsoever.

https://mainflorist.com/checkout/

I am seeing a this error, but not sure what’s causing it. I am using PHP 8.3 and the Jupiter X theme, but even with other themes, the errors persist. The error occurs with or without any modifications to the functions.php file.

Store "wc/store/validation" is already registered.
c @ data.min.js?ver=7c62e39de0308c73d50c:2
register @ data.min.js?ver=7c62e39de0308c73d50c:2
(anonymous) @ data.min.js?ver=7c62e39de0308c73d50c:2
9538 @ wc-cart-checkout-base-frontend.js?ver=c805309b07586da6f60a:43
l @ checkout-frontend.js?ver=5dd64761c5edaf06069b:1
8682 @ wc-cart-checkout-base-frontend.js?ver=c805309b07586da6f60a:43
l @ checkout-frontend.js?ver=5dd64761c5edaf06069b:1
1669 @ shipping-method-frontend.js?ver=3ffd12c88ab2c3188c1c:1
l @ checkout-frontend.js?ver=5dd64761c5edaf06069b:1
Promise.then
(anonymous) @ checkout-frontend.js?ver=5dd64761c5edaf06069b:1
c @ react.min.js?ver=18.3.1.1:10
Qs @ react-dom.min.js?ver=18.3.1.1:10
wl @ react-dom.min.js?ver=18.3.1.1:10
bl @ react-dom.min.js?ver=18.3.1.1:10
yl @ react-dom.min.js?ver=18.3.1.1:10
fl @ react-dom.min.js?ver=18.3.1.1:10
Nn @ react-dom.min.js?ver=18.3.1.1:10
(anonymous) @ react-dom.min.js?ver=18.3.1.1:10

Thank you.

Execute GraphQL mutation using Next.js API Routes

How can I execute a graphql mutation using an authenticated user and API Routes in Next.js. I tried to use generateClient() from aws-amplify/api but it throws NoSignedUser: No current user error.

const graphqlclient = generateClient();

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === 'POST') {
    const body = req.body;

    if (!graphqlclient) return res.status(401).json({ message: 'Unauthorized' });

       const newProduct = body.newProduct;


       const results = await graphqlclient.graphql({
           query: createProduct,
           variables: {
               input: newProduct
           }
       })

       return res.status(200).json({ success: true, product: results });
    }

    res.status(405).json({ message: 'Method not allowed' });
}

I have also tried

const client = generateServerClientUsingCookies({
   config: amplifyConfig,
   cookies
});

but I get the error cookies was called outside a request scope.

How to create an astro project with “JavaScript”?

When I run npm create astro@latest it is not asking me whether I want the astro project to be TypeScript or JavaScript anymore.

I want to know, if there is any way, I can create an Astro Project with just JavaScript.

I’ve also tried this following approaches but nothing seemed to work:

  • Deleted the tsconfig.json file that was auto generated when creating the astro project
  • added ---lang='js' at the top of the .astro file
  • Restarted the server after applying the above changes.

SQL Query – To fetch record count based on not in condition

I have table A

ID Code
100 S01
100 S02
101 S01
101 S03
102 S01
102 S03
103 S01
103 S02
103 S04
104 S01
104 S02

I want to get count of ids which have code S03 and ids with out code S03

Expected Result

CodeFound NoCode
2 3

Here code found ids would be(101,102) and no code are(100,103,104)

Im having issue in fetching NoCode records it is fetching the count of records which are not supposed to..

select count(unique ID) from A where Code not in 'S03'

Can someone please help on this

Is there a way to pull a redirect link using apps script from google sheets?

I’m trying to create a google form that populates a google sheet. I have the form, “Gym Form A” and “Gym Form B” working but A won’t automatically redirect to B.I have a macro that generates a link and that link is filled on the last row and column of a specific sheet on google sheets. I wanted to pull that link dynamically and then just have the sheet A redirect to there but it isn’t working.

Redirect code

function onFormSubmit(e) {
  generatePrefilledLinks();
}

function generatePrefilledLinks() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const data = sheet.getDataRange().getValues();
  const headers = data[0];

  const dateIndex = headers.indexOf("Workout Date");
  const typeIndex = headers.indexOf("Workout Type");

  if (dateIndex === -1 || typeIndex === -1) {
    throw new Error("Headers 'Workout Date' and/or 'Workout Type' not found.");
  }

  const baseURL = "https://docs.google.com/forms/d/e/1FAIpQLScojqj2IUfZSpyOATMsJKuTbr_iSGJ3NginEBY4wCwWddp8-A/viewform";
  const linkCol = headers.length + 1;
  sheet.getRange(1, linkCol).setValue("Prefilled Exercise Log Link");

  const lastRowIndex = data.length - 1;
  const workoutDate = encodeURIComponent(data[lastRowIndex][dateIndex]);
  const workoutType = encodeURIComponent(data[lastRowIndex][typeIndex]);

  const prefillURL = `${baseURL}?entry.1754835796=${workoutDate}&entry.2111064850=${workoutType}`;
  sheet.getRange(lastRowIndex + 1, linkCol).setValue(prefillURL);
}

As you can see, when I fill in form A it populates the bottom right of the “prefilled exercise log link header

I would like it to actually take that link and update the gym form A redirect link so it autofill’s my gym form B portion so all I need to do is fill up gym form B Gym Form A redirect link

However it isn’t working and I’m getting a blank screen Current issue screen

Before I was getting invalid values on the other page, but the code I have gives the correct link.

function doGet() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const data = sheet.getDataRange().getValues();

  if (data.length < 2) {
    return HtmlService.createHtmlOutput("No responses found.");
  }

  const lastRow = data.length - 1; // last row (0-indexed)
  const lastCol = data[0].length - 1; // last column (0-indexed)
  const lastValue = data[lastRow][lastCol].trim(); // Trim any leading or trailing spaces

  // Log for debugging purposes
  Logger.log("Last value: " + lastValue);

  // Ensure the last value is a valid URL and redirect directly
  const htmlContent = `
    <html>
      <head>
        <meta http-equiv="refresh" content="0; url=${lastValue}" />
      </head>
      <body>
        <p>Redirecting to the workout log...</p>
      </body>
    </html>
  `;

  // Return HTML content
  return HtmlService.createHtmlOutput(htmlContent);
}

Get link code

I deployed and have it on anyone with link and the executer is “me” not sure where else to go.

Smooth style application on target element in Dragenter and Dragleave

I’d like to apply a dashed border around my targeted table columns when a draggable element is hovered over the column on dragenter, and remove the border on dragleave.

I am able to successfully target and style these table columns, however there is a “blinking” effect where the border gets quickly applied/removed. Is there a way I can add in a specific check to make this drag transition between columns smoother and avoid these event listeners/style application and removal from being executed unnecessarily?

<div draggable="true">Drop item</div>

<table>
  <tbody>
    <tr>
      <td class="cell" data-column-number="1">Cell-1</td>
      <td class="cell" data-column-number="2">Cell-2</td>
    </tr>
    <tr>
      <td class="cell" data-column-number="1">Cell-3</td>
      <td class="cell" data-column-number="2">Cell-4</td>
    </tr>
  </tbody>
</table>
const tds = document.querySelectorAll("[data-column-number]")

for (let td of tds) {
  td.addEventListener("dragenter", (event) => {
    let colNum = td.dataset.columnNumber
    let cols = document.querySelectorAll(`[data-column-number="${colNum}"]`)
    
    console.log("<-- drag enter --->")

    for (let col of cols) {
      col.classList.add("hovered")
    }
  })

  td.addEventListener("dragleave", (event) => {
    let colNum = td.dataset.columnNumber
    let cols = document.querySelectorAll(`[data-column-number="${colNum}"]`)
    
    console.log("<-- drag leave --->")

    for (let col of cols) {
      col.classList.remove("hovered")
    }
  })
}
div {
  border: dotted 2px green;
  width: 70px;
  background-color: yellow;
  text-align: center;
  cursor: grab;
}

div:active {
  cursor: grabbing;
}

td.hovered {
  border: dashed 2px red;
}

table {
  margin-top: 30px;
}

JsFiddle Link: https://jsfiddle.net/z8mkdj3y/26/