INVALID_VALUE: vertexAttribPointer/enableVertexAttribArray index out of range. Same JS paired with 2 different shaders – 1 works, 1 errors

I am modifying sample code at https://interactivecomputergraphics.com/8E/Code/06/shadedCube.html. Pared-down versions of this code are found in vertex.html (see below, which does more work in its vertex shader) and fragment.html (see below, which does more work in its fragment shader). The fragment.html file is based on vertex.html and shadedSphere2.html / shadedSphere4.html files from the same directory as shadedCube.html on the https://interactivecomputergraphics.com/ website. Both HTML files use the same JS file, shaded-cube.js (see below).

I can load and run vertex.html (using shaded-cube.js) but I get errors when I try to load and run fragment.html (which also uses shaded-cube.js):

WebGL: INVALID_VALUE: vertexAttribPointer: index out of range
WebGL: INVALID_VALUE: enableVertexAttribArray: index out of range

The errors correspond to these statements in shaded-cube.js:

const normalLoc = gl.getAttribLocation(program, 'aNormal');
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normalLoc);
console.log('normalLoc', normalLoc);

And the output of the console.log statement above for fragment.html is normalLoc -1.

I don’t understand the source of the error – I realize that I may be missing something obvious. Why does shaded-cube.js work for vertex.html and not for fragment.html?

I have looked at WEBGL: INVALID_VALUE: vertexAttribPointer: index out of range, INVALID_VALUE: enableVertexAttribArray: index out of range and tried to apply it to my situation.

Any help is greatly appreciated.

vertex.html

<!DOCTYPE html>
<html>
    <head>
        <script id="vertex-shader" type="x-shader/x-vertex">
            #version 300 es

            in vec4 aPosition;
            in vec3 aNormal;
            out vec4 vColor;

            uniform vec4 uAmbientProduct, uDiffuseProduct, uSpecularProduct;
            uniform float uShininess;
            uniform mat4 uModelViewMatrix, uProjectionMatrix;
            uniform vec4 uLightPosition, uViewerPosition;
            
            void main()
            {
                vec4 NN = vec4(aNormal, 0);
                vec3 N = normalize((uModelViewMatrix * NN).xyz);
                vec3 pos = (uModelViewMatrix * aPosition).xyz;
                vec3 light = uLightPosition.xyz;
                vec3 L = normalize(light - pos);

                vec3 V = normalize(uViewerPosition).xyz;
                vec3 H = normalize(L + V);

                // Compute terms in the illumination equation
                // ambient 
                vec4 ambient = uAmbientProduct;
                // diffuse
                float Kd = max(dot(L, N), 0.0);
                vec4 diffuse = Kd * uDiffuseProduct;
                // specular
                float Ks = pow(max(dot(N, H), 0.0), uShininess);
                vec4 specular = Ks * uSpecularProduct;

                vColor = ambient + diffuse + specular;
                vColor.a = 1.0;

                gl_Position = uProjectionMatrix * uModelViewMatrix * aPosition;
            }
        </script>
        <script id="fragment-shader" type="x-shader/x-fragment">
            #version 300 es

            precision mediump float;

            in vec4 vColor;
            out vec4 fColor;

            void
            main()
            {
                fColor = vColor;
            }
        </script>
        <script type="text/javascript" src="https://interactivecomputergraphics.com/8E/Code/Common/initShaders.js"></script>
        <script type="text/javascript" src="https://interactivecomputergraphics.com/8E/Code/Common/MVnew.js"></script>
        <script type="text/javascript" src="shaded-cube.js"></script>
    </head>
    <body>
        <canvas id="gl-canvas" width="512" height="512">
            Your browser does not support the HTML5 canvas element
        </canvas>
    </body>
</html>

fragment.html

<!DOCTYPE html>
<html>
    <head>
        <script id="vertex-shader" type="x-shader/x-vertex">
            #version 300 es

            in vec4 aPosition;
            in vec3 aNormal;
            out vec3 N, L, V;

            uniform mat4 uModelViewMatrix, uProjectionMatrix;
            uniform vec4 uLightPosition, uViewerPosition;

            void main()
            {
                vec3 pos = (uModelViewMatrix * aPosition).xyz;
                vec3 light = uLightPosition.xyz;
                vec4 NN = vec4(aNormal,0.0);

                vec3 N = normalize((uModelViewMatrix * NN).xyz);
                vec3 L = normalize(light - pos);
                vec3 V = normalize(uViewerPosition).xyz;

                gl_Position = uProjectionMatrix * uModelViewMatrix * aPosition;
            }
        </script>
        <script id="fragment-shader" type="x-shader/x-fragment">
            #version 300 es

            precision mediump float;
            
            in vec3 N, L, V;
            out vec4 fColor;

            uniform vec4 uAmbientProduct, uDiffuseProduct, uSpecularProduct;
            uniform float uShininess;

            void main()
            {
                vec3 H = normalize(L + V);
                vec4 ambient = uAmbientProduct;

                float Kd = max( dot(L, N), 0.0 );
                vec4 diffuse = Kd * uDiffuseProduct;

                float Ks = pow(max(dot(N, H), 0.0), uShininess);
                vec4 specular = Ks * uSpecularProduct;

                fColor = ambient + diffuse + specular;
                fColor.a = 1.0;
            }
        </script>
        <script type="text/javascript" src="https://interactivecomputergraphics.com/8E/Code/Common/initShaders.js"></script>
        <script type="text/javascript" src="https://interactivecomputergraphics.com/8E/Code/Common/MVnew.js"></script>
        <script type="text/javascript" src="shaded-cube.js"></script>
    </head>
    <body>
        <canvas id="gl-canvas" width="512" height="512">
            Your browser does not support the HTML5 canvas element
        </canvas>
    </body>
</html>

shaded-cube.js

'use strict';

function shadedCube() {
  let gl;
  let program;

  const numPositions = 36;

  const positionsArray = [];
  const normalsArray = [];

  const vertices = [
    vec4(-0.5, -0.5, 0.5, 1.0),
    vec4(-0.5, 0.5, 0.5, 1.0),
    vec4(0.5, 0.5, 0.5, 1.0),
    vec4(0.5, -0.5, 0.5, 1.0),
    vec4(-0.5, -0.5, -0.5, 1.0),
    vec4(-0.5, 0.5, -0.5, 1.0),
    vec4(0.5, 0.5, -0.5, 1.0),
    vec4(0.5, -0.5, -0.5, 1.0)];

  const viewerPosition = vec4(0.0, 0.0, 20.0, 0.0);
  const lightPosition = vec4(0.0, 2.0, 2.0, 0.0);
  const lightAmbient = vec4(0.2, 0.2, 0.2, 1.0);
  const lightDiffuse = vec4(1.0, 1.0, 1.0, 1.0);
  const lightSpecular = vec4(1.0, 1.0, 1.0, 1.0);

  const materialAmbient = vec4(0.0, 0.0, 0.8, 1.0);
  const materialDiffuse = vec4(0.8, 0.8, 0.0, 1.0);
  const materialSpecular = vec4(0.4, 0.4, 0.4, 1.0);
  const materialShininess = 100.0;

  const xAxis = 0;
  const yAxis = 1;
  const zAxis = 2;
  const axis = 0;
  const theta = vec3(0, 0, 0);

  const flag = true;

  function quad(a, b, c, d) {
    const t1 = subtract(vertices[b], vertices[a]);
    const t2 = subtract(vertices[c], vertices[b]);
    let normal = cross(t1, t2);
    normal = vec3(normal);
    console.log('cube face normal', normal[0], normal[1], normal[2]);

    positionsArray.push(vertices[a]);
    normalsArray.push(normal);
    positionsArray.push(vertices[b]);
    normalsArray.push(normal);
    positionsArray.push(vertices[c]);
    normalsArray.push(normal);
    positionsArray.push(vertices[a]);
    normalsArray.push(normal);
    positionsArray.push(vertices[c]);
    normalsArray.push(normal);
    positionsArray.push(vertices[d]);
    normalsArray.push(normal);
  }

  function colorCube() {
    quad(1, 0, 3, 2);
    quad(2, 3, 7, 6);
    quad(3, 0, 4, 7);
    quad(6, 5, 1, 2);
    quad(4, 5, 6, 7);
    quad(5, 4, 0, 1);
  }

  window.onload = function init() {
    const canvas = document.getElementById('gl-canvas');
    gl = canvas.getContext('webgl2');
    if (!gl) {
      alert( 'WebGL 2.0 is not available');
    }
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(0.8, 0.8, 0.8, 1.0);
    gl.enable(gl.DEPTH_TEST);

    //
    //  Load shaders and initialize attribute buffers
    //
    program = initShaders(gl, 'vertex-shader', 'fragment-shader');
    gl.useProgram(program);

    // generate the data needed for the cube
    colorCube();
    console.log('number of normals', normalsArray.length);

    const vBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, flatten(positionsArray), gl.STATIC_DRAW);
    const positionLoc = gl.getAttribLocation(program, 'aPosition');
    gl.vertexAttribPointer(positionLoc, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(positionLoc);
    console.log('positionLoc', positionLoc);

    const nBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, nBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, flatten(normalsArray), gl.STATIC_DRAW);
    const normalLoc = gl.getAttribLocation(program, 'aNormal');
    gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(normalLoc);
    console.log('normalLoc', normalLoc);

    const projectionMatrix = ortho(-1, 1, -1, 1, -100, 100);

    const ambientProduct = mult(lightAmbient, materialAmbient);
    const diffuseProduct = mult(lightDiffuse, materialDiffuse);
    const specularProduct = mult(lightSpecular, materialSpecular);

    gl.uniform4fv(
        gl.getUniformLocation(program, 'uAmbientProduct'), ambientProduct);
    gl.uniform4fv(
        gl.getUniformLocation(program, 'uDiffuseProduct'), diffuseProduct);
    gl.uniform4fv(
        gl.getUniformLocation(program, 'uSpecularProduct'), specularProduct);
    gl.uniform1f(
        gl.getUniformLocation(program, 'uShininess'), materialShininess);
    gl.uniform4fv(
        gl.getUniformLocation(program, 'uLightPosition'), lightPosition);
    gl.uniform4fv(
        gl.getUniformLocation(program, 'uViewerPosition'), viewerPosition);

    gl.uniformMatrix4fv(
        gl.getUniformLocation(program, 'uProjectionMatrix'),
        false, flatten(projectionMatrix));
    render();
  };

  function render() {
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    if (flag) {
      theta[axis] += 2.0;
    }
    let modelViewMatrix = mat4();
    modelViewMatrix = mult(modelViewMatrix,
        rotate(theta[xAxis], vec3(1, 0, 0)));
    modelViewMatrix = mult(modelViewMatrix,
        rotate(theta[yAxis], vec3(0, 1, 0)));
    modelViewMatrix = mult(modelViewMatrix,
        rotate(theta[zAxis], vec3(0, 0, 1)));

    gl.uniformMatrix4fv(
        gl.getUniformLocation(program, 'uModelViewMatrix'),
        false, flatten(modelViewMatrix));
    gl.drawArrays(gl.TRIANGLES, 0, numPositions);
    requestAnimationFrame(render);
  };
};

shadedCube();

Trying to use WDIO in Electron app causes error

I’m trying to run WDIO by clicking button in Electron app, but when I launch the app and click the button the app goes blank. i.e. It becomes a white screen. If I open DevTools before clicking it displays the following message:

“DevTools was disconected was diconected the page”

WDIO script works properly by itself, here it is:

const { remote } = require('webdriverio')
const fs = require('fs')
const path = require('path')
const axios = require('axios')

async function getData() {
    const dir = process.cwd() + '\Download';
    const browser = await remote({

        capabilities: {
            browserName: 'chrome',
            'goog:chromeOptions': {
                args: ['--headless', '--window-size=900,700'],
                prefs: { "download.default_directory": dir }
            }
        }
    })
    // Opening the website
    await browser.url('https://somewebsite');
    await browser.pause(2000);
    // Enter login 
    let access = JSON.parse(fs.readFileSync('passwords.json'));
    await browser.$('input[name="LoginForm[username]"]').setValue(access.login);
    await browser.$('input[name="LoginForm[password]"]').setValue(access.password);
    await browser.$('//button[@class="btn btn-danger btn-block btn-lg"]').click();
    await browser.pause(2000);
    // Go through the website
    await browser.url('https://somewebsite');
    const table = await browser.$('/html/body/div[2]/div[1]/div[3]/div[2]/table');
    await browser.pause(2000);
    async function counts() {
        const count = await browser.$('/html/body/div[2]/div[1]/div[3]/div[2]/table/tfoot/tr/td[1]').getText();
        const textRemove = count.replace('Показано ', '').replace(' із ', ', ');
        return textRemove.split(',').map(Number);
    }
    let number = await counts();
    while (number[0] < number[1]) {
        await table.scrollIntoView({ block: 'end', inline: 'end' });
        await browser.pause(500);
        number = await counts();
    }
    await browser.$('/html/body/div[2]/div[1]/div[3]/div[1]/div[2]/div[2]/button').click();
    await browser.$('/html/body/div[2]/div[1]/div[3]/div[1]/div[2]/div[2]/div/div[2]/div[2]/a[4]').click();
    await browser.pause(3000);
    await browser.closeWindow();
    // Rename downloaded files
    const oldFiles = fs.readdirSync(dir);
    oldFiles.forEach((fileName) => {
        const currentFilePath = path.join(dir, fileName);
        // Check if the file's name contains the part you want to modify
        if (fileName.includes('Товари')) {
            // Create the new file name by replacing the part
            const newFileName = fileName.replace('Товари', 'Goods');
            // Construct the new file path
            const newFilePath = path.join(dir, newFileName);
            // Rename the file
            fs.renameSync(currentFilePath, newFilePath);
        }
    });
    // Check the location
    const files = fs.readdirSync(dir);
    const fileStats = files
        .map(file => ({
            name: file,
            path: path.join(dir, file),
            stats: fs.statSync(path.join(dir, file))
        }))
        .filter(file => file.stats.isFile());
    const lastFile = fileStats
        .sort((a, b) => b.stats.mtime - a.stats.mtime)[0];
    const lastFilePath = lastFile.path;
    // Send data to the JSON
    let data = JSON.parse(fs.readFileSync('links.json'));
    data.DNTrade = lastFilePath;
    const JSONData = JSON.stringify(data, null, 2);
    fs.writeFileSync('links.json', JSONData);
    console.log(fs.readFileSync('links.json') === JSONData);
    if (fs.readFileSync('links.json') === JSONData) {
        (await async function makePostRequest() {
            axios.post('http://127.0.0.1:5000', 'Data updated successfully')
                .then(function (response) {
                    console.log(response.data);
                })
                .catch(function (error) {
                    console.error('Error:', error);
                });
        }())
    }
};

window.addEventListener('DOMContentLoaded', () => {
    const button = document.querySelector('#butt');
    button.addEventListener('click', () => {
        getData()
    })
})

Here the ‘index.html’ file I use to render the page in Electron:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Document</title>
</head>
<body>
    <button id="butt">Click me</button>
</body>
</html>

And finally ‘main.js’ which electron uses:

const { app, BrowserWindow } = require('electron')
const path = require('node:path')

const createWindow = () => {
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(__dirname, 'wdioRun.js'),
            nodeIntegration: true
        }
    })

    mainWindow.loadFile('index.html')
    mainWindow.on('closed', function () {
        mainWindow = null;
    });
}

app.whenReady().then(() => {
    createWindow()

    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
})

I’ve tried to launch WDIO in both Firefox and Edge by changing capabilities, but the issue remains the same.
Initially, I used import in WDIO, but it was too confusing to integrate it into Electron. So, I switched to require and checked the WDIO script by itself. It still works, but inside Electron, it doesn’t.
When I enabled logging in main.js, I received only ‘Renderer process crashed’.
The only useful thing I found in other similar answers on Stack Overflow is logging and debugging, but I still hope there is an easier way

How can I send emails using javascript for free?

// Creates user with email and password
app.post("/", async (req, res) => {
  const { name, email, password } = req.body;

  try {
    const studentSameEmail = await Student.find({ email });
    if (studentSameEmail.length !== 0) {
      return res
        .status(409)
        .json({ message: "A user with this email already exists." });
    }

    await bcrypt
      .hash(password, 10)
      .then(async (hash) => {
        const student = await Student.create({
          name,
          email,
          password: hash,
        });
        await student.save();
        res.status(200).json(student);
      })
      .catch((err) => console.error(err));
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
});

This code is perfectly fine, all is left that I want is to implement sending emails. I tried using nodemailer and some other open-source APIs but for nodemailer I needed an SMTP host and it costed money and was way too complicated. Are there any libraries or alternatives that I can possibly use that are free?

How to call AWS beckrock with @aws-sdk/client-bedrock-runtime in react application

I am trying to explore the possibility of creating an independent generative ai chat environment using AWS bedrock Claude v2. my initial thought was to create a react single page application as POC and just use tanstack query to call the bedrock api. However, as i am researching, i run into a brick wall where there are not a lot of resources available online about how to interact with AWS bedrock runtime using JavaScript, and the few that uses JavaScript are using node.js runtime instead of on a browser. the component is not finished but should compile, upon research it is suggested to add a global plugin to vite.config.js, but that did not solve my issue. I need help to adapt below JavaScript code into react component. also i would love to use webscoket and stream the response from bedrock but have not figureout how to implement that, please share any insight thanks!

react component called message:

import React from "react";
import { Input } from "@chakra-ui/react";
import { useState, useEffect } from "react";
import { BedrockRuntimeClient, InvokeModelCommand } from "aws-sdk";

export default function Message() {
  const [input, setInput] = useState("");
  const [maxtoken, setMaxToken] = useState(300);
  const [temperature, setTemperature] = useState(1);
  const [topK, setTopK] = useState(250);
  const [topP, setTopP] = useState(0.999);

  // Create an AWS service client
  const client = BedrockRuntimeClient({
    region: "us-east-1",
    credentials: {
      accessKeyId: process.env.AWS_ACCESS_KEY_ID ?? "",
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY ?? "",
    },
  });

  async function makeBedRockCall() {
    const request = {
      prompt: `nnHuman:${input}nnAssistant:`,
      max_tokens_to_sample: maxtoken,
      temperature: temperature,
      top_k: topK,
      top_p: topP,
    };
    const input = {
      body: JSON.stringify(request),
      contentType: "application/json",
      accept: "application/json",
      modelId: "anthropic.claude-v2",
    };

    try {
      const bedRockCommand = new InvokeModelCommand(input);
      const response = await client.send(bedRockCommand);
      const completion = JSON.parse(
        Buffer.from(response.body).toString("utf-8")
      );
      return completion;
    } catch (error) {
      console.log(error);
    }
  }

  return (
    <div className="pt-5">
      <Input placeholder="Input Questions" />
    </div>
  );
}

error in the browser

Uncaught TypeError: BedrockRuntimeClient is not a function
    at Message (Message.jsx:14:18)
    at renderWithHooks (react-dom.development.js:16305:18)
    at mountIndeterminateComponent (react-dom.development.js:20074:13)
    at beginWork (react-dom.development.js:21587:16)
    at HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
    at invokeGuardedCallback (react-dom.development.js:4277:31)
    at beginWork$1 (react-dom.development.js:27451:7)
    at performUnitOfWork (react-dom.development.js:26557:12)
    at workLoopSync (react-dom.development.js:26466:5)

The above error occurred in the <Message> component:

    at Message (http://localhost:5173/src/components/Message.jsx?t=1698945371615:24:29)
    at App
    at EnvironmentProvider 
    at ColorModeProvider 
    at ThemeProvider2 
    at ThemeProvider3 
    at ChakraProvider 
    at ChakraProvider22 
    at QueryClientProvider

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  define: {
    global: {},
    'process.env': {},
  }
})

I have tried searching on stackoverflow and AWS documentation: here are we i found.
below post indicate my javascript lib used should be functional
How to generate an image with @aws-sdk/client-bedrock-runtime
link to aws documentation
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/BedrockRuntime.html#invokeModel-property

Find or combine formulas in order to get a variable, based on a supplied list of formulas and input values in JS

As the title says, I need to find or combine formulas in order to get a variable e.g. “A” based on a supplied list of formulas and input values like this:

const formulas = [
    "FW=0.5*cw*roh*(v**(2))*A",
    "FG=m*g",
    "F=FG-FW",
    "a=F/m",
    "dv=a*dt",
    "ds=v*dt",
    "s=s+ds"
];

const inputs = [
    "cw=0.05",
    "m=...",
    [...]
];

Finding the initial formula to substitute in is fairly easily solved, but I’m having trouble with automatically substituting the other formulas, both in how to do it in theory and in practice.

Flask-Pymongo send_file not returning the file

I am trying to upload PDF file or image file from React app into Flask Pymongo. I uploaded the file and then tried to view the file in React app. I am using Flask=1.1.2, Flask-PyMongo=2.3.0, React=^17.0.1.

React frontend code to try to get the file

const [fileURL, setFileURL] = useState(null);
     const result = await axios.get(`${API}/file/${filename}`, {
        responseType: 'blob'
      });
      setFileURL(URL.createObjectURL(result.data));
 <img src={fileURL} alt={match.params.filename} className="view-file"/>

Flask backend code to upload and send file code

if 'file' in request.files:
        _file = request.files['file']
        _filename = _file.filename
        _file_mimetype = _file.content_type
        mongo.save_file(_file.filename, request.files['file'])
   
@ app.route('/file/<filename>')
@ cross_origin(supports_credentials=True)
def file(filename):
    print(filename)
    return mongo.send_file(filename)

mongo.send_file() doesn’t return anything. I can’t view or download the image or pdf file in frontend. Please help me to give some suggestions.

Split string in json object and return as array

I’m working with data sent from an api. I need to iterate through this info in order to render html elements. I have a problem with the ‘subjects’ data below as it is sent as a string, but I can only work with this as an array.

Sample json

{
    "employees": [
        {
            "id": 7099,
            "subjects": "English,Biology",
        },
        {
            "id": 7100,
            "subjects": "English,French",
        },
        {
            "id": 7101,
            "subjects": "Maths,Science",
        },
        {
            "id": 7102,
            "subjects": "English,Chemistry",
        },
        {
            "id": 7103,
            "subjects": "English,Biology,Chemistry",
        }
    ]
}

Here is a simplified version of my current component code in vue:

<template>    
  <div  v-for="employee in employees" :key="employee.id">
    <div v-for="subject in employee.subjects" :key="subject"> 
      {{ subject }} 
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      employees: []
    }
  },
  mounted() {
    fetch('http://localhost:3000/employees')
      .then(response => response.json())
      .then(response => this.employees = response)
  }
}
</script> 

I had a similar problem earlier, where I was recommended here to send the ’employee.subjects’ to a function that would split the strings and return them to be inserted into the html. This worked great, but it will not work in this situation as I will need to filter the data by subject before inserting the data into the html.

As far as I understand, I need to loop through the json, collect the ‘subjects’, split them, store this into a new array, and then insert back into the original ‘this.employees’.

About the furthest I’ve managed is below:

this.employees.forEach((employee) => {}

I’m not too sure how to go about this. It seems like a simple enough task, but nothing I try seems to work. Any ideas would be appreciated.

Different Uncaught ReferenceError for same situations

I don’t understand why for these same situations console returns two different outputs

console.log(a);
let a = 1;

console says a is not defined

and here

function a1() {
    console.log(a);
    let a = 1;
}
a1();

console says Cannot access ‘a’ before initialization
Isn’t it supposed to return “Cannot access ‘a’ before initialization” in both cases? Because we use the let declaration for declaring variables and they are in TDZ in both cases? Why does it say a is not defined?

Why does it work so? Is hoisting of variables in a global scope different from hoisting within block scope?

For flat config, what should I run instead of ‘npx eslint . –ext .js’?

When using eslint.config.js (flat config), what command should I use when linting *.js files from the command line?

With eslintrc.js or eslintrc.json, I have been using npx eslint . --ext .js, as suggested here.
Until now, it always worked fine.

But when I try that with eslint.config.js, I get:

Invalid option '--ext' - perhaps you meant '-c'?
You're using eslint.config.js, some command line flags are no longer available.
Please see https://eslint.org/docs/latest/use/command-line-interface for details.

I didn’t find any solution at https://eslint.org/docs/latest/use/command-line-interface.

My eslint.config.js is in the directory where I try to run the lint command.
It contains:

import js from '@eslint/js';
import globals from 'globals';

export default [
  {
    rules: js.configs.recommended.rules,
    languageOptions: { globals: { ...globals.node } },
  },
];

My package.json contains:

{
  "name": "flat-config",
  "devDependencies": {
    "eslint": "^8.52.0"
  },
  "private": true,
  "type": "module"
}

I ran npm install before running npx eslint . --ext .js.

For demo purposes, I have a small bad-code.js file :

const hiUnused = 'hi there';
const hello='Hello world';
const unusedFunc = function(unusedVariable) { console.log('hi!') }
consoler.log(hello);

I include the tag because I think the corresponding question and answer(s) would be very similar for TypeScript.

Cannot set properties of null (setting ‘innerHTML’) for Vanilla JS Component

I am working on a Vanilla JS Component and I am trying to use the innerHTML() function to change the text in a certain ID in the render() HTML code. However, I am getting the Cannot set properties of null (setting 'innerHTML') error. I am confused why this error is arising because the ID of the element I am looking for does exist, and the type of the string I am planning to put intto the innerHTML() function is a string and is not null type. The code is below

class checkoutitemC extends HTMLElement {
  constructor() {
    super();
  }
  connectedCallback(){
    const itemName = this.getAttribute('name');
    document.getElementById("nameX").innerHTML=`${itemName}`;
    const price = this.getAttribute('price');
    document.getElementById("priceX").innerHTML=`$${price}`;
    const qty = this.getAttribute('qty');
    document.getElementById("qtyX").innerHTML=`Qty: ${qty}`;
    this.render()
  }
  render(){
    this.innerHTML=`
<li class="list-group-item d-flex justify-content-between lh-condensed">
  <div>
    <h6 class="my-0" id="nameX"></h6>
    <small class="text-muted" id="qtyX"></small>
  </div>
  <span class="text-muted" id="priceX"></span>
</li>
    `
  }
}

I tried checking the types of the inputs I was putting into the innerHTML Text and found that to not be null. I also tried simiplying the issue in a seperate HTML file where innerHTML() and getElementById() do work. This tells me that something with the structure of the component causes this issue.

What are some potential explanations for this weird behaviors?

ReferenceError: ClassicEditor is not Defined (ckeditor5, ASP.NET MVC)

Yesterday I downloaded the Classic Editor of build ckeditor5 (version 40) from the official website and am struggling to implement it into my ASP.NET MVC website. Following their .NET tutorial, I attempted to create a simple WYSIWYG editor, but am regularly running into the ReferenceError: ClassicEditor is not Defined message that I have seen others run into with CKEditor5, even after downloading and attempting to mimic the MRE for the ClassicEditor from their website.

Here is what my code looks like, noting that multiple Bootstrap and jQuery links are handled by a core library outside of this repository:

<script src="/js/ckeditor.js"></script>
<script>
  ClassicEditor
    .create($('#ckeditor'))
    .catch(error => {
        console.error(error);
    });
</script>
<div class="row form-group">
  <div class="col-xl-6 col-lg-6 col-md-12 col-sm-12">
    <div class="row">
      <div class="col-md-12">
        <textarea class="ckeditor" id="ckeditor"></textarea>
      </div>
    </div>
  </div>
</div>

Some of the suggestions I tried already include:

  1. Replacing /js/ckeditor.js with the CDN link
  2. Placing the ClassicEditor inside and outside of a jQuery $(function(){})
  3. Setting window.ClassicEditor=ClassicEditor in the script
  4. Setting var ClassicEditor = require('js/ckeditor')

Vue.js Pagination – Current Page Number Exceeding Maximum Number Of Pages

I’m attempting to implement pagination in this table I’ve built which contains data for Magic: The Gathering cards.

The default state is to only show 5 items per page, with a page selector dropdown and a results-per-page dropdown located at the bottom of the screen (along with “Next Page” and “Previous Page” buttons for navigation).

const app = new Vue({
  el: "#app",
  data: {
    apiUrl: "https://api.magicthegathering.io/v1/cards",
    cards: [],
    pageNumber: 1,
    resultsPerPage: 5,
    dropdownResultsPerPage: 5,
    increments: [5, 10, 15, 20, 25]
  },
  created: function() {
    var vue = this;
    axios
      .get(this.apiUrl)
      .then(function(data) {
        vue.cards = data.data.cards;
      })
      .catch(function(error) {
        console.log(error);
      });
  },
  computed: {
    startIndex: function() {
      return (this.pageNumber - 1) * this.resultsPerPage;
    },
    endIndex: function() {
      return this.startIndex + this.dropdownResultsPerPage;
    },
    numberOfPages: function() {
      return Math.ceil(this.cards.length / this.dropdownResultsPerPage);
    },
    paginatedData: function() {
      return this.cards.slice(this.startIndex, this.endIndex);
    }
  },
  methods: {
    nextPage: function() {
      this.pageNumber++;
    },
    previousPage: function() {
      this.pageNumber--;
    }
  }
});
body {
  overflow: hidden;
}

#header {
  display: flex;
  position: sticky;
  border-bottom: 1px solid black;
}

#app .content {
  overflow: auto;
  height: 300px;
  position: relative;
}

#pagination: {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  box-shadow: 0px 0px 6px 2px #fafafa;
}

[v-cloak] {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.0/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.8/vue.min.js"></script>
<div id="header">
  <h1>MTG Cards</h1>
</div>
<div id="app" v-cloak>
  <div class="content">
    <table>
      <thead>
        <th>Id</th>
        <th>Name</th>
        <th>Mana Cost</th>
      </thead>
      <tbody>
        <tr v-for="(card, index) in paginatedData" :key="index">
          <td>{{ card.id }}</td>
          <td>{{ card.name }}</td>
          <td>{{ card.manaCost }}</td>
        </tr>
      </tbody>
    </table>
  </div>
  <div id="pagination">
    <p>
      Page:
      <select v-model="pageNumber">
        <option v-for="(page, index) in numberOfPages" :key="index" :value="page">
          {{ page }}
        </option>
      </select>
      of {{ numberOfPages }}
      <button @click="previousPage" :disabled="pageNumber == 1">
        Previous
      </button>
      <button @click="nextPage" :disabled="pageNumber >= numberOfPages">
        Next
      </button> |
      <select v-model="dropdownResultsPerPage">
        <option v-for="(increment, index) in increments" :key="index" :value="increment">
          {{ increment }}
        </option>
      </select>
      cards per page
    </p>
  </div>
</div>

Let’s say you have resultsPerPage set to 5, which would give you a total number of pages of 100.

Now let’s say you navigate to page 5 of 20 and then change the resultsPerPage value to 25. This will change the total number of pages from 20 to 4, but since you are on page 5 you won’t be able to see that reflected in the Page Number dropdown, and the page navigation then gets a little confusing.

Is there a way to maintain the visual page number while also keeping the same results in the table on screen?