how can i hide or show select list depends on its value using for loop in vue?

this code:

<b-col md="6">
 <b-form-group label="Sub Matter" label-for="sub_matter">
   <div class="d-flex align-items-center">
     <div class="w-100">
       <b-form-select v-model="matter.sub_matter" :options="subMatterOptions"
         disabled></b-form-select>
     </div>
    <div>
       <b-button variant="primary" class="ml-2" @click="addSubMatter"
         v-if="subMatters.length < 9">
         +
       </b-button>
    </div>
   </div>
  </b-form-group>
 </b-col>

will show select list (disabled) and will show the value of matter.sub_matter and if i click “+” button it will add new select list with v-model=”sub_matter_2″ and if i click “+” button it will add another select list with v-model=”sub_matter_3″ and so on until sub_matter_10

this code:

<b-col md="6" v-for="(subMatterKey, index) in subMatters" :key="index">
  <b-form-group :label="`Sub Matter ${index + 2}`" :label-for="`sub_matter_${index + 2}`"
    v-if="shouldDisplaySubMatter(subMatterKey)">
    <div class="d-flex align-items-center">
     <div class="w-100">
     <b-form-select v-model="matter[subMatterKey]"
     :options="subMatterOptions"></b-form-select>
     </div>
    <div>
    <b-button variant="danger" class="ml-2" @click="removeSubMatter(index)">
      -
     </b-button>
     </div>
    </div>
   </b-form-group>
  </b-col>

will be showing when i press “+” button from the first button

this is the script:

data() {
    return {
        subMatterOptions: [
            { value: 'SubSale (SS)', text: 'SubSale (SS)' },
            { value: 'Direct Developer (DD)', text: 'Direct Developer (DD)' },
            { value: 'Auction (A)', text: 'Auction (A)' },
            { value: 'Love and Affection (Gift)', text: 'Love and Affection (Gift)' },
            { value: 'Perfection of Transfer (POT)', text: 'Perfection of Transfer (POT)' },
            { value: 'Perfection of Charge (POC)', text: 'Perfection of Charge (POC)' },
            { value: 'Discharge of Charge (DC)', text: 'Discharge of Charge (DC)' },
            { value: 'Deed of Receipt and Reassignment (DRR)', text: 'Deed of Receipt and Reassignment (DRR)' },
            { value: 'LOAN', text: 'LOAN' },
            { value: 'Others', text: 'Others' },
        ],
        subMatters: ['sub_matter_2', 'sub_matter_3', 'sub_matter_4', 'sub_matter_5', 'sub_matter_6', 'sub_matter_7', 'sub_matter_8', 'sub_matter_9', 'sub_matter_10'],
        matter: {
            sub_matter: "",
            sub_matter_2: "",
            sub_matter_3: "",
            sub_matter_4: "",
            sub_matter_5: "",
            sub_matter_6: "",
            sub_matter_7: "",
            sub_matter_8: "",
            sub_matter_9: "",
            sub_matter_10: "",
        }
    };
},
computed: {
    filteredSubMatters() {
        return this.subMatters.filter(
            (subMatterKey) =>
                this.matter[subMatterKey] !== null && this.matter[subMatterKey] !== "",
            console.log(subMatterKey)
        );
    },
},
methods: {

    shouldDisplaySubMatter(subMatterKey) {
        console.log("subMatters",this.subMatters)
        console.log("sub_matter_2",this.matter.sub_matter_2)
        console.log("sub_matter_3",this.matter.sub_matter_3)
        console.log("sub_matter_4",this.matter.sub_matter_4)
        console.log("sub_matter_5",this.matter.sub_matter_5)
        console.log("sub_matter_6",this.matter.sub_matter_6)
        console.log("sub_matter_7",this.matter.sub_matter_7)
        console.log("sub_matter_8",this.matter.sub_matter_8)
        console.log("sub_matter_9",this.matter.sub_matter_9)
        console.log("sub_matter_10",this.matter.sub_matter_10)

        if (this.subMatters.indexOf(subMatterKey) === 0) {
            return true;
        }
        const precedingSubMatters = this.subMatters.slice(0, this.subMatters.indexOf(subMatterKey));
        for (const key of precedingSubMatters) {
            if (this.matter[key] !== '') {
                return true;
            }
        }
        return this.matter[subMatterKey] !== null;
    },


    addSubMatter() {
        if (this.subMatters.length < 9) {
            const newSubMatterKey = `sub_matter_${this.subMatters.length + 2}`;
            this.subMatters.push(newSubMatterKey);
        }
    },
    removeSubMatter(index) {
        const subMatterKey = this.subMatters[index];
        this.matter[subMatterKey] = "";
        this.subMatters.splice(index, 1);
    }, 
}

what i’m trying to do is if any of matter.sub_matter_2 until matter.sub_matter_10 has value i want to display its select list otherwise if its empty i don’t want its select list to be displayed (i can add it from “+” button)

currently all select lists are showing, i’m trying to show only select list that has value

in this function:

shouldDisplaySubMatter(subMatterKey) {
        console.log("subMatters",this.subMatters)
        console.log("sub_matter_2",this.matter.sub_matter_2)
        console.log("sub_matter_3",this.matter.sub_matter_3)
        console.log("sub_matter_4",this.matter.sub_matter_4)
        console.log("sub_matter_5",this.matter.sub_matter_5)
        console.log("sub_matter_6",this.matter.sub_matter_6)
        console.log("sub_matter_7",this.matter.sub_matter_7)
        console.log("sub_matter_8",this.matter.sub_matter_8)
        console.log("sub_matter_9",this.matter.sub_matter_9)
        console.log("sub_matter_10",this.matter.sub_matter_10)

        if (this.subMatters.indexOf(subMatterKey) === 0) {
            return true;
        }
        const precedingSubMatters = this.subMatters.slice(0, this.subMatters.indexOf(subMatterKey));
        for (const key of precedingSubMatters) {
            if (this.matter[key] !== '') {
                return true;
            }
        }
        return this.matter[subMatterKey] !== null;
    },

what am i doing wrong?

note: the above code is update form so sub_matter, sub_matter_2, sub_matter_3 and sub_matter_4 has value, these are the outputs of the console log:

console.log("subMatters",this.subMatters) value is:
subMatters 
Array(9) [ "sub_matter_2", "sub_matter_3", "sub_matter_4", "sub_matter_5", "sub_matter_6", "sub_matter_7", "sub_matter_8", "sub_matter_9", "sub_matter_10" ]

console.log("sub_matter_2",this.matter.sub_matter_2) value is: sub_matter_2 Direct Developer (DD)
console.log("sub_matter_3",this.matter.sub_matter_3) value is: sub_matter_3 Auction (A)
console.log("sub_matter_4",this.matter.sub_matter_4) value is: sub_matter_4 Love and Affection (Gift)
console.log("sub_matter_5",this.matter.sub_matter_5) value is: sub_matter_5 null
console.log("sub_matter_6",this.matter.sub_matter_6) value is: sub_matter_6 null
console.log("sub_matter_7",this.matter.sub_matter_7) value is: sub_matter_7 null
console.log("sub_matter_8",this.matter.sub_matter_8) value is: sub_matter_8 null
console.log("sub_matter_9",this.matter.sub_matter_9) value is: sub_matter_9 null
console.log("sub_matter_10",this.matter.sub_matter_10) value is: sub_matter_10 null

Javascript – Handling camera permission when blocked mid stream

I want to handle a exception where the user allows the camera permission for video call but mid streaming to everyone, user decides to block permission through browser permissions.


function handleCameraPermission() {
  if (navigator.mediaDevices.getUserMedia) {
    // The browser supports `getUserMedia()`.
    navigator.mediaDevices.getUserMedia({
      video: true
    }).then(stream => {
      // The user has granted permission to access the camera.
      // Do something with the `stream` object.
      document.getElementById("video").srcObject = stream;
    }).catch(error => {
      // The user has denied permission to access the camera.
      // Display a message to the user explaining why they need to grant permission.
      alert("Please grant permission to access the camera in order to use this feature.");
    });
  } else {
    // The browser does not support `getUserMedia()`.
    // Display a message to the user explaining that their browser does not support this feature.
    alert("Your browser does not support the `getUserMedia()` method.");
  }
}

I have tried this code but this only works the first time when the user is asked for permission. I want to handle this exception at anytime. If there is any event which is triggered when the browser permission is blocked or any other way of handling this.

Javascript to auto-click “Load more”-Button

I’m running the site onlineyoga.ch which uses a third party software.

My issue is on the player page:
https://onlineyoga.ch/programs/entspannungsinseln-im-alltag

Since I can’t change the HTML Code, I would like to run a Javascript that auto-clicks the show more button called “Mehr anzeigen”, which I can add to the custom scripts section.

See Screenshot

I tried several approaches, but didn’t find a working code:

For example:

// Wait until the DOM is fully loaded
document.addEventListener('DOMContentLoaded', function() {
  // Find the button using the class 'button left'
  var button = document.querySelector('.button.left ds-button');

  // Check if the element was found
  if (button) {
    // Simulate a click on the button
    button.click();

    // Display a notification
    window.alert("Button has been clicked!");
  }
});

The problem is, if I test my scripts in the chrome console, I always get a “undefined” back and the click does not happen. So I can’t go further with this..
See Screenshot of Chorme Script testing with Console

Do you know how I can reach my goal and make this clickable with a Javascript and can sucessfully test it on https://onlineyoga.ch/programs/entspannungsinseln-im-alltag ?

How to validate HTML form and call JS function through the same button? If not, how to set it up properly?

I am trying to use required and patterns in my HTML form. The submit button for the form has a function attached to it on document ready that hides the new-guest div and shows the qr-generated div. This function is attached to all page-show buttons. There is also a function that is attached to the form on submit that processes the info in the form. Currently, when I click the submit button, it hides the new-guest div, despite the inputs not being filled out or valid. I feel like there’s a minimal change I can make before I write more specific functions for this form. Any advice on how I can proceed?

<div class="container p-4 view" id="new-guest">
    <!-- when making a form, always start with form class, form-floating is a bootstrap class -->
    <form class="form-floating" method="post" id="infoform">
      <!-- each form-floating div holds a label and the input you want to take in -->
      <div class="form-floating">
        <!-- type is self explanatory, form-control is bootstrap class, placeholder is for the animation to work, required is self explanatory -->
        <input type="text" class="form-control" id="firstName" name="firstName" placeholder="lionel" required><br><br>
        <label for="firstName">First Name</label>
      </div>
      <div class="form-floating">
        <input type="text" class="form-control" id="lastName" name="lastName" placeholder="messi" required><br><br>
        <label for="lastName">Last Name</label>
      </div>
      <div class="form-floating">
        <input type="tel" class="form-control" id="phoneNumber" name="phoneNumber" pattern="[0-9]{10}" placeholder="idk"
          required>
        <label for="phoneNumber">Phone Number</label>
        <small>Format: 1234567890</small><br><br>
      </div>
      <button type="submit" page-show="qr-generated" class="btn btn-primary" value="Submit">Submit</button>
    </form>
  </div>
//function attached to buttons to change div currently viewable
    <script>
      $(document).ready(function (e) {
        showView("home");
        function showView(viewName) {
          $('.view').hide();
          $('#' + viewName).show();
        }
        $('[page-show]').click(function (e) {
          var viewName = $(this).attr('page-show');
          showView(viewName);
        });
      });
    </script>
async function submitForm(e) {
        // Get form values
        e.preventDefault();
        var firstName = document.getElementById("firstName").value;
        var lastName = document.getElementById("lastName").value;
        var phoneNumber = document.getElementById("phoneNumber").value;
....
}
var form = document.getElementById("infoform");
form.addEventListener("submit", submitForm);

Unable to import JavaScript module due to net::ERR_ABORTED 404 (Not Found) – How to fix?

I’ve searched this error on different platform and tried the answers but none worked here is my code

javascript:

import { Octokit } from "./octokit.js";
const TOKEN = "mytoken";
const octokit = new Octokit({
    auth: TOKEN
});

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>gitmail</title>
</head>
<body>
    
</body>
<script type='module' src="test.js" ></script>
</html>

I tried with and without “.js” . tried with “../” and “./” I even wrote the full path to the module but that didn’t help as well.

I am using VS code as editor and the live server. Not only this module but other modules do not work as well

How do I extend the duration of each photo in a fading slideshow carousel on a webpage?

I’ve managed to manipulate a slideshow carousel from w3schools for a carousel slideshow with fading, however it is unclear to me how to make each photo stay on for longer – to pause longer before fading to the next iamge (ie 30 seconds to several minutes).
How do I extend and hold each photo longer on the screen?

(Intent is to only use this on Chrome as a photo display for my monitor/tv)

<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<body>
    <div style="overflow: hidden; background-color: black; height: 100vh;">
        <div class="w3-content w3-section" style="object-fit: contain; max-width: 100%; position: center center;">
  <img class="mySlides w3-animate-fading" src="img_rr_01.jpg" style="width:100%">
  <img class="mySlides w3-animate-fading" src="img_rr_02.jpg" style="width:100%">
  <img class="mySlides w3-animate-fading" src="img_rr_03.jpg" style="width:100%">
  <img class="mySlides w3-animate-fading" src="img_rr_04.jpg" style="width:100%">
        </div>
    </div>
    <script>
        var myIndex = 0;
        carousel();

        function carousel() {
            var i;
            var x = document.getElementsByClassName("mySlides");
            for (i = 0; i < x.length; i++) {
                x[i].style.display = "none";
            }
            myIndex++;
            if (myIndex > x.length) { myIndex = 1 }
            x[myIndex - 1].style.display = "block";
            setTimeout(carousel, 9000);
        }
    </script>
</body>
</html>

I noticed I can’t just set the timeout longer as that causes some photos to just repeat or weird clipping. I also tried to adjust the css to make it longer than 10seconds, but that also causes other weird artifacts/clipping.

React 2 Object of Same Class Having Same Values After Updating One of Them

I am new to react redux and facing a strange problem while working on my project. I have a class named ApiUtils.js which has some set of functions to handle API realted calls.

import axios from 'axios';    
const ErrorResponse = {
  data: {
    message: 'Something went wrong, please try again'
  }
};

class ApiUtils {
  request = null;

  baseUrl = null;

  defaultTimeout = 0;

  constructor(baseUrl, defaultTimeout) {
    this.baseUrl = baseUrl;
    this.defaultTimeout = defaultTimeout;
  }
setAxiosConfig = (isLogin = false, token = '') => {
    // Create a Unauthorised axios Instance
    let headerDetails = {
      'Content-Type': 'application/json'
    };
    if (isLogin) {
      headerDetails = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest'
      };
    }
    if (token) {
      headerDetails = {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${token}`
      };
    }

    this.request = axios.create({
      baseURL: this.baseUrl,
      headers: headerDetails
    });
  };
post = async (url, body, requestTimeout = this.defaultTimeout) => {
    let response = null;
    try {
      response = await this.request.post(url, body, {
        timeout: requestTimeout
      });
      return response;
    } catch (ex) {
      if (ex.response && ex.response.data && ex.response.data.message) {
        throw ex.response;
      } else if (
        ex.response.status === 409 &&
        ex.response.data.error === 'Email Id already exist'
      ) {
        throw ex.response.data;
      } else if (
        ex.response.data.status === 401 &&
        ex.response.data.error === 'Exceeded Reset Passwords Attempts'
      ) {
        throw ex.response.data;
      } else if (
        ex.response.data.status === 401 &&
        ex.response.data.error === 'User type does not match'
      ) {
        throw ex.response.data;
      } else {
        if (
          ex.response &&
          ex.response?.data &&
          ex.response?.data?.data?.message &&
          ex.response?.status === 408
        ) {
          throw ex.response;
        } else {
          // if error response not defined
          // ErrorResponse.data.statusCode = ex.response.status
          throw ErrorResponse;
        }
      }
    }
  };

    export const AuthExternalApiUtils = new ApiUtils(
      process.env.REACT_APP_EXT_BASE_URL,
      process.env.REACT_APP_API_TIMEOUT
    );
    
    export const WsApiUtils = new ApiUtils(
      process.env.REACT_APP_WS_API_ROOT,
      process.env.REACT_APP_WS_API_TIMEOUT
    );
    
    export default new ApiUtils(process.env.REACT_APP_API_ROOT, process.env.REACT_APP_API_TIMEOUT);

I have a 2 objects of this ApiUtils class

export const AuthExternalApiUtils = new ApiUtils(
  process.env.REACT_APP_EXT_BASE_URL,
  process.env.REACT_APP_API_TIMEOUT
);

export const WsApiUtils = new ApiUtils(
  process.env.REACT_APP_WS_API_ROOT,
  process.env.REACT_APP_WS_API_TIMEOUT
);

export default new ApiUtils(process.env.REACT_APP_API_ROOT, process.env.REACT_APP_API_TIMEOUT);

Now if I update the variables of any one of the above the other one has the same value. For example: if I update the baseUrl of WsApiUtils with https://xyzbaseurl.com/ and do console.log(AuthExternalApiUtils.baseUrl) it also has the same value.

Why this is happening? is this an expected behavior or I am doing something wrong here.

Cypress and file upload using drag n drop

I’m attempting to test, using cypress, the functionality of a file upload widget.

The cypress tests which I’ve tried are:

const filePath = './cypress/fixtures/example.jpg'

    cy.get('.dropzone')
    .selectFile(filePath, 
    { action: 'drag-drop',
      force: true, }).trigger('drop', {force: true})

and


    cy.get('.dropzone > input[type="file"]').should('exist').invoke('show')
    .selectFile(filePath, {
      action: 'drag-drop',
      force: true,
      log: true,
    })
    .trigger('drop', {force: true})

The html that the tests are executing against is:

<div tabindex="0" role="button" class="dropzone  svelte-817dg2" style="">
<input accept="image/*" type="file" name="avatar" autocomplete="off" tabindex="-1" style="display: none;"> 
<p>Drag 'n' drop some files here, or click to select files</p>
</div>

In both cases, and every variation on these, the tests never actually upload a file.

However, in the cypress chrome browser, I’m able to manually perform the drag n drop action successfully.

Missing script : “start” while running npm start even though package.json is at the right place with all the scripts in it

Missing script : “Start” while running npm start even though package.json file is in the directory with scripts in it

{
  "name": "typee",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.34",
    "@types/react": "^18.2.7",
    "@types/react-dom": "^18.2.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.5",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

This is my package.json file after running

npx create-react-app typee –template typescript

when I try to run npm start

I get this

Missing script : “start”

Loop through Object and push into Array

I am looking to loop the object and want to add those object in array in Javascript.

 My Object:
        var raw_data = {
            "name":"Mike",
            "age":"27"
        }
     var array_data = []
 
Then I loop through the object: 

  for (let [key, name] of Object.entries(raw_data)) {
    if (name !== "") {
      array_data.push({
        email: `${raw_data.name}`,
        password: `${raw_data.age}`,
      });
    }
  }
  console.log(array_data);

My out put is :

[
  { email: '[email protected]', password: '1234567' },
  { email: '[email protected]', password: '1234567' }
]

I would like expect to get only one insert:

[
  { email: '[email protected]', 
  password: '1234567' }
]

Could you please help me how to get that?

Two Calls to Function, One Failing – Javascript – Chrome Extension

Hi I am working on my first chrome extension and am running into a problem when calling a function. I have a function that sends a prompt to the ChatGPT API and returns a value. When I call it this way:

// Execute if "Context Menu" from background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (
      message.type === "CM_SpellingGrammar" ||
      message.type === "CM_Task" ||
      message.type === "CM_Answer" ||
      message.type === "CM_WordCount" ||
      message.type === "CM_Rewrite" ||
      message.type === "CM_Clarity" ||
      message.type === "CM_Scholar" ||
      message.type === "CM_Tone" ||
      message.type === "CM_StructureOrganization"
     ) {
    CM_result = message.type;
    sendRetrieve();
  }
});

This is a call in my contentScript.js file using inputs from the Context Menu read from my background.js file.

However when I try to call the same function like this:

function TESTCLICKED(event) {
  CM_result = "CM_SpellingGrammar";
   sendRetrieve();
}

The request seems to be send to ChatGPT API but the console just returns “null”

Why is this happening? The function calls seem to be the same with the same inputs.

Here is my function to send a prompt to ChatGPT API:

function sendRetrieve() {
// If there's an active text input
if (
  document.activeElement &&
  (document.activeElement.isContentEditable ||
    document.activeElement.nodeName.toUpperCase() === "TEXTAREA" ||
    document.activeElement.nodeName.toUpperCase() === "INPUT")
) {
  // Set as original for later
  originalActiveElement = document.activeElement;
  // Use selected text or all text in the input
  textOriginal = 
    document.getSelection().toString().trim() ||
    document.activeElement.textContent.trim();
  text =
    document.getSelection().toString().trim() ||
    document.activeElement.textContent.trim();
} else {
  // If no active text input use any selected text on page
  textOriginal = document.getSelection().toString().trim();
  text = document.getSelection().toString().trim();
}
if (!text) {
  alert(
    "No text found. Select this option after right-clicking on a textarea that contains text or on a selected portion of text."
  );
  return;
}

console.log(originalActiveElement);


// SPECIAL CASES PROMPT
// Alter the message based on task from user for prompt
if (CM_result === "CM_SpellingGrammar") {
  text = "Revise the following for grammar and spelling:nn[" + text + "]nn If the provided text cannot be revised for spelling or grammar return 'NoneNullNoneNullNone'";
}  else if (CM_result === "CM_Task") {
    text = text;
} else if (CM_result === "CM_Answer") {
  text = "If the following is a question, answer it. Else return 'NoneNullNoneNullNone': [" + text + "]";
} else if (CM_result === "CM_WordCount") {
    var wordcountInput = prompt("Please provide a description of the word count adjustment you would like made:nnHint: It often helps to provide an upper and lower limit.");
    if (wordcountInput) {
      text = "Adjust the word count of the following based on 'Word count adjustment':nn[" + text + "]nnWord count adjustment: [" + wordcountInput + "]nn If you cannot complete this task return 'NoneNullNoneNullNone'";
    } else {
      return
    }
} else if (CM_result === "CM_Rewrite") {
  text = "Rewrite the following to convey the same meaning in different structure, words, and organization: [" + text + "]";
} else if (CM_result === "CM_Clarity") {
    text = "Revise the following for clarity:nn[" + text + "]";
} else if (CM_result === "CM_Scholar") {
  text = "Revise the following to meet the standards of an extremely scholarly written paragraph, up to the highest academic quality:nn[" + text + "]";
} else if (CM_result === "CM_Tone") {
  var toneInput = prompt("Please provide a tone description to complete the revisions:");
  if (toneInput) {
    text = "Adjust the tone of the following based on 'Desired tone':nn[" + text + "]nnDesired tone: [" + toneInput + "]nn If you cannot complete this task return 'NoneNullNoneNullNone'";
  } else {
    return
  }
} else if (CM_result === "CM_StructureOrganization") {
  text = "Revise the following for structure and organization:nn[" + text + "]";
}

// Define the prompt to send to the API
let userPrompt = {
  model: "gpt-3.5-turbo",
  messages: [{ role: "user", content: text }],
  temperature: 1,
};


document.body.style.cursor = "wait";

// Send a POST request to the endpoint with the prompt and headers
fetch(endpointUrl, {
  method: "POST",
  headers,
  body: JSON.stringify(userPrompt),
})
  .then((response) => response.json())
  .then((data) => {
    // Use original text element and fallback to current active text element
    const activeElement =
      originalActiveElement ||
      (document.activeElement.isContentEditable && document.activeElement);
    if (activeElement) {
      if (
        activeElement.nodeName.toUpperCase() === "TEXTAREA" ||
        activeElement.nodeName.toUpperCase() === "INPUT"
      ) {
        responseMessage = data.choices[0].message.content;
        console.log(responseMessage);


        // SPECIAL CASES RESPONSE
        // Dont add a period if the original prompt didn't end in one
        if ((
            CM_result === "CM_SpellingGrammar" || 
            CM_result === "CM_Rewrite") && 
            textOriginal.charAt(textOriginal.length - 1) !== "." && 
            responseMessage.charAt(responseMessage.length - 1) === "."
          ) {
          responseMessage = responseMessage.slice(0, -1);
        } 
        // Check for quotation marks and remove them
        if (
            responseMessage.charAt(0) === '"' &&
            responseMessage.charAt(responseMessage.length - 1) === '"'
          ) {
          responseMessage = responseMessage.slice(1, -1);
        }
        // Alert if CM_Answer prompt was not a question
        if (CM_result === "CM_Answer" && responseMessage.includes('NoneNullNoneNullNone')) {
          alert(
            "It appears the prompt provided was not a question. Try submitting a question."
          );
          document.body.style.cursor = "default";
          return;
        } 
        // Alert if CM_Tone prompt was not a valid tone
        if (CM_result === "CM_Tone" && responseMessage.includes('NoneNullNoneNullNone')) {
          alert(
            `It appears the provided tone could not be applied to the text or the prompt provided was not a valid tone. Try submitting a valid tone including but not limited to:nn${toneExamples}`
          );
          document.body.style.cursor = "default";
          return;
        } 
        // Alert if CM_WordCount prompt was not a valid tone
        if (CM_result === "CM_WordCount" && responseMessage.includes('NoneNullNoneNullNone')) {
          alert(
            "It appears the provided word count adjustment was invalid. Try submitting a valid word count adjustment description."
          );
          document.body.style.cursor = "default";
          return;
        } 
        // Alert if CM_GrammarSpelling prompt was not able to be corrected
        if (CM_result === "CM_SpellingGrammar" && responseMessage.includes('NoneNullNoneNullNone')) {
          alert(
            "It appears the prompt you provided was not able to be corrected for grammar or spelling. Please try a different prompt"
          );
          document.body.style.cursor = "default";
          return;
        } 
        // Insert Response
        if (CM_result === "CM_Answer") {
          activeElement.value = activeElement.value + "n" + responseMessage;
        } else {
          activeElement.value = responseMessage;
        }



      }
    } else {
      // Alert reply since no active text area
      alert(`ChatGPT says: ${data.reply}`);
    }

    document.body.style.cursor = "default";
  })
  .catch((error) => {
    console.error(error);
    document.body.style.cursor = "default";
  });
}

How do I iterate over such object properties of an object in TypeScript?

I want to iterate over the oCities object and access the properties using a for…in loop as you can see in the attached screen recording but it looks like this for…in statement expected a string property for the iteration to occur, not an object. Any ideas on how I can pull this off?

type City = {
  iPopulation: number;
  sPopulation: string;
  latitude: number;
  longitude: number;
  color?: string;
  name: string;
  x: string;
  y: string;
};
interface Cities {
  [key: string]: City;
}
let oCities: Cities = {
  'Sao Paulo': {
    iPopulation: 11895893,
    sPopulation: '11,895,893',
    latitude: -23.5505,
    longitude: -46.6333,
    name: 'São Paulo',
    x: '0px',
    y: '0px',
  },
  'Rio de Janeiro': {
    iPopulation: 6453682,
    sPopulation: '6,453,682',
    latitude: -22.9068,
    longitude: -43.1729,
    name: 'Rio de Janeiro',
    x: '0px',
    y: '0px',
  },
  Salvador: {
    iPopulation: 2902927,
    sPopulation: '2,902,927',
    latitude: -12.9722,
    longitude: -38.5014,
    name: 'Salvador',
    x: '0px',
    y: '0px',
  },
  Brasilia: {
    iPopulation: 2852372,
    sPopulation: '2,852,372',
    latitude: -15.7942,
    longitude: -47.8822,
    name: 'Brasília',
    x: '0px',
    y: '0px',
  },
}

I’m trying to do something like:

  for(let city in oCities) {
    // save xy position
    oCities[city].x = oCities[city].longitude + 'lon';
    oCities[city].y = oCities[city].latitude + 'lat';
  }

But it’s not working. I really need some ideas.
enter image description here

Count numbers of Objects and Array contained into a main Object

I have an Object that contains various values, Objects, and Arrays, as shown in the snippet.

I am looking for a function that can count the total number of Objects and Arrays within this Object.

Currently, I am able to iterate through this main Object and log the Objects and Arrays with appropriate indentation. So, I can visualize the structure of this main Object later on; you don’t need to worry about that.

What I really want to understand is how my function works, specifically one particular line of code that I wrote. This line was suggested to me as a trick instead of simply calling the function again.

I will provide you with the Object and function in the snippet below, and I will indicate the part that I don’t fully comprehend afterwards.

        let datas = {
            name:"Main datas list",
            content:"List of Students and teachers",
            students:[
                {
                    name:"John",
                    age:23,
                    courses:["Mathematics","Computer sciences","Statistics"]
                },
                {
                    name:"William",
                    age:22,
                    courses:["Mathematics","Computer sciences","Statistics","Algorithms"]
                }
            ],
            teachers:[
                {
                    name:"Terry",
                    courses:["Mathematics","Physics"],
                }
            ]
        }

        function countAndDisplay(obj, indent = "") {
            let count = 0;

            for (let key in obj) {
                if (typeof obj[key] !== "object") {
                    console.log(`${indent}${key} : ${obj[key]}`);
                }

                if (typeof obj[key] === "object") {
                    if (Array.isArray(obj[key])) {
                        console.log(`${indent}Array : ${key} contains ${obj[key].length} element(s)`);
                    } else if (!Array.isArray(obj[key])) {
                        console.log(`${indent}Object : ${key} contains ${Object.keys(obj[key]).length} element(s)`);
                    }

                    count++; // Increment the count for each object or array encountered
                    
                    // Recursively count and display sub-elements

                    count += countAndDisplay(obj[key], indent + "  ");
                    
                    console.log(`${indent}=> DEBUG TEST COUNT VALUE = ${count}`); // just to understand how the itertion counts the elements
                }
            }

            return count;
        }

        let totalCount = countAndDisplay(datas);
        console.log(`datas contains ${totalCount} Objects or Arrays`);

Could you please explain the purpose and behavior of the code snippet here?

count++;
This line increments the value of the variable ‘count’ by 1 each time it is executed. I understand this part.

The next line is unclear to me.
count += the same function();
Specifically, I’m having trouble understanding how ‘count += the same function()’ can assign a value to the count variable immediately after it was incremented.

I don’t understand why the count variable is incremented (as if assigning a value to it), and then on the next line, count += is used with the recursive function (which seems to assign another value to the variable after the increment).

When I call the function, I know that it will execute all of its code again, including the line where I increment the count variable. However, the syntax is not easy to comprehend because if I simply call the function like countAndDisplay(obj[key], indent + " "); in place of count += countAndDisplay(obj[key], indent + " ");, it doesn’t work at all and doesn’t produce the expected result.

Could someone help me understand the logic behind this, so that I can improve my understanding and apply it in similar situations in the future? This isn’t an urgent matter, but rather an opportunity for me to enhance what I have already learned.

Thank you in advance for any time and effort you dedicate to answering this question.

How to use async properly to get chrome.storage?

I am creating a google chrome extension. On the popup, I am displaying a leaderboard. However, I am new to JavaScript so I don’t know how to properly use async. I am using chrome.storage to get stored scores to display on the leaderboard, then sending them from background.js to score.js. My issue is that, since chrome.storage.get happens asynchronously, my findScores method does not wait for chrome.storage.get to finish before incorrectly returning a default empty score.

Here is my code:

background.js

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
      console.log(sender.tab ?
                  "from a content script:" + sender.tab.url :
                  "from the extension");
      if (request.type === "request") {
        var scoresVar = findScores(request.table, "All");
        console.log("Sending response " + scoresVar);
        sendResponse({scores: scoresVar})
      } 
      else if (request.type === "score") {
        saveScore(request.website, request.score, request.tab);
        sendResponse("Finished adding score " + request.score);
      }
    }
);

function findScores(table, website) {
    const categories = table.split("-");
    if (categories.includes("personal")) {
        chrome.storage.sync.get([website], function(response) {
            if (!(typeof response[website] === 'undefined')) {
                console.log("Found " + response[website]);
                return response[website];
            }
        });
    } else if (categories.includes("global")){
        // TODO: Add global leaderboards
        return ["-"];
    }
    console.log("Didn't find, on default");
    return ["-"];
}

popup.js

async function requestScores(tableID) {
  var url = "All"
  if (tableID.includes("current")) {
    var url = await getCurrentTab();
  }
  console.log("Sending message to load scores to " + url);
  (async () => {
    const response = await chrome.runtime.sendMessage({type: "request", request: "load scores", table: tableID, tab: url});
    console.log("Received: " + response);
    // add scores to HTML DOM
    });
  })();
}

My console messages reveal that I first return a default score, which is sent to popup.js. I have tried throwing async keywords in front of functions (as well as “await” in front of variables like scoresVar = await findScores(request.table, “All”) but it just caused more issues, where findScores still returned a default value, but background.j instead sent an undefined promise.

How can I fix my code?

How to Get an Integer from HTML in JavaScript [closed]

I’m trying to use JavaScript to get a number from my html using document.getElementById().value but I’m getting the whole thing (i.e 52 instead of just 52. Any tips on how to get this would be greatly appreciated

The only variations I know to try are adding .value at the end of the getElementById() or leaving it off

I just need to know how I can get the integer value of the element in the html instead of the whole tag.