element.classList.remove(“u-hidden”) does not work

I am using the following code:

 var el = document.getElementById("MY_ITEM");
 el.textContent = "TEST";
 el.classList.add("success_message");
 el.classList.remove("u-hidden");

Everything works up until the line 4. No error message, just that class u-hidden does not get removed from the element so I cannot see it in the browser. Is there a better way to do that?

Google App Script recursive Loop does not trigger prompt.getResponseText()

I made the following script to identify names that were not matching between two files. This works perfectly fine for the first loop, and it gets to the var prompt perfectly fine on the second loop, however whenever I try to complete the prompt on sheets it seemingly does nothing and just stalls there. It is not because of the input because if I do that input the first time it goes through fine. I must be missing something as to why this isn’t looping properly. Any help would be greatly appreciated

function onEdit(e) {
    startPoint();
    
}

function startPoint(){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("README");
    var cell = "N5";
    var difference = sheet.getRange(cell).getValue().toFixed(2);

    if (difference > 0){
      yesDifference(difference);
    }else noDifference(difference);
}

function yesDifference(num){
  const ui = SpreadsheetApp.getUi()
    const result = ui.alert(
     'There is a difference of: ' + 
     num
      + 'nWould you like to solve the issue',
      ui.ButtonSet.YES_NO)
    if (result == ui.Button.YES){
      findDifference(num);
    }else{
      return
    }
}

function noDifference(num){
  const ui = SpreadsheetApp.getUi()
    const result = ui.alert(
     'Tips are matching!');
    return
}

function findDifference(num){
  const ui = SpreadsheetApp.getUi();
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("README");
  var missingNames = sheet.getRange("Z3:Z20").getValues();
  for(var i = 0; i < missingNames.length; i++){
      var person = missingNames[i].toString();
      if(person.length > 1){
        const result = ui.alert(
          'I am not able to match:n' + person + 'nbetween Harri and R365 would you like to try and find them?',
          ui.ButtonSet.YES_NO);
        if(result == ui.Button.YES){
          findNameMatch(person);
        }
      }
  }
    return
}

function findNameMatch(name){
  const ui = SpreadsheetApp.getUi();

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("README");

  var allNames = sheet.getRange("A2:A100").getValues();
  var filteredNames = [];

  for(var i = 0; i < allNames.length; i++){
    var person = allNames[i].toString();
    if(!(person.length > 1)){
      i = allNames.length;
    }else{
      if(!(filteredNames.includes(person))){
        filteredNames.push(person);
      } 
    }
  }

  var prompt = ui.prompt('Out of the following names:nnn' + filteredNames.join('rn') + "nnnPlease enter below which name is supposed to be " + name);

  var fullName = prompt.getResponseText().toString();

  var resp = ui.alert(fullName);

  var firstName = fullName.substring(0, fullName.indexOf(' '));
  var lastName = fullName.substring(fullName.indexOf(' ') + 1);

  var originalFirst = name.substring(0, name.indexOf(' '));
  var originalLast = name.substring(fullName.indexOf(' ') + 1);

  var names = ui.alert(
    'First Name: ' + firstName + "nLast Name: " + lastName
  )

  changeName(originalFirst, firstName, originalLast, lastName);
  startPoint();
}

function changeName(oldF, correctF, oldL, correctL){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("365");
  var allFNames = sheet.getRange("A2:A100").getValues();
  var allLNames = sheet.getRange("B2:B100").getValues();

  for(var i = 0; i < allFNames.length; i++){
    var name = allFNames[i].toString();
    var lastName = allLNames[i].toString();
    if(!(name.length > 1)){
      i = allFNames.length;
    }else{
      if((name === oldF) &&(lastName === oldL)){
        var newFirst = "A" + (i + 2);
        var newLast = "B" + (i + 2);

        var newFNames = sheet.getRange(newFirst).setValue(correctF);
        var newLNames = sheet.getRange(newLast).setValue(correctL);

        const ui = SpreadsheetApp.getUi();
        const result = ui.alert(
        'The names have been changed at ' + newFirst + ", and " + newLast + " to " + correctF + ", and " + correctL);
        i = allFNames.length;
      }
    }
  }
  return
}

Returning undefined and NaN

When I call a function using a method, it’s returns undefined and Nan.

When it’s called counter.increment, it should return the input “init” + 1, counter.decrement should return “init” – 1 and counter.reset should return the initial value of “init”. But instead for some reason, the three console.log returns undefined and the function createCounter returns NaN.

var createCounter = function(init) {
    
    return {

        increment: (init) => {
            
            console.log(init);
            return init++;

        },

        decrement: (init) => {

            console.log(init);
            return init--;

        },

        reset: (init) => {

            console.log(init);
            return init;
            
        }

    }

};


const counter = createCounter(5)
counter.increment(); // 6
counter.reset(); // 5
counter.decrement(); // 4

ChatGPT API Issue or jQuery – Not Retrieving Full Response

I have some javascript that is analysing content, it generates a content analysis of content initially, and then adds a button to “write content” about the content analysis.

My problem is the first section to analyse works, but it only generates the first 50 words or so and cuts off. When I click the write content button, it seems to generate the next 50 words and not actually do according to the prompt.

What am I doing wrong? is my API calls correct?

<script>
function fetchChatGPTResponse(content, postNo) {
        $.ajax({
            url: 'chatgpt_api.php',
            method: 'POST',
            data: {
                prompt: 'write a content analysis based on this: ' + content // Use the post content as the prompt
            },
            success: function(response) {
                // Display the content analysis in the response div
                document.getElementById('response' + postNo).innerHTML = response + `<br><button onclick="fetchChatGPTArticle('${encodeURIComponent(response)}', '${postNo}');">Write Content</button>`;
    
                    
            },
            error: function() {
                document.getElementById('response').innerText = "Error";
            }
        });
    }
    
    function fetchChatGPTArticle(article, postNo2) {
        $.ajax({
            url: 'chatgpt_api.php',
            method: 'POST',
            data: {
                prompt: 'Based on this content analysis pasted after this statement, could you write me an article to reinforce this statement in 1000 words, ensure that it is engaging. Don't include any stats about upvotes and comments: ' + decodeURIComponent(article)
            },
            success: function(article) {
                // Display the generated article in the article div
                document.getElementById('article' + postNo2).innerHTML = article;
            },
            error: function() {
                document.getElementById('article' + postNo2).innerText = "Error";
            }
        });
    }
        </script>

chatgpt_api.php:

<?php
$api_key = 'XXXX';

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['prompt'])) {
    $prompt = $_POST['prompt'];

    $data = [
        'model' => 'gpt-3.5-turbo',
        'messages' => [['role' => 'user', 'content' => $prompt]],
        'max_tokens' => 100
    ];

    $headers = [
        'Content-Type: application/json',
        'Authorization: Bearer ' . $api_key,
    ];

    $ch = curl_init('https://api.openai.com/v1/chat/completions');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

    $response = curl_exec($ch);
    curl_close($ch);

    $responseData = json_decode($response, true);
    $message = $responseData['choices'][0]['message']['content'] ?? 'No response from ChatGPT.';

    echo $message; // Return the response to the AJAX call
}
?>

Node.js – specific parts of Node needed to multiple-player online game [closed]

I’m working on a self-created JavaScript project to shore up my knowledge of JavaScript and Tailwind CSS but also to learn Node.js. The project I am working on is a Bingo game.

The goal: multiple people log onto the site on their computer. Each has a Bingo card. The server spits out the numbers. The players are responsible for marking their own card (it won’t mark automatically like a few games I’ve seen on the internet). When a player gets a Bingo, they click the Bingo button. The (server?/client?) verifies that the player has a legitimate bingo. The first to hit the bingo button wins (a little concerned about whether lagging or delay could cause the wrong player to be declared the winner).

I’m good with creating a Bingo game itself. What I’m unsure about is the online part a/k/a the Node.js part. I’m having trouble figuring out all the pieces I will need to learn to put this together. Obviously I’ll need some GET/POST requests. I’m not sure if I’ll need local or session storage (for the balls maybe?). I don’t think I’ll need a database unless I decide to save a history of winners somewhere (even then, is a database required)? Not sure what else I need.

I’m somewhat confused by Node. Not looking for specific code – I want to study and figure it out. What I’m hoping is that you call can just tell me the specific Node parts/topics I will need to study and implement for this game.

I should also mention that I am wanting to keep this strictly vanilla JavaScript and Node.js – no React or Vue or any sort of JavaScript frameworks.

Thanks!

Recursive nested ul ordered by depth

I am creating a nested list from an array generated from an hierarchical table of categories, with subcategories having a parent ID of the parent category ID. I am trying to display the list in a format like folders and files, where list items with more items in them are grouped together like folders followed by those that don’t, let’s call them files.

I have managed to create the list but each set of categories and subcategories are displaying in alphabetical order as opposed to the desired format outlined below. I have tried to achieve the desired format inside the recursive function as well as a separate function targeting these “folders” after the list has been generated.

The desired outcome would look like this:

<ul id='myList' class="folder">
  <li data-id=0>
    <ul class="folder">
      <li data-id=1>catA
        <ul class="folder">
          <li data-id=3>catA_1
          <ul>
            <li data-id=4>catA_1_1</li>
          </ul> 
          <ul>
            <li data-id=5>catA_1_2</li>
          </ul> 
          <ul>
            <li data-id=6>catA_1_3</li>
          </ul>                              
          </li>
        </ul>
        <ul class="folder">
          <li data-id=8>catA_3
            <ul>
              <li data-id=9>catA_3_1</li>
            </ul>
            <ul>
              <li data-id=10>catA_3_2</li>
            </ul>
            <ul class="folder">
              <li data-id=11>catA_3_3
                <ul>
                  <li data-id=12>catA_3_3_1</li>
                </ul>
                <ul data-id=13>catA_3_3_2</ul>
              </li>
            </ul>
          </li>
        </ul>
        <ul>
          <li data-id=7>catA_2</li>  <!-- *Note these two (data-id = 7 & 14) trail the above "folders" as they have no items in them -->
        </ul>
        <ul>
          <li data-id=14>catA_4</li>
        </ul>               
      </li>
    </ul>
    <ul>
      <li data-id=2>catB</li> <!-- And so on with catB -->
    </ul>    
  </li>
</ul>

  const src = [[1,"catA",0],[2,"catB",0],[3,"catA_1",1],[4,"catA_1_1",3],[5,"catA_1_2",3],[6,"catA_1_3",3],[7,"catA_2",1],[8,"catA_3",1],[9,"catA_3_1",8],[10,"catA_3_2",8],[11,"catA_3_3",8],[12,"catA_3_3_1",11],[13,"catA_3_3_2",11],[14,"catA_4",1],[15,"catB_1",2],[16,"catB_1_1",15],[17,"catB_1_2",16],[18,"catB_1_3",16],[19,"catB_2",15],[20,"catB_3",15],[21,"catB_3_1",20],[22,"catB_3_2",20],[23,"catB_3_3",20],[24,"catB_3_3_1",23],[25,"catB_3_3_2",23],[26,"catB_4",15]];

function tree(src, parent = 0) {
  const el = document.getElementById("myList").querySelector("li[data-id='" + parent + "']");
  
  if (!el) return;
  
  for (var i = 0; i < src.length; i++) {
    if (src[i][2] === parent) {
      const new_parent = src[i][0];
      el.insertAdjacentHTML("afterend", "<ul><li data-id='" + new_parent + "'>" + src[i][1] + "</li></ul>");
      el.parentElement.classList.add("folder");
      tree(src, new_parent);
    }
  }
}

tree(src)
<ul id='myList'>
  <li data-id=0></li>
</ul>

When compressing image submitted through form before upload. First submit will fail but subsequent attempts complete as expected

I’m creating a screenshot submission form, and I want to compress the image before uploading it to my server. I’ve got the process so it works, but whenever I test it the first time I try submitting it fails. Clicking the submit button a second time, without changing anything, without re-selecting the file, just simply clicking submit again, it succeeds as I would expect it to.
I’m using Next.js, with swr and react-toastify to handle data fetching/caching and user notification respectively.

This is my compression function.

const compressImage = imgData =>
   new Promise((resolve, reject) => {
      const img = document.createElement("img");
      img.src = imgData;
      console.log(img);
      const canvas = document.createElement("canvas");
      const context = canvas.getContext("2d");

      const originalWidth = img.width;
      const originalHeight = img.height;
      console.log(originalWidth, originalHeight);

      const baseWidth = 480;
      const baseHeight = 270;
      const canvasWidth = Math.min(baseWidth, ((originalWidth * baseHeight) / originalHeight) | 0);
      const canvasHeight = Math.min(baseHeight, ((originalHeight * baseWidth) / originalWidth) | 0);
      console.log(canvasWidth, canvasHeight);

      canvas.width = Math.min(originalWidth, canvasWidth);
      canvas.height = Math.min(originalHeight, canvasHeight);
      console.log(canvas.width, canvas.height);

      try {
         context.drawImage(img, 0, 0, canvasWidth, canvasHeight);
      } catch (err) {
         return reject(err);
      }

      // Reduce quality
      canvas.toBlob(blob => {
         if (blob) resolve(blob);
         else reject("No blob");
      }, "image/jpeg");
   });

I suspect the issue is either here with how I’m creating the img element, or somewhere before here and this is where it’s making itself obvious.

When I check the logs I see the first attempt shows me the src being set correctly, but a size of 0 0 which then propagates down, and my expectation is that when the canvas size is 0 there’s nothing to put in the blob at the end.

<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD…">
0 0
0 0
0 0

The second submit gives be logs like I would expect to see.

<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD…">
1920 1080
480 270
480 270

I’m a bit lost on what to look for or what to change. It feels like somehow there’s a react hook that’s using stale data, but then why would the img src be correct in the compression function.

I’ve created this form for submitting:

<Modal.Body>
   {screenshot && (
      <img
         src={screenshot}
         alt="Submitted Screenshot"
         width="100%"
         style={{ objectFit: "contain" }}
      />
   )}
   <form
      id="screenshotForm"
      action={async formData => {
         setSubmitting(true);
         const screenshotFile = formData.get("screenshot");
         // Is this actually redundant?
         const screenshotData = await new Promise(resolve => {
            const fr = new FileReader();
            fr.addEventListener("load", e => resolve(e.target.result));
            fr.readAsDataURL(screenshotFile);
         });
         try {
            const compressedData = await compressImage(screenshotData);
            const blobUrl = URL.createObjectURL(compressedData);
            setScreenshot(blobUrl);
            const formData = new FormData();
            formData.append("image", compressedData);
            formData.append("beatmapId", selectedMap.id);
            formData.append("mods", selectedMap.mods);
            await toast.promise(
               mutate("/api/db/player", () => uploadScreenshot(formData), {
                  optimisticData: oldData => {
                     const updatedMaplist = oldData.maps.current;
                     const index = updatedMaplist.findIndex(
                        m => m.id === selectedMap.id && m.mods === selectedMap.mods
                     );
                     updatedMaplist[index].screenshot = compressedData.arrayBuffer();
                     return {
                        ...oldData,
                        maps: {
                           ...oldData.maps,
                           current: updatedMaplist
                        }
                     };
                  },
                  populateCache: (result, oldData) => ({
                     ...oldData,
                     maps: {
                        ...oldData.maps,
                        current: result
                     }
                  })
               }),
               {
                  pending: "Uploading",
                  success: "Image uploaded",
                  error: "Unable to upload image"
               }
            );
         } catch (err) {
            toast.error("Unable to upload image");
            console.error(err);
         }
         setSubmitting(false);
      }}
   >
      <FormLabel htmlFor="imageUpload">Upload Screenshot</FormLabel>
      <FormControl type="file" accept="image/*" id="imageUpload" name="screenshot" />
   </form>
</Modal.Body>
<Modal.Footer>
   <Button type="submit" form="screenshotForm" disabled={submitting}>
      Submit {submitting && <Spinner size="sm" />}
   </Button>
   <Button onClick={() => setShowModal(false)}>Done</Button>
</Modal.Footer>

Both of these are in the page.js file, which is declared as “use client”;
uploadScreenshot is imported from ‘./actions’ which is “use server”;

Another possible symptom is that the spinner on the button shown by submitting is never visible. But if that’s a separate issue then I don’t care about it here.

Need help understanding how to make fetch request from React frontend to Node backend

I have a fundamental understanding of how my project architecture needs to look based on the resources I am using but I’m getting hung up on implementing specific features to create my MVP. I am working on a project which makes calls to a third-party api (tumblr for anyone wondering) and I have the basics set up and understanding to get the data I want to my Node backend server. Where I’m having trouble is passing that data back to my React frontend to use.

My Node backend currently passes back a single url under “url” in my response json, like so:

app.get("/img", async (req, res) => {
  // Make the request
  var response = await client.taggedPosts(req.tag, { limit: 1 });
  console.log(response[0].post_url);
  res.json({ url: response[0].post_url });
});

where url is a string.

The idea is to then return that url for my frontend to use, which makes a call to the node server when a button is clicked:

function SearchBar() {
  const [resList, setResList] = React.useState(null);
  const FetchAPI = () => {
    if (document.getElementById("search-input").value) {
      console.log("fetching...");
      fetch("/img", { tag: document.getElementById("search-input").value })
        .then((res) => res.json())
        .then((data) => setResList(data.url));
    } else {
      //Pop-up handler to be added?
    }
    if (resList) {
      console.log(resList);
    }
  };

  useEffect(() => {}, []);

  return (
    <span className="SB-span">
      <form>
        <input id="search-input" type="search" placeholder="Search" />
        <button onClick={FetchAPI}>Search</button>
      </form>
    </span>
  );
}

As far as debugging goes I can temporarily see the console outputs that tell me the fetch call is being made though I can’t see any update to resList and the console clears itself in the browser after each call. This is most likely a fundamental misunderstanding on my part but I’m a bit lost as React has so much documentation with numerous solutions to a given problem.

What I’m looking for is to receive one singular url which may be expanded into a list of multiple later on, and to pass that result to another component on the page with the intention of cycling through the results like a slideshow. If more info is needed feel free to let me know and I will answer to the best of my ability.

How to stop css rotate animation resetting to 0 when using set angle points?

I had a menu design idea that involves a central cursor that points to indicate what menu item is currently being selected. I achieved this using some JavaScript code that takes a list of fixed angles that represent the buttons and then calculates whether to rotate clockwise or anti-clockwise based on whichever would require less degrees to reach. The issue I encountered however was that upon going from these 2 angles (222° to 115° and vice versa) the arrow would not take the fastest route and spin the opposite direction.

After doing some research what I believe to actually be happening is the cursor is resetting to 0° so that it completes the circle before then making its way to the selected angle from the zero point thus causing it to go the wrong direction. I read a few answers on here and did some general research on the rotate function as a whole but have been unable to find a case that is similar enough to mine nor intuit a way in-which I could fix it myself (web development as a whole is new to me). I would ideally like for it to ignore the rule that compels it to complete the circle and instead just point to the supplied angle though I am aware that is likely impossible to do with css’s rotate tool, so if there is anything that would do the same to that effect it would be much appreciated. I made a functional example to showcase my issue in a jsfiddle.

html:

<img src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.sVcpgS1I_6kEJvuOecuuUgHaHa%26pid%3DApi&f=1&ipt=00bebfbdf248c4677c3ad5a9f6910bdfbd564aa401d634006f527981942f13d6&ipo=images" id="cursor">

css:

#cursor {
    width: 100px;
    height: 100px;
    position: absolute;
    top: 40%;
    left: 40%;

    transition: all 0.25s ease-out;
    -moz-transition: all 0.25s ease-out;
    -ms-transition: all 0.25s ease-out;
    -o-transition: all 0.25s ease-out;
    -webkit-transition: all 0.25s ease-out;
}

js:

const angles = {        // Dictionary of where we want our static angle positions to be
    button1: 290,
    button2: 222,
    button3: 115,
    button4:  75,
    button5:  0
}

var cursor = document.getElementById("cursor")
var currentAngle = 0;

$(".button").hover(function(){      // When mouse enters button area

    let next_angle = angles[this.id];
    let turn_radius = 0;
    let clockwise = (Math.abs(next_angle - currentAngle) < 180) ? true : false; // Calculates which direction is less degrees from source and returns boolean

    if (clockwise){
        turn_radius = (next_angle - currentAngle);
    }
    else {
        turn_radius = "-" + (360 - Math.abs(next_angle - currentAngle));
    }
    cursor.style.rotate = turn_radius +"deg";
});

https://jsfiddle.net/u3w4vz1n/latest/

Set Firebase Web Frameworks SSR Database URL?

I’m using Firebase web frameworks.

I have two realtime databases on my project, project-name.firebaseio.com and project-name-dev1.firebaseio.com.

I have no problem setting the database to development version on the frontend, or on cloud functions, but on generated function that does server-side-rendering, ssrprojectname, I’m always defaulting to project-name.firebaseio.com (the production database), when I want to be able to set it to my hosted development database.

I can’t easily use the emulator because my dev database is too big.

I’m seeing this on the console when starting up:

[apiv2][body] GET https://firebase.googleapis.com/v1beta1/projects/-/webApps/1:REDACTED_NUMBER:web:REDACTED_HASH/config {"projectId":"project-name","appId":"1:REDACTED_NUMBER:web:REDACTED_HASH","databaseURL":"https://project-name.firebaseio.com","storageBucket"...

and

[2024-10-23T04:43:14.749Z] <<< [apiv2][body] GET https://firebase.googleapis.com/v1beta1/projects/project-name/adminSdkConfig {"projectId":"project-name","databaseURL":"https://project-name.firebaseio.com","storageBucket"...}

The important parts above are that I want to use project-name-dev1.firebaseio.com for the database, and not the production version.

.firebaserc

{
  "projects": {
    "default": "project-name"
  },
  "targets": {
    "project-name": {
      "hosting": {
        "hosting-name": [
          "hosting-name"
        ]
      },
      "database": {
        "main": [
          "project-name",
          "project-name-dev1"
        ]
      }
    }
  },
  "etags": {}
}

Another hint is that I see a .env file generated when I start the hosting,function emulators (.firebase/hosting-name/functions/.env):

...
__FIREBASE_DEFAULTS__="config":{"projectId":"project-name","appId":"1:REDACTED_NUMBER:web:REDACTED_HASH","databaseURL":"https://project-name.firebaseio.com","storageBucket"...

Again, this uses https://project-name.firebaseio.com instead of https://project-name-dev1.firebaseio.com that I want to set up.

Maybe the actual question is, how is that .env generated, and can I control it?

I’m using Nuxt / VueFire, Vue 3, but I don’t think that matters here.

React Redux access full store state via hook like useSelector

I’m learning Redux to use it with React. And I’m stuck with a simple task.
I have a store which consists of an array of objects like this

const initialState = {
  items: [
    {
      property1: someValue,
      property2: someValue,
      ...
    },
    {
      property1: someValue,
      property2: someValue,
      ...
    },
    {
      property1: someValue,
      property2: someValue,
      ...
    },
    ...
  ]
}

I’ve set up Provider, store, sliceReducer, and all other necessary stuff.

At one place in my app I need to get a particular item by Id. So I’ve written a selector function for this and using it with a useSelector hook. And it works nice.

But at the other place I need to get whole array of objects. This means I need to get a full store state. And selector functions are only for selecting some piece of the store.

I thought that calling useSelector hook without parameters will give me whole that state object I’m getting in selector functions. However it throws an error that I must pass a selector to useSelector.

I know that there is the useStore hook exists but I’ve read that it gives a reference to store without rerenders. So it means that this hook does not update this reference when the store state changes.

How can I get full store state in my React component using hook like useSelector with rerenders?

cy.intercept not applying header

I’m using cypress to test an api, and I’ve got an access_token parameter in the hash that I need to stick in the Authorization header for all requests.

In the example below, if I use the header directly in the request() call, everything works perfectly. If I move it into the interceptor, I get a 401/Unauthorized. What am I doing wrong?

cy.location('hash').then((hash) => {
    // Extract access_token from hash
    const params = new URLSearchParams(hash.replace('#', ''));
    const accessToken = params.get('access_token');
    cy.log(`Adding Authorization header: Bearer ${accessToken}`);

    // Intercept all requests
    cy.intercept('*', (req) => {
      // Add Authorization header
      
      if (accessToken) {
        //req.headers['Authorization'] = `Bearer ${accessToken}`
      }
      req.continue()
    }).as('auth');

    cy.request({
      url: '/v1/me',
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    }).then((response) => {
      expect(response.status).to.eq(200)
      expect(response.body).to.have.property('email')
    })
  });

How to Run a modern Website on Android 4.2.2 Tablet [closed]

I have multiple old tablets with me, which only support upto Android 4.2.2 version. I want to run a website I built on those tablets. I am opening the link on the chrome browser and my main page loads but only the headers and footers are visible. My main content is not visible. I am guessing the reason could be the html, js and css are not able to be rendered there.

I am willing to buy a new tablet, however I have around 10 tablets with android 4.2.2 which i don’t want to waste. I am planning to use these tablets in my restaurant for customers to browse the menu.

Any suggestions on how can i solve the issue?

I have also tried to build an app with the features and send an apk file to the tablet, but i was unsuccessful in that also.

I have tried to reduce the resolutions but that also did not help.

Sample html file of the page:

<!-- header.html -->
<!-- *Resolution:** 1024 x 552, Fixed Landscape Orientation -->
<!-- Header / Title Bar -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
  <title>HA Dashboard</title>
  <link rel="icon" href="data:,">
  <!--Link to CSS file for styling   --> 
  <link rel="stylesheet" href="setting.css">
  <!-- Include polyfills for older browsers -->
  <!-- <script src="/Appwebsite/js/polyfills.js"></script> -->
  <!-- Include the MQTT.MIN.js library   -->
  <!-- <script src="/Appwebsite/js/mqtt.min.js"></script> -->
  <script src="mqtt.min.js"></script> <!--Include the MQTTWS31.js library -->  
  <script src="mqtt.js"></script>  <!--Link for MQTT connection -->
</head>
<body>
    <div class="wrapper" id="wrapper">
      <div class="header" id="header">
          <img src=hass1.jpg" alt="Dashboard Icon" style="height: 30px; vertical-align: middle;padding-left: 30px; padding-right: 30px;">
          Restaurant
          <div class="tabs">
              <div class="tablinks" id="page1">A</div>
              <div class="tablinks" id="page2">B</div>
              <div class="tablinks" id="page3">C</div>
              <div class="tablinks" id="page4">D</div>
              <div class="tablinks" id="page5">E</div>
              <div class="tablinks" id="page6">F</div>
          </div>
      </div>
    
      <div id="gridContainer">
          <!-- Content will be loaded dynamically here -->
          <!-- for header.html gridcontainer needs to be empty -->
      </div>
      
      <div class="footer" id="footer">
        <p>&copy; Restaurant. All rights reserved.</p>
      </div>
    </div>

  <!-- Code to function Top menu -->
  <script>
      document.addEventListener("DOMContentLoaded", function() {

          // Define the activePageName variable
          var activePageName = 'Page 1'; // Default to Page 1

          function loadPage(page, pageName) {
              var xhr = new XMLHttpRequest();
              xhr.open('GET', page, true);
              xhr.onreadystatechange = function() {
                  if (xhr.readyState === 4 && xhr.status === 200) {
                      document.getElementById("gridContainer").innerHTML = xhr.responseText;
                      activePageName = pageName;
                      updateActivePage();
                  }
              };
              xhr.send();
          }

          // Update the visual indicator for the current page
          function updateActivePage() {
              // Update the header text to show the current page name
            //   document.getElementById("currentPage").innerText = activePageName;

              // Remove 'active' class from all buttons and add to the current one
              var buttons = document.querySelectorAll('button');
              for (var i = 0; i < buttons.length; i++) {
                  buttons[i].classList.remove('active');
              }
          }

          const pages = ['page1', 'page2', 'page3', 'page4', 'page5', 'page6'];

          function resetButtonColor() {
            pages.forEach(pageId => {
                document.getElementById(pageId).classList.remove('active');
            });
          }

          // Default to load Page 1 on start
          loadPage('page1.html');
          document.getElementById('page1').classList.add('active');

        pages.forEach((pageId, index) => {
            const pageButton = document.getElementById(pageId);
            pageButton.addEventListener('click', function () {
                resetButtonColor();
                loadPage(`${pageId}.html`, `Page ${index + 1}`); // Load corresponding page
                pageButton.classList.add('active'); // Add active class
            });
        });
      });
  </script>
</body>
</html>

Image upload failing after React Native Version upgrade to 0.75.3 from 0.72.4

I am sending image as form data.
My code was working perfectly but after upgrading the react native version my image upload fails
After debugging i found that images are not getting sent in the form data and somehow image uri which i am passing is sent which results in failed upload

const uploadImage = async (formData: FormData) => {
  while (attempts <= imageRetryAttemptsConstants && !success) {
    const {apiSuccess, responseData} = await NetworkManager.postMultipart(
      NetworkUrls.uploadImage,
      formData,
    

const uploadInspectionImage = async (
  registration: string,
  image: ImageFile,
  code: string,
) => {
  const imageUri = image.editedUri ? image.editedUri : image.rawUri;
  const imageName = `${code}-${image.name}`;
  const params = {
    registration: registration,
    image: {
      uri: getSavedImagePath(imageUri),
      type: image.type,
      name: imageName,
    },
  };
  const formData = createFormData(params);
  await uploadImage(formData);
  return imageName;
};

This is my network manager



  async apiWrapperWithOptions(
    ...args: [string, string, RequestBody?, boolean?]
  ) {
    const [url, type, options = null, isMultipart = false] = args;
    try {
      if (!this.netStatus) {
        throw new Error(Errors.noInternet);
      }
      const headers: RequestInit = this.getHeader(type, options, isMultipart);
      const start = new Date();
      const apiRes = fetch(url, headers);
      const res = await PromiseUtils.timeoutPromise(
        PromiseUtils.createTimeoutReject(NETWORK_TIMEOUT, () => {}),
        apiRes,
      );
      } else {
        const responseText = await res.text();
        const response = JSONbig.parse(responseText);
        Logger.log('successResponse', JSON.stringify(response));
        const timeTaken = new Date().getTime() - start.getTime();
        Logger.log('API timeTaken for URL', url, '##', timeTaken);
        return {responseData: response, apiSuccess: response?.isSuccess};
      }
    } catch (error: ResponseError | any) {
  }


  postMultipart(url: string, params: FormData | null = null) {
    return this.apiWrapperWithOptions(url, 'POST', params, true);
  }

I was trying to send image file but somehow image file was not getting sent instead image uri is going in the api

DOM Node Rendering Issue in Storybook

I am experiencing difficulties integrating a DOM node into Storybook. Although my Twig rendering function correctly generates a DOM node, Storybook returns an error indicating that it expects a valid HTML snippet or DOM node. This issue persists despite thorough checks on the content returned by the function. I would appreciate any guidance on how to resolve this problem to ensure the rendering works correctly and that the DOM node is accepted by Storybook. Any assistance regarding configuration or debugging tips would be greatly appreciated.

Element.stories.js

import { renderTwigTemplate } from '../twig-renderer';

const templatePromise = import('../test.twig?raw');

export default {
    title: 'Card Component'
};

const Template = async (args) => {
    const template = await templatePromise;
    const { default: resolvedTemplate } = template;

    const html = await renderTwigTemplate(resolvedTemplate, args);
    console.log('Retour de la fonction Template :', html);

    if (!html) {
        throw new Error('Le nœud DOM retourné est nul.');
    }
    return html;
};

export const Default = Template.bind({});
Default.args = {
    title: 'Hello, Card!',
    content: 'This is a simple card component.',
};

twig-renderer :
`

import Twig from 'twig';

export function renderTwigTemplate(templateString, data) {
    const template = Twig.twig({ data: templateString });
    const renderedHtml = template.render(data);
    console.log('HTML rendu :', renderedHtml); 

    const templateElement = document.createElement('div');
    templateElement.innerHTML = renderedHtml;

    const firstChild = templateElement.firstChild;
    console.log('Premier enfant du template :', firstChild);
    return firstChild;
}

The logs are returning DOM node but I still have the error “Expecting an HTML snippet or DOM node from the story: “Default” of “Card Component”.”