โŒ

Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

nodejs array doesn't remove item and googleapis throws error Invalid values[2][0]: list_value

I have the below code for a DELETE route on my app's server. I'm facing two majors problems from this :

1. Unable to remove item from array

This section of the code is supposed to remove friend from friendsArray. But it doesn't work as intended. The output of console.log("Modified Friends Array",friendsArray) is:

Modified Friends Array [
  'friend1',
  'friend2',
  'friend3'
]

The value for friend was given as friend2 in the query parameters. Which still exists even after the given instructions:

// removing friend from array
const friendsArray = await fetchFriends(email);
console.log("Friends array: "+friendsArray)   
console.log("Friends array type: "+ typeof friendsArray)       
console.log("Friend to be removed: "+friend)
delete friendsArray[friend]
JSON.stringify(friendsArray)
console.log("Modified Friends Array",friendsArray)

Note: the output of console.log("Friends array type: "+ typeof friendsArray) is Friends array type: object

2. googleapis error while updating values

I receive this error from googleapis:

 error: undefined,
  status: 400,
  code: 400,
  errors: [
    {
      message: 'Invalid values[2][0]: list_value {\n' +
        '  values {\n' +
        '    string_value: "friend1"\n' +
        '  }\n' +
        '  values {\n' +
        '    string_value: "friend2"\n' +
        '  }\n' +
        '  values {\n' +
        '    string_value: "friend3"\n' +
        '  }\n' +
        '}\n',
      domain: 'global',
      reason: 'badRequest'
    }
  ]
}

I tried setting the updating values from values: [[friendsArray]] to values: [friendsArray] and even values: [[[friendsArray]]] but that didn't work either...

Here is my entire file:

require("dotenv").config()

const axios = require('axios')

const { google } = require("googleapis")
const sheets = google.sheets({ version: 'v4' })
const creds = './credentials.json'

module.exports = {
    route: "users/profile/friends",
    method: "DELETE",
    run: async (req, res) => {

        async function fetchFriends(email) {
            try {
                const response = await axios.get(require('../api')('Profiles'))
                const [headerRow, ...rows] = response.data.values;

                const Data = rows.map(row => {
                    const obj = {};
                    headerRow.forEach((key, index) => {
                        obj[key] = row[index];
                    });
                    return obj;
                });
                const result = Data.filter(user => user.email === email)
                return JSON.parse(result[0].friends)
            } catch (e) {
                console.log(e)
                throw e
            }
        }

        const { email, friend } = req.query

        try {
            // removing friend from array
            const friendsArray = await fetchFriends(email);
            console.log("Friends array: "+friendsArray)   
            console.log("Friends array type: "+ typeof friendsArray)       
            console.log("Friend to be removed: "+friend)
            delete friendsArray[friend]
            JSON.stringify(friendsArray)
            console.log("Modified Friends Array",friendsArray)

            const auth = await google.auth.getClient({
                keyFile: creds,
                scopes: ['https://www.googleapis.com/auth/spreadsheets']
            })
            const spreadsheetId = process.env.DATABASE_ID

            const rowReq = {
                spreadsheetId,
                range: 'Profiles!A:D',
                auth
            }
            const rowRes = await sheets.spreadsheets.values.get(rowReq)
            const rows = rowRes.data.values
            const rowIndex = rows.findIndex(row => row[0] === email)

            const Index = rows[0].indexOf("friends")
            const Column = String.fromCharCode(Index + 65)
            const Range = `Profiles!${Column}${rowIndex + 1}`

            const frndsUpdateRequest = {
                auth,
                spreadsheetId,
                range: Range,
                valueInputOption: 'RAW',
                resource: {
                    values: [[friendsArray]],
                },
            }

            const response = await sheets.spreadsheets.values.update(frndsUpdateRequest)

            res.status(200).send(response)
        } catch (e) {
            console.log("Error removing friend: ", e)
            res.status(500).send("Error removing friend: " + e.message);
        }
    }
}

How to detect if any modal <dialog> is open?

I have a page with multiple <dialog> elements, which I open as modal using their showModal() methods.

I want to detect whether any of them is currently opened from Javascript (since some event handlers shouldn't trigger when a modal is opened). Is it possible to check if modal is currently opened? Maybe through existance of dialog::backdrop or checking someway for inertness of non-modal content?

How to use .js and .d.ts files in project

having this some.js file

export function myFunc(a, b) {
  return a.asdf + b;
}

I want to be able to write something like this let's say in some.d.ts file

export declare function myFunc(a: number, b: number): number;

then run 'npx tsc' command which will give me 'asdf is not a member of type number', but right now i get errors saying "parameter a implicitly has any type". I have this tsconfig.json

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "skipLibCheck": false,
  },
  "include": ["**/*.js", "**/*.d.ts"]
}

Is it that I miss some ts options or I should declare types in .d.ts differently? If it is impossible, what is the general way to program in js but having typings and not in one global.d.ts file?

I also tried

declare namespace some {
  export function myFunc(a: number, b: number): number;
}

and

declare module "some" {
  export function myFunc(a: number, b: number): number;
}

I'm having trouble simulating a click in my script

I made this little piece of code to test out my question answerer. Here's the code:

function findAndClickWord(word) {
    var textNodes = document.evaluate("//text()", document.body, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0; i < textNodes.snapshotLength; i++) {
        var node = textNodes.snapshotItem(i);
        var searchText = node.textContent;
        var newText = searchText.replace(new RegExp(word, 'g'), '<span class="highlighted-word" style="background-color: yellow; cursor: pointer;">$&</span>');
        if (searchText !== newText) {
            node.parentNode.innerHTML = newText;
            var wordElements = document.querySelectorAll(".highlighted-word");
            if (wordElements.length > 0) {
                wordElements.forEach(function(element) {
                    element.scrollIntoView();
                    for (var j = 0; j < 100; j++) {
                        element.click();
                    }
                });
            }
            break;
        }
    }
}

// Call the function with the word "yes"
findAndClickWord("yes");

Thanks in advance for help! P.S: I have seen other guides and help topics, but they didn't work for me.

I tried to rewrite the code many times, but it didn't work. I expected to see the word ("yes") highlighted and clicked.

why new Promises get's used next to await while there is no need to them?

I had code below from javascript.info async/await tutorial and I noticed it has used new Promise next to await, this is the cut from the code:

await new Promise((resolve, reject) => setTimeout(resolve, 3000));
img.remove();

link to code

so it's possible to type this code as below:

 await setTimeout(()=>{img.remove()}, 3000));

so I'm wondering what's the necessity to use new Promise next to await keyword(while we eliminate .then() and .catch() with await and try...catch but I've seen new Promises get used alongside the await)?

p.n: I thought maybe it gets used when we have conditions for rejection and success inside new Promise but in this example we have no condition and still it's used.

How to auto increment name value in a HTML dinamic "+" form input

I have this HTML form and JavaScript to add a dinamic form input when I click the + button, how can I give an individual name to each input field? name="name1" name="email1", name="name2" name="email2", name="name3" name="email3" and so on...

<div class="row justify-content-center">
        <div class="col-xl-8">
          <div class="contact-form__inner">
            <form action="form/register.php" method="post">
              <div class="input-group">
                <div class="input-single">
                  <label for="contactFirstName">Team Name</label>
                  <input type="text" name="contact-name" id="contactFirstName" required
                    placeholder="Enter your team name">
                </div>
                <div class="input-single">
                  <label for="contactEmail">Email</label>
                  <input type="email" name="contact-email" id="contactEmail" required placeholder="Enter your email">
                </div>
              </div>
              <div class="input-group">
                <div class="input-single">
                  <label for="contactEmail">Player Name</label>
                  
                </div>
                <div class="input-single">
                  <label for="contactPhone">Player Email</label>
                  
                </div>
              </div>
              <div class="input-group m-3">                            
                            <input type="text" name="name1" class="form-control m-input" placeholder="Player name">
                            <input type="text" name="email1" class="form-control m-input" placeholder="Player email">
                            <div class="input-group-prepend">
                                <button class="btn btn-danger"
                                        id="DeleteRow"
                                        type="button">
                                    <i class="bi bi-trash"></i>
                                    Delete
                                </button>
                            </div>
                        </div>
              <div id="newinput"></div>
                    <button id="rowAdder" type="button" class="btn btn-dark">
                        <span class="bi bi-plus-square-dotted">
                        </span> ADD
              </button>              
              <div class="section__cta">
                <input type="text" class="d-none" name="form-anti-honeypot" value="">
                <button type="submit" class="cmn-button">Send Message</button>
              </div>
            </form>            
    </div>
    <script type="text/javascript">
        $("#rowAdder").click(function () {
            newRowAdd =
                '<div id="row"> <div class="input-group m-3">' +
                '<input type="text"  name="name2" class="form-control m-input" placeholder="Player name"><input type="text"  name="email2" class="form-control m-input" placeholder="Player email">' +
                '<div class="input-group-prepend">' +
                '<button class="btn btn-danger" id="DeleteRow" type="button">' +
                '<i class="bi bi-trash"></i> Delete</button> </div></div> </div>' ;
                
 
            $('#newinput').append(newRowAdd);
        });
        $("body").on("click", "#DeleteRow", function () {
            $(this).parents("#row").remove();
        })
    </script>
          </div>
        </div>

I have tried an auto increment funtion but I cannot make it work

whilst trying to make a language select for a web im making i get an error that reads [Cannot read properties of null (reading 'addEventListener')]

javascript code (the error code is placed at addEventListener)

const translations = {
    en: {
        text1: "testing"
    },
    no: {
        text1: "testing"
    },
    gm: {
        text1: "testen"
    }
}


const languageSelectop = document.querySelector("LS");

problem being around here

languageSelectop.addEventListener("change", (event) => {
    setLanguage(event.target.value)
})
const setLanguage = (language) => {
    if(language == "no"){
        console.log(language);
    }else if(language == "en"){
        console.log(language)
    }else if(language == "gm"){
        console.log(language)
    }
}

html code (no aperent isues as far as i know)

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Arctic Fox Web - WIP</title>
        <script type="text/javascript" src="js/Language.js"></script>
        
    </head>
    <body>

        <div>
            <select name="" id="LS">
                <option value="en">English</option>
                <option value="no">Norsk</option>
                <option value="gm">Deutsch</option>
            </select>

        </div>

        <div>
            testing
        </div>
        <div>
            testing
        </div>
    
    </body>
</html>

im following a tutorial on yt thus i dont quite know whats wrong if it is needed here is the video Youtube

useObserver hook doesn't work after re-render components

I have simple React app, that using two types of pagination: general by pages pagination and like twitter infinity pagination. For infinity pagination I used "useObserver" hook, to find the div element in the end of the page and if I see that element I load the next part of data. For general pagination I used general useState and general gooks. It doesn't matter. I want to dynamically switch between those two type of pagination by button click. I have two buttons: one button for pagination and second one for infinity pagination. When I clicked for the first one I render pages, when I pressed for the second one I re-render end of the page and remove pages and and div for infinity loading. But after re-render infinity loading my "useObserver" hook doesn't work.

My "useObserver" hook:

import { useEffect, useRef } from "react";

export const useObserver = (ref, canLoad, isLoading, callBack) => {

const observer = useRef();

useEffect(() => {
    if (isLoading) return;
    if (ref.current === undefined || ref.current === null) return;
    if (observer === null) return;
    if (observer.current) observer.current.disconnect();

    var callBackObserver = (entries) => {
        if (entries[0].isIntersecting && canLoad) {
            callBack();
        }
    };

    observer.current = new IntersectionObserver(callBackObserver);
    observer.current.observe(ref.current);
}, [isLoading]);
};

My pagination switcher component:

import React from 'react';
import PostList from './PostList';
import Loader from './UI/loader/Loader';
import Pagination from './UI/pagination/Pagination';

export default function PaginationType({ isPagination, isPostLoading, removePost,
 sortedAndSearchedPosts, title, page,
 changePage, totalPages, lastElement }) {

 if (isPagination) {
    return (
        <div>
            {isPostLoading
                ? <div style={{ display: 'flex', justifyContent: 'center', marginTop: 50 }}><Loader /></div>
                : <PostList
                    remove={removePost}
                    posts={sortedAndSearchedPosts}
                    title={title}
                />
            }

            <Pagination page={page}
                changePage={changePage}
                totalPages={totalPages}
            />
        </div>
    );
}
else {
    return (
        <div>
            {isPostLoading &&
                <div style={{ display: 'flex', justifyContent: 'center', marginTop: 50 }}><Loader /></div>
            }

            <PostList
                remove={removePost}
                posts={sortedAndSearchedPosts}
                title={title}
            />
            <div ref={lastElement} style={{ height: 20, background: 'red' }} />
        </div>
    );
}
};

Code from component that calling pagination switcher:

function Posts() {

 const [isClassicPage, setClassicPage] = useState(true);
 const [page, setPage] = useState(1);
 const [posts, setPosts] = useState([]);
 const [totalPages, setTotalPages] = useState(0);

 const [fetchPosts, isPostLoading, postError] = useFetching(async (limit, page) => {
 const response = await PostService.getAll(limit, page);
 if (isClassicPage) {
   setPosts(response.data);
 }
 else {
   setPosts([...posts, ...response.data]);
 }
 const totalCount = response.headers['x-total-count'];
 setTotalPages(getPageCount(totalCount, limit));
 });

 const lastElement = useRef();  

 useObserver(lastElement, page < totalPages, isPostLoading, () => {
   setPage(page + 1);
 });

 return (
  <div className="App">

  <PaginationSwitcher setClassicPage={setClassicPage} />      

  {postError &&
    <h1>Load error, so sorry :C</h1>
  }

  <PaginationType
    isPagination={isClassicPage}
    isPostLoading={isPostLoading}
    removePost={removePost}
    sortedAndSearchedPosts={sortedAndSearchedPosts}
    title={"List of Posts 1"}
    page={page}
    changePage={changePage}
    totalPages={totalPages}
    lastElement={lastElement}
  />

</div>
);
}
export default Posts;

I expecting that after switching between two buttons and re-rendering components all will be work fine!

Component only has access to array's old state

I'm working with React and I have a table that users can add and delete rows from. The table is made with an array of components. Each component/row has a trash can icon that when clicked executes the delete row function. It would seem that each component only has access to the old state of the array/table, and so deleting doesn't work correctly. Any ideas how I could fix this issue?

An example of a component in the useState array that makes up this table:

<Row
  className={className}
  columns={columns}
  text={text}
  key={key}
  keyProp={key}
  deleteFunction={() => removeRow(key)}
/>

The delete function that is a prop for every row/component in the array:

function removeRow(key) {
  setMeals(meals.filter(i => i.props.keyProp !== key));
  // This should only remove the one row which had its trash can icon clicked.
  // If there's 10 rows and you click the trash can for row 4, rows 4-10
  // will be deleted.
  // If you click the trash can for row 7, rows 7-10 will be deleted and so on.
}

react-horizontal-scrolling-menu scrolling error

**Hello, I'm having a problem with react-horizontal-scrolling-menu , when scrolling, it scrolls to the right a lot, and the rest of the elements disappear, and when you add overflowX: 'scroll' to the BOX, the scroll doesn't work until after the first click

Plus LeftArrow, RightArrow don't work

Take a look at the code**

[error img here]
1

<Box component="div" sx={{position:'relative', width:'100%',p:'20px'}}>
        <HorizontalScrollbar data={bodyParts} bodyParts={bodyParts} bodyPart={bodyPart} setBodyPart={setBodyPart}/>
  </Box>

HorizontalScrollba

  import React, { useContext } from 'react';
import { ScrollMenu, VisibilityContext } from 'react-horizontal-scrolling-menu';
import { Box, Typography } from '@mui/material';
import BodyPart from './BodyPart';
import RightArrowIcon from '../assets/icons/right-arrow.png';
import LeftArrowIcon from '../assets/icons/left-arrow.png';

const LeftArrow = () => {
  const { scrollPrev } = useContext(VisibilityContext);

  return (
    <Typography onClick={() => scrollPrev()} className="right-arrow">
      <img src={LeftArrowIcon} alt="right-arrow" />
    </Typography>
  );
};

const RightArrow = () => {
  const { scrollNext } = useContext(VisibilityContext);

  return (
    <Typography onClick={() => scrollNext()} className="left-arrow" >
      <img src={RightArrowIcon} alt="right-arrow"/>
    </Typography>
  );
};

const HorizontalScrollbar = ({ data, bodyParts, setBodyPart, bodyPart }) => (
  <Box mt={4} sx={{position:'static'}}>
  <ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}>
    {data.map((item) => (
      <Box
        key={item.id || item}
        itemId={item.id || item}
        title={item.id || item}
        m="0 40px"
      >
         <BodyPart item={item} setBodyPart={setBodyPart} bodyPart={bodyPart} /> 
      </Box>
    ))}
  </ScrollMenu>
  </Box>
);

export default HorizontalScrollbar;

I'm trying to test a specific validation case with chai, mocha and sinon, but i get an error: TypeError: expect(...).to.be.true is not a function

Issue Testing Validation Scenario in Controller Layer

I'm encountering an error while testing a validation scenario in my controller layer. The scenario involves checking for the absence of a 'name' field in the request body. Here's the test code:

it('Testing a case of absent name on req body', async function () {
    const req = { body: {} };
    const res = {
      status: sinon.stub().returnsThis(),
      json: sinon.spy(),
    };

    await productsController.insertProduct(req, res);

    expect(res.status.calledWith(400)).to.be.true();
    expect(res.json.calledWith({ message: '"name" is required' })).to.be.true();
});

The controller logic being tested is as follows:

if (!name) {
    return res.status(400).json({ 
      message: '"name" is required', 
    });
}

However, upon running the test, I encounter the error:

TypeError: expect(...).to.be.true is not a function
at Context.<anonymous> (tests/unit/controllers/products.controller.test.js:41:50)

How can I resolve this error and ensure my test for the absence of the 'name' field functions correctly?


How to execute a script after the component load in Lit-Element

I'm trying to add a prefix to the phone number input after the component load, but I'm getting an error. In a normal web component, the connectedCallback() method would be enough but here it doesn't seem to work. How can I fix this?

The error I'm getting: Uncaught TypeError: Cannot read properties of null (reading 'getAttribute')

import { LitElement, html } from "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js";
import "https://unpkg.com/[email protected]/build/js/intlTelInput.min.js";
import { formattedArray } from "./countries.js";

export class Form extends LitElement {
  static properties = {
    name: {},
    modalContent: {},
  };

  constructor() {
    super();
    this.countries = formattedArray;
  }

  render() {
    return html`
      <form class="flex flex-col gap-3" @submit=${this.handleSubmit}>
        <input type="text" class="form-control" placeholder="First name" name="first_name" />
        <input type="text" class="form-control" placeholder="Last name" name="last_name" />
        <input type="text" class="form-control" placeholder="Address" name="address" />
        <input type="text" class="form-control" placeholder="Zip Code" name="zip" />
        <input type="text" class="form-control" placeholder="City" name="city" />
        <select class="form-control" name="country">
          ${this.countries.map(country => html`<option value="${country}">${country}</option>`)}
        </select>
        <input type="tel" class="form-control" placeholder="Phone" name="phone" id="phone" />
        <input type="email" class="form-control" placeholder="Email" name="email" />
        <button type="submit" class="btn btn-primary">
          Continue
        </button>
      </form>
    `;
  }

  connectedCallback() {
    super.connectedCallback();
    // Initialize intlTelInput
    const input = document.querySelector("#phone");
    window.intlTelInput(input, {
      initialCountry: "auto",
      separateDialCode: true,
      utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js", // Add the correct path to utils.js
    });
  }

  handleSubmit(event) {
    event.preventDefault();

    const formData = new FormData(event.target);
    const formObject = Object.fromEntries(formData.entries());

    // Do something with the form data, for example, log it
    console.log("Form data:", formObject);

    this.dispatchEvent(new Event('submitted', {bubbles: true, composed: true}));
  }

  createRenderRoot() {
    return this;
  }
}

customElements.define("custom-form", Form);

get time format to hh:mm

I fetch a specific time from an JSON. The value I get for the start-time looks like this: 2021-02-15T20:30:00+01:00 But I need to get it in hh:mm. I tried Date.parse() but I am unable to get the hours and minutes from this value. How can I do this else?

fetch('XXX')
        .then(Response => Response.json())
        .then(data => { 

    var summary = data['items']['0']['summary'];
    var location = data['items']['0']['location'];
    var start = data['items']['0']['start']['dateTime'];
    var end = data['items']['0']['end']['dateTime'];

Scrolling is blocked after router push

Working on a Vuejs project, I am trying to change the page of my PWA using the classic this.$router.push(); which works perfectly everywhere else but when doing it from a modal included in a component, the pushed page load but I cannot scroll it.

Note that, reloading the page unlock the scrolling and coming from somewhere else to the same page works too. So I gave up looking for the problem from the pushed page.

I tried to hide the modal before calling push FROM the modal and it didn't change nothing. I tried to call push from the main page (the one containing the modal-component) after I closed the modal and it didn't change nothing.

I searched a lot and hope that someone already encountered such a problem and found a solution..

Array.from() vs spread syntax

Is there some difference between using Array.from(document.querySelectorAll('div')) or [...document.querySelectorAll('div')]?

Here is a example:

let spreadDivArray = [...document.querySelectorAll('div')];
console.log(spreadDivArray);

let divArrayFrom = Array.from(document.querySelectorAll('div'));
console.log(divArrayFrom);

The console.log() will log the same result.

Is there any performance difference?

How to get time using Moment JS

I've two javascript variables: startDate and endDate. I want to store the current time(unix timestamp in ms) to endDate and timestamp of 24 hours before in startDate. I'll use this two variables to query the records for last 1 day. How can I do that using moment JS?

โŒ
โŒ