While making an API call gives ‘options.uri is a required argument’

I am using node 12 and npm request module version 2.88.0. While making a request to an API call , it is giving me error as options.uri is a required parameter. Also i had tried to change the url to uri but still getting same.
apiURL is defined as in

{
  "Config": {
    "dev": {
      "apiURL": "https://apiURL.com"
      
  }
}
}

and config where its fetched on the basis of what enviornment is it running

const config = require('./default');

var dev = config.Config.dev;
var prod = config.Config.prod;

module.exports.configure = function () {
    var environment = 'dev'; //process.env.NODE_ENV;
    var config = {};
    switch (environment) {
        case 'prod':
                config = {
                    apiURL: prod.apiURL,
                   //etc
                }
                return config;
                
            case 'dev':
                config = {
                    
                    apiURL: dev.apiURL,
                    //etc
                }
                return config;
            
        default:
            var error =
                'No Environment Configured.';
            throw error;
    }
};

Here is the actual code part while making the api call

async function callAPI(id, pass) {
  request(
    {
      url: apiURL,
      method: 'POST',
      body: {
        id,
        pass,
      },
      json: true,
    },
    async function (error, response, body) {
      if (response && response.statusCode == 200) {
        logger.log(
          INFO,
          JSON.stringify({
            Module: 'API ',
            Response: `${JSON.stringify(body)}`,
          }),
        );
        return Promise.resolve(response);
      } else {
        return Promise.reject(response);
      }
    },
  );
}

Is it possible to store Google Maps object as an attribute in a Vue component?

My google maps is being initialized in mounted() and stored in map attribute:

mounted() {
  this.initMap();
},
methods: {
  async initMap() {
    const loader = new Loader({
      apiKey: settings.googlemaps,
      version: 'weekly',
    });

    try {
      await loader.load();
      const {Map} = await google.maps.importLibrary('maps');

      this.map = new Map(this.$refs.map, {
        center: {lat: 37.75768866503074, lng: -96.54510528125},
        zoom: 4,
        minZoom: 3,
        streetViewControl: false,
        mapTypeControl: false,
        mapId: settings.mapid,
      });
    } catch (error) {
      console.error('Error loading Google Maps API', error);
    }
  },
}

The markers content comes from an external API and is passed from the parent component:

watch: {
  places: {
    deep: true,
    handler() {
      this.initMarkers();
    },
  },
},

The problem is the markers is not being added to the map (I’m not applying the places loop yet):

async initMarkers() {
  try {
    const {AdvancedMarkerElement} =
      await google.maps.importLibrary('marker');

    new AdvancedMarkerElement({
      map: this.map,
      title: 'Marker title',
      position: {
        lat: 38.992534,
        lng: -122.745783,
      },
    });
  } catch (error) {
    console.error('Error loading marker library', error);
  }
},

Looks like AdvancedMarkerElement cannot read/access this.map correctly.

How to grab all checkboxes in GMail?

I am trying to just report back all checkboxes in Gmail for a small background script. Eventually i want to return only those that are checked. The checkboxes that are beside each email, used to select them and operate them, are indicated by role=”checkbox”.

With current code, i only get an empty list, and i can’t figure out why. Here is my code:

background.js

console.log("Start");
browser.contextMenus.create(
    {
        id: "AlertTest",
        title: "Test2",
        contexts: ["all"],
    },
    () => void browser.runtime.lastError,
);

browser.contextMenus.onClicked.addListener((info, tab) => {
    switch (info.menuItemId) {
    case "AlertTest":
        //console.log(info.selectionText);
        var ele = document.querySelectorAll("[role=checkbox]");
        console.log(ele);
        break;
    }
});

function onError(error) {
    console.log(error);
}

ref.current is null inside useEffect

I have a list of refs that is being forwarded to the child components. They seem to work fine as I can do operations with them as feedback to the user actions (in this case, it is scrolling into view). However, I want to scroll to them when component is rendered/mounted, which sounds like a classic ref usage: add ref dependencies to a useEffect and scroll when they are ready. But it basically does not work. When I console.log out the refs, I see the ref.current is assigned. However when I console.log refs[scrollTo], it is undefined. This might be related to how chrome browser consoles work though.

So here is my example code:

const MyComponent = (props) => {
  const refs = {
    a: useRef<HTMLDivElement>(null),
    b: useRef<HTMLDivElement>(null),
    c: useRef<HTMLDivElement>(null),
  }
  
  useEffect(() => {
    if (props.scrollTo && refs[props.scrollTo].current) {
      refs[props.scrollTo].current.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
  }, [refs.a.current, refs.b.current, refs.c.current]);

  return <>
    <ChildComponent key='a' ref={refs.a} onClick={
      refs.a.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
    } />
    <ChildComponent key='b' ref={refs.b} onClick={
      refs.b.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
    } />
    <ChildComponent key='c' ref={refs.c} onClick={
      refs.c.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
    } />
  </>
};

refs[props.scrollTo].current always returns null here in the use effect, preventing me to scroll there on load. useCallback solution also does not apply here for me as well, since I need those DOM refs for scrollintoview behaviour on onclicks. What am I missing here?

In a Vue “Composition” + Pinia “Setup Function” SPA, how can I mock a global referenced in a store, such as `gapi`?

I have a Vue SPA using Pinia as a store. The application also creates a global namespace gapi via a google API script tag: https://developers.google.com/drive/api/quickstart/js

Thus in my store, I’ll have code such as

  function gapiLoaded() {
    gapi.load('client', initializeGapiClient);
  }

In my test functions, I’ll have components that leverage the store, via the useStore paradigm. Thus my store code is run, and I get errors such as gapi is not defined when I run my test suite.

Here’s an example test file:

import { describe, it, expect } from 'vitest';
import { mount } from '@vue/test-utils';
import Files from '../Files.vue';
import type { ReadFile } from '../Files.vue';
import { createTestingPinia } from '@pinia/testing';
// import any store you want to interact with in tests
import { useDriveStore } from '@/stores/drive';
import { fn } from '@vitest/spy';

describe('Files Component', () => {

  it('renders properly', () => {
    const wrapper = mount(Files, {
      global: {
        plugins: [
          createTestingPinia({
            createSpy: fn,
            initialState: {
              drive: {
                files: [
                  {
                    name: 'test file 1',
                    id: '1'
                  },
                  {
                    name: 'test file 2',
                    id: '2'
                  }
                ]
              }
            }
          })
        ],
        mocks: {
          gapi: {
            load: function() {},
            client: {
              init: function() {},
            }
          }
        }
      }
    });
    const store = useDriveStore(); // uses the testing pinia!
    const filesList = '[data-testid=files-list]';
    expect(store.fetchFiles).toHaveBeenCalledTimes(1);
    expect(wrapper.find(filesList).text()).toContain('test file 1');
    expect(wrapper.findAll('[data-testid=files-item]')).toHaveLength(2);
  });
});

As you can see, I’ve attempted to mock the gapi per the vue-test-util docs, however, perhaps vue-test-util docs are referring to globals referenced by components, and isn’t equipped to handle globals referenced by a store file.

I tried to see if createTestingPinia allowed some sort of global mock option, but the docs don’t mention it: https://pinia.vuejs.org/cookbook/testing.html and I failed to find comprehensive documentation on the function.

How can I, in a @pinia/testing + vue-test-utils test file, mock globals referenced within a pinia store file?

The entire codebase is FOSS if it helps to have more context: https://codeberg.org/calebrogers/vue-google-drive

how to make logger for cookies to notify when a cookie gets updated or deleted/created

I need some logger that can log timestamp and cookie activity (when a cookie gets updated or deleted/created) when I surf over the webpage.
There is a browser.cookies.onChanged in https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/onChanged but its only for extensions, browser object itself is not available in chrome console. Is there any way to run the js code in the console to do this or are there any other ways? Maybe there is a extension for this already?

HTML can i assign the value of span id in a hidden input [duplicate]

<div id="form_container">
<h1 align="justify"><font color="#4074BF">Reviews and Questions</font></h1>

<form action="send_email.php" method="post">
  <p><font color="#4074BF">Question or Review<br />
  <textarea cols="50" id="message" name="message" rows="5" required>Ask a Question or Submit a Review. </textarea></font></p>

  <div class="inline_style">
    <p><font color="#4074BF">Please type this number in the space below </font><span id="_challenge"></span></p>
    <p><font color="#4074BF"><input id="testphrase" name="testphrase" size="10" type="text"/></font></p>
    <input type="hidden" id="challenge" name="challenge" value="<?=$_challenge?>" type="text" />
    <br />
  </div>

  <p><font color="#4074BF">
    <input id="submit" type="submit" value="Send" />
    <input id="reset" name="reset" type="reset" value="Clear" />
    </font>
  </p>
  <br />
  
</form>
</div>
<?php
// send_email.php
$errors = [];

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Get POST data
    $challenge = isset($_POST['challenge']) ? strip_tags(trim($_POST['challenge'])) : '';
    $testphrase = isset($_POST['testphrase']) ? strip_tags(trim($_POST['testphrase'])) : '';
    $message = isset($_POST['message']) ? strip_tags(trim($_POST['message'])) : '';

    // Validate form fields
     
   if ($challenge != $testphrase) {
        echo "testphrase = $testphrase<br>";
        echo "challenge = $challenge<br>"; 
        exit();
   }
   
    if (empty($email)) {
        $errors[] = 'Email is empty';
    } else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors[] = 'Email is invalid';
    }

    // If no errors, send email
    if (empty($errors)) {
        $recipient = "[email protected]";
        $subject = "Website Question / Review";
        $message = "From: $name <$email> rn$message";
        $message = wordwrap($message,70);

        // Send email
        if (mail($recipient, $subject, $message, $headers)) {
           // Destroy data _POST
            foreach ($_POST as $key => $value) {
                unset($_POST[$key]);
            }
           // redirect user and terminate the script
            header("Location: thank_you.html");
            exit();
        } else {
            echo "Failed to send email. Please try again later.";
        }
    } else {
        // Display errors
        echo "The form contains the following errors:<br>";
        foreach ($errors as $error) {
            echo "- $error<br>";
            echo "$snotmail<br>";
            echo "$heard<br>";
        }
    }
} else {
    // Not a POST request, display a 403 forbidden error
    header("HTTP/1.1 403 Forbidden");
    echo "You are not allowed to access this page.";
}
?>
window.onload = function() {
    var d = new Date();
    var seconds = d.getSeconds();
    var thisday = d.getDay();
    var rnumber = thisday + "" + seconds;
    document.getElementById("_challenge").textContent = rnumber;
}
;

I have posted the form, php and javascript that I am using above. I am successfully assigning a value to the span id “_challenge” in javascript. Span displays the value as expected. I am then trying to pass that value to php using

<input type="hidden" id="challenge" name="challenge" value="<?=$_challenge?>" type="text" />

but it keeps showing as empty when I use echo in php. If I assign a constant value for example value=”240″ that is passed properly the echo statement displays it.

Is there something wrong with the syntax of my variable assignment to the value attribute or is there another method to pass this value which is assigned in the script to _challenge?

Thanks.

I have tried many different methods that are described in SO but all have yielded the same empty value.

Can’t run javascript in jupyter notebook or jupyterlab

I am working in jupyter lab env using ipwidgets python library. I am making a dashboard environment using jupyter lab. The problem I am facing is that form some reason javascript is not working at all. I thought it would have been a problem with the environment I am using so I installed a fresh environment in a sandbox but it still does not work.
This is the example code that I am trying to run

from IPython.display import Javascript, display
import ipywidgets as widgets

# Define a function to display a JavaScript alert
def show_alert():
    display(Javascript('alert("Hello from JavaScript!")'))

# Create a button widget
button = widgets.Button(description="Click me!")

# Set the button's action
button.on_click(lambda b: show_alert())

# Display the button
display(button)

For testing I run this code in google colab and It is working fine there.
When I run the code and clicke the ‘click me’ button I get the following output in the jupyter console

how can i implement tag all? | telegram bot

i can’t tag other chat users(except administrators)
and i just couldn’t do it.
i decided to leave a function for tag admins.

    for (let i = 0; i < userCount; i++) {
      const member = await ctx.telegram.getChatMember(chatId, i + 1); 
      const user = member.user;

i’ve tried doing exact same method for a tag users
but im have error

Error in receiving users: TelegramError: 400: Bad Request: PARTICIPANT_ID_INVALID
and next

response: {
    ok: false,
    error_code: 400,
    description: 'Bad Request: PARTICIPANT_ID_INVALID'
  },
  on: {
    method: 'getChatMember',
    payload: { chat_id: -1234567890, user_id: 1 }
  }
}

and my full code

import dotenv from 'dotenv';
dotenv.config();

const botToken = process.env.TELEGRAM_BOT_TOKEN;

import { Telegraf } from 'telegraf';
const bot = new Telegraf(botToken);

bot.command('all', async (ctx) => {
  try {
    const chatId = ctx.chat.id;

    const userCount = await ctx.telegram.getChatMembersCount(chatId);
    console.log(`users count: ${userCount}`);

    let message = '';
    const tagLimit = 5;
    let chunk = [];

    const admins = await ctx.telegram.getChatAdministrators(chatId);

    for (let i = 0; i < admins.length; i++) {
      const user = admins[i].user;

      if (user.username) {
        chunk.push(`@${user.username}`);
      } else {
        chunk.push(`@${user.id}`);
      }

      if (chunk.length === tagLimit) {
        message += chunk.join('n') + 'n';
        chunk = [];
      }
    }

    if (chunk.length > 0) {
      message += chunk.join('n');
    }

    console.log('tags users:n' + message.trim());
    await ctx.reply(message.trim() || 'users not have @usernames');

  } catch (error) {
    console.error('an error when receiving users:', error);
    ctx.reply('an error when receiving users_list');
  }
});

bot.launch();
console.log('bot is started');

Unexpected TypeScript behavior with oxide.ts

To fully reproduce the issue, you could set up tiny Node.js project using the following code:

package.json:

{
  "scripts": {
    "start": "tsc && node app.js"
  },
  "devDependencies": {
    "@types/node": "22.5.4",
    "typescript": "5.5.4"
  },
  "dependencies": {
    "oxide.ts": "1.1.0"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "commonjs",
    "sourceMap": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "esModuleInterop": true,
  }
}

app.ts:

import { None, Option } from 'oxide.ts'

export enum Currency {
  EUR = 'EUR',
  UAH = 'UAH',
  USD = 'USD',
}

export interface GenericClientInterface {
  execute(address: string): Promise<void>
}

export interface SpecificClientInterface extends GenericClientInterface {
  lookup(account: string): Promise<boolean>
}

export type CurrencyClientMap = {
  [Currency.EUR]: Option<GenericClientInterface>
  [Currency.UAH]: Option<SpecificClientInterface>
  [Currency.USD]: typeof None
}

export interface CurrencyFactoryInterface {
  build<C extends Currency>(currency: C): CurrencyClientMap[C]
}

export class MyClass{
  public constructor(
    private readonly currencyClientFactory: CurrencyFactoryInterface,
  ) {}

  public execute(currency: Currency): void {
    const clientResult = this.currencyClientFactory.build(currency)

    if (clientResult.isNone()) { // <-- TypeScript error here.
      console.log('clientResult is None')
    }

    const client = clientResult.unwrap()

    console.log('Client: ', client)
  }
}

If you set up a project the way described above, you’ll notice that in line 35 of app.ts, there is a TypeScript error:

The 'this' context of type 'Option<GenericClientInterface> | Option<SpecificClientInterface> | Readonly<OptionType<never>>' is not assignable to method's 'this' of type 'Option<GenericClientInterface> & Option<SpecificClientInterface> & Option<never>'.
  Type 'Option<GenericClientInterface>' is not assignable to type 'Option<GenericClientInterface> & Option<SpecificClientInterface> & Option<never>'.ts(2684)

Why is it happening? All three returned types have .isNone() method. Why A | B | C is expected to be A & B & C in the value returned by .build() method? Is it a TypeScript or Oxide.ts issue?

i can’t add any new leaflet plugins to my folium map

can anyone show me how to add this plugin correctly:

def initialize_map(self):
    # Create a base map
    m = folium.Map(location=[30.0444, 31.2357], zoom_start=8)
    folium.TileLayer(
        tiles='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
        attr='Esri',
        name='Esri Satellite',
        overlay=False,
        control=True
    ).add_to(m)

    # Add Leaflet-Ruler plugin
    folium.JavascriptLink("https://cdn.jsdelivr.net/gh/gokertanrisever/leaflet-ruler@master/src/leaflet-ruler.js",).add_to(m)
    folium.CssLink("https://cdn.jsdelivr.net/gh/gokertanrisever/leaflet-ruler@master/src/leaflet-ruler.css").add_to(m)
    # Initialize the ruler
    ruler_init = """
    function addRuler(map) {
        L.control.ruler().addTo(map);
    }
    """
    m.get_root().html.add_child(folium.Element("<script>"+ruler_init+"</script>"))

i tried to add ruler plugin but it doesn’t appear

Opening another URL in previously opened tab

I am opening multiple URLs in same tab which works well once but as soon as I refresh the source page from where the new tab was opened it opens new tab, any workaround for this?

window.currentChild = false;

function openInTab($elm) {
    if (currentChild) currentChild.close();
    const child = window.open($elm.attr("href")+new Date(), "myWindowName", '');
    currentChild = child;

    //Scrope script in child windows
    child.frames.eval(`
    setInterval(function () {
        if (!window.opener.currentChild)
          window.opener.currentChild = window;
    }, 500);
  `);
  return false;
}

Scenario1:

  1. click on Open In Tab link, it will open a new tab
  2. again click on Open In Tab link, it will close the previously opened tab and open a new tab

Scenario2:

  1. click on Open In Tab link, it will open a new tab
  2. again click on Open In Tab link, it will close the previously opened tab and open a new tab
  3. refresh the source jsfiddle page
  4. click on Open In Tab link, it will open a new tab (Expected closing previously opened tab)

Fiddle here: https://jsfiddle.net/nitinjs/a1zd2kuh/11/