Uncaught TypeError in javascript - javascript

I have created chatbot using pytorch and integrating it into flask project.
But getting some erros please help me with it. Thanks!
// app.js
app.js file used while creating chatbot
class Chatbox {
constructor() {
this.args = {
openButton : document.querySelector('.chatbox__button'),
closeButton : document.querySelector('.chatbox__support'),
sendButton : document.querySelector('.send__button')
}
this.state = false;
this.messages = [];
}
display() {
const {openButton, chatBox, sendButton} = this.args;
openButton.addEventListener('click', () => this.toggleState(chatBox))
sendButton.addEventListener('click', ()=> this.onSendButton(chatBox))
const node = chatBox.querySelector('input');
node.addEventListener("keyup", ({key}) => {
if (key === "Enter"){
this.onSendButton(chatBox)
}
})
}
toggleState(chatBox){
this.state = !this.state;
if(this.state){
chatBox.classList.add('chatbox--active')
}else{
chatBox.classList.remove('chatbox--active')
}
}
onSendButton(chatbox){
var textField = Chatbox.querySelector('input');
let text1 = textField.value
if (text1 === ""){
return;
}
let msg1 = {name : "User", message:text1}
this.messages.push(msg1);
fetch($SCRIPT_ROOT + '/predict', {
method: 'POST',
body : JSON.stringify({message:text1}),
mode : 'cors',
headers : {
'Content-Type' : 'application/json'
},
})
.then(r => r.json())
.then(r => {
let msg2 = {name: 'Sam', message: r.answer};
this.messages.push(msg2);
this.updateChatText(chatbox)
textField.value = ''
}).catch((error) => {
console.error('Error:', error);
this.updateChatText(chatbox)
textField.value = ''
});
}
updateChatText(chatbox){
var html = '';
this.messages.slice().reverse().forEach(function(item,){
if (item.name === 'Sam'){
html += '<div class="messages__item messages__item--visitor'> + item.message + '<div>'
}
else{
html += 'div class="messages-__item messages__item--operator' + item.message + '<div>'
}
});
const chatmessage = chatbox.querySelector('.chatbox__messages');
chatmessage.innerHTML = html;
}
}
const newChat = new Chatbox();
newChat.display();
base.html
frontend file to render chatbot window. But on clicking on icon it does not loaded.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Chatbot</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div class="container">
<div class="chatbox">
<div class="chatbox__support">
<div class="chatbox__header">
<div class="chatbox__image--header">
<img src="https://img.icons8.com/color/48/000000/circled-user-female-skin-type-5--v1.png" alt="image">
</div>
<div class="chatbox__content--header">
<h4 class="chatbox__heading--header">Chat support</h4>
<p class="chatbox__description--header">Hi. My name is Sam. How can I help you?</p>
</div>
</div>
<div class="chatbox__messages">
<div></div>
</div>
<div class="chatbox__footer">
<input name="input" type="text" placeholder="Write a message...">
<button class="chatbox__send--footer send__button">Send</button>
</div>
</div>
<div class="chatbox__button">
<button><img src="{{ url_for('static', filename='images/chatbox-icon.svg') }}" /></button>
</div>
</div>
</div>
</body>
<script>
$SCRIPT_ROOT = {{ request.script_root|tojson }};
</script>
<script type="text/javascript" src="{{ url_for('static', filename='app.js') }}"></script>
</html>
Im getting the following errors:
Uncaught TypeError: Cannot read properties of undefined (reading 'querySelector')
at Chatbox.display (app.js:20:34)
at app.js:95:9
app.js:33 Uncaught TypeError: Cannot read properties of undefined (reading 'classList')
at Chatbox.toggleState (app.js:33:25)
at HTMLDivElement.<anonymous> (app.js:16:61)
Python chatbot using Pytorch

Error 1: chatBox is undefined because this.args does't have the chatBox property, you wrote "closeButton" at the 2nd position.
Erorr 2: Again, chatBox is undefined.

Related

Nuxt.js + Vue.js + Javascript Hackernews API displaying comments (nested kids also)

I have following code in my project:
<template>
<div>
<Head>
<Title>{{ story.title}}</Title>
<Meta name="description" content="product.description" />
</Head>
<StoryDetails :story="story" />
<button class="btn">
<NuxtLink to="/">Back to home</NuxtLink>
</button>
</div>
</template>
scripts:
<script setup>
definePageMeta({
layout: "stories"
})
const { id } = useRoute().params
const uri = 'https://hacker-news.firebaseio.com/v0/item/'+ id +'.json?print=pretty'
const { data: story } = await useFetch(uri, { key:id })
const { data: comments} = []
if(!this.story.value) {
throw createError({ statusCode: 404, statusMessage: 'Story not found!', fatal: true })
}
this.story.kids.forEach(id => {
$fetch('https://hacker-news.firebaseio.com/v0/item/'+ id +'.json?print=pretty')
.then((response) => {
this.comments.push(response)
console.log(this.comments)
})
.catch(err=> {q
this.err = err
})
})
console.log(this.comments)
</script>
Please, help. How can I display comments (nested kids also) ?
I am getting this error for code above:
GET http://localhost:3000/_nuxt/pages/[id].vue?vue&type=style&index=0&scoped=dd4001d8&lang.css net::ERR_ABORTED 404 (Page not found: /_nuxt/pages/[id].vue?vue&type=style&index=0&scoped=dd4001d8&lang.css)
My github repo: https://github.com/AzizxonZufarov/newsnuxt2/blob/main/pages/%5Bid%5D.vue
PS: Also I am getting this error:
[plugin:vite:css] [postcss] C:/Users/Acer/Desktop/newsnuxt/pages/[id].vue?vue&type=style&index=0&scoped=dd4001d8&lang.css:4:15: Unknown word
C:/Users/Acer/Desktop/newsnuxt/pages/[id].vue:4:15
2 | <div>
3 | <Head>
4 | <Title>{{ story.title}}</Title>
| ^
5 | <Meta name="description" content="product.description" />
6 | </Head>

If I don't choose a file and press the send button, I will get a popup but it'll break any future popups

If I press Send ☞ without choosing a file, it'll say "No file selected." in a little Bootstrap warning alert but it seems to break all future alerts like file uploaded or file already exists on disk.
If I make an error alert like file already on disk, it'll work and won't break future alerts (meaning it won't stop alerts that popup in the future from showing).
So, why is the "No file selected" alert breaking other alerts?
In this clip, you can see me trying to make more than one of that alert but it just doesn't want to.
Here is my ejs file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Androp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
</head>
<body>
<div class="container-fluid">
<p>
<h1>Androp - Send to [...] MBP</h1>
</p>
<div class="input-group mb-3">
<button class="btn btn-outline-primary" type="button" onclick="send()">Send ☞</button>
<input type="file" class="form-control" id="fileSelector">
</div>
<div id="alerts"></div>
<div class="text-center">
<div id="spinny" class="spinner-border" style="width: 3rem; height: 3rem; visibility: hidden;"></div>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io()
const engine = socket.io.engine
let maxSize = 0
let sending = false
socket.on("disconnect", (reason) => {
alert(`Disconnected from laptop! Check your internet or refresh the page. 💀 (${reason})`, "warning")
})
engine.on("close", reason => {
console.log(reason)
})
socket.emit("getMaxSize", (size) => {
return maxSize = size
})
const alert = (message, type) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = [
`<div class="alert alert-${type} fade show" role="alert">`,
` <div>${message}</div>`,
'</div>'
].join('')
document.getElementById("alerts").append(wrapper)
return bootstrap.Alert.getOrCreateInstance(wrapper)
}
function send() {
if (sending) {
return false
}
sending = true
const file = document.getElementById("fileSelector").files[0] || false
function close(alert) {
setTimeout(() => {
alert.close()
}, 3500)
}
if (!file) { return close(alert("No files to upload.", "warning")) }
if (file.size >= maxSize) { return close(alert(`File is bigger than ${Math.round(maxSize / (1024 ** 2))} MB`, "danger")) }
document.getElementById("spinny").style.visibility = 'visible'
socket.timeout(10000).emit("upload", file, file.name, file.size, (err, status) => {
if(err) {
return close(alert("Could not contact laptop within 10s, laptop might be in sleep mode. 💀", "warning"))
}
document.getElementById("spinny").style.visibility = 'hidden'
sending = false
return close(alert(status.message, status.success ? "success" : "danger"))
})
}
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.11.5/dist/umd/popper.min.js"
integrity="sha384-Xe+8cL9oJa6tN/veChSP7q+mnSPaj5Bcu9mPX5F5xIGE0DVittaqT5lorf0EI7Vk"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/js/bootstrap.min.js"
integrity="sha384-ODmDIVzN+pFdexxHEHFBQH3/9/vQ9uori45z4JjnFsRydbmQbmL5t1tQ0culUzyK"
crossorigin="anonymous"></script>
</body>
</html>
You should move the flag sending = true when you actually plan to send after validation. I would also place sending = false right when callback returns, even if err
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Androp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
</head>
<body>
<div class="container-fluid">
<p>
<h1>Androp - Send to [...] MBP</h1>
</p>
<div class="input-group mb-3">
<button class="btn btn-outline-primary" type="button" onclick="send()">Send ☞</button>
<input type="file" class="form-control" id="fileSelector">
</div>
<div id="alerts"></div>
<div class="text-center">
<div id="spinny" class="spinner-border" style="width: 3rem; height: 3rem; visibility: hidden;"></div>
</div>
</div>
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js" integrity="sha384-7EyYLQZgWBi67fBtVxw60/OWl1kjsfrPFcaU0pp0nAh+i8FD068QogUvg85Ewy1k" crossorigin="anonymous"></script>
<script>
const socket = io()
const engine = socket.io.engine
let maxSize = 0
let sending = false
socket.on("disconnect", (reason) => {
alert(`Disconnected from laptop! Check your internet or refresh the page. 💀 (${reason})`, "warning")
})
engine.on("close", reason => {
console.log(reason)
})
socket.emit("getMaxSize", (size) => {
return maxSize = size
})
const alert = (message, type) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = [
`<div class="alert alert-${type} fade show" role="alert">`,
` <div>${message}</div>`,
'</div>'
].join('')
document.getElementById("alerts").append(wrapper)
return bootstrap.Alert.getOrCreateInstance(wrapper)
}
function send() {
if (sending) {
return false
}
const file = document.getElementById("fileSelector").files[0] || false
function close(alert) {
setTimeout(() => {
alert.close()
}, 3500)
}
if (!file) {
return close(alert("No files to upload.", "warning"))
}
if (file.size >= maxSize) {
return close(alert(`File is bigger than ${Math.round(maxSize / (1024 ** 2))} MB`, "danger"))
}
sending = true
document.getElementById("spinny").style.visibility = 'visible'
socket.timeout(10000).emit("upload", file, file.name, file.size, (err, status) => {
if (err) {
return close(alert("Could not contact laptop within 10s, laptop might be in sleep mode. 💀", "warning"))
}
document.getElementById("spinny").style.visibility = 'hidden'
sending = false
return close(alert(status.message, status.success ? "success" : "danger"))
})
}
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
</body>
</html>

Why Electron Remote not working on Electron-Tabs?

I get these errors in my Electron App Project:
webview logged from Dashboard.html(146): Uncaught TypeError: window.require is not a function
webview logged from dashboard.js(7): Uncaught ReferenceError: require is not defined
and further errors in other files that also use the require function.
Edit: To be more explicit: These errors occur in the tab files that should be opened. Not in the main Window.
These errors occured, because i updated my electron version to the latest one (was on 10 or 11 before) - but needed new version for a new npm module.
I already tried to add nodeIntegration: true, contextIsolation: false, enableRemoteModule: true to webpreferences of main browserwindow and also to each tab in electron-tabs and it didnt work.
I will show here only the main files, because showing the whole project is too much for the question text...
Index.html for Electron:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ExMeX Companion App</title>
<link rel="stylesheet" href="node_modules/electron-tabs/electron-tabs.css">
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<div class="etabs-tabgroup">
<div class="etabs-tabs"></div>
<div class="etabs-buttons"></div>
</div>
<div class="etabs-views"></div>
<script>
// 1. Require the module
const TabGroup = require("electron-tabs");
// 2. Define the instance of the tab group (container)
let tabGroup = new TabGroup({});
let tabDashboard = tabGroup.addTab({
title: "Dashboard",
src: "pages/Dashboard.html",
visible: true,
active: true,
webviewAttributes: {
webSecurity: false,
plugins: true,
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
}
});
let webviewDashboard = tabDashboard.webview;
webviewDashboard.addEventListener('console-message', function(e) {
var srcFile = e.sourceId.replace(/^.*[\\\/]/, '');
if (srcFile == 'renderer_init.js') {
console.log("Electron Security warning hidden from console.");
} else {
console.log('webview logged from ' + srcFile + '(' + e.line + '): ' + e.message);
}
});
//implementation to get messages from other renderer windows
const {
remote,
ipcRenderer
} = require('electron');
var ExmexGUITabOpened = 'false';
var ExmexGUITabID = 0;
ipcRenderer.on("cardClickedExmexGUI", function(event, arg) {
if (ExmexGUITabOpened == 'false') {
//create new tab
console.log("Tab creation ExmexGUI");
let tabExmexGUI = tabGroup.addTab({
title: "Batch Orchestration",
src: "pages/BatchOrchestration.html",
visible: true,
active: true,
webviewAttributes: {
webSecurity: false,
plugins: true,
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
}
});
ExmexGUITabOpened = 'true';
ExmexGUITabID = tabExmexGUI.id;
tabExmexGUI.on("close", (tab) => {
ExmexGUITabOpened = 'false';
ExmexGUITabID = 0;
});
let webview2 = tabExmexGUI.webview;
webview2.addEventListener('console-message', function(e) {
var srcFile = e.sourceId.replace(/^.*[\\\/]/, '');
if (srcFile == 'renderer_init.js') {
console.log("Electron Security warning hidden from console.");
} else {
console.log('webview logged from ' + srcFile + '(' + e.line + '): ' + e.message);
}
});
} else {
let activeExmexTab = tabGroup.getTab(ExmexGUITabID);
activeExmexTab.activate();
}
});
var ExmexConfigurationTabOpened = 'false';
var ExmexConfigurationTabID = 0;
ipcRenderer.on("cardClickedExmexConfiguration", function(event, arg) {
if (ExmexConfigurationTabOpened == 'false') {
//create new tab
console.log("Tab creation ExmexConfiguration");
let tabExmexConfig = tabGroup.addTab({
title: "ExMeX Configuration",
src: "pages/ExmexConfiguration.html",
visible: true,
active: true,
webviewAttributes: {
webSecurity: false,
plugins: true,
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
}
});
ExmexConfigurationTabOpened = 'true';
ExmexConfigurationTabID = tabExmexConfig.id;
tabExmexConfig.on("close", (tab) => {
ExmexConfigurationTabOpened = 'false';
ExmexConfigurationTabID = 0;
});
let webview3 = tabExmexConfig.webview;
webview3.addEventListener('console-message', function(e) {
var srcFile = e.sourceId.replace(/^.*[\\\/]/, '');
if (srcFile == 'renderer_init.js') {
console.log("Electron Security warning hidden from console.");
} else {
console.log('webview logged from ' + srcFile + '(' + e.line + '): ' + e.message);
}
});
} else {
let activeExmexConfigTab = tabGroup.getTab(ExmexConfigurationTabID);
activeExmexConfigTab.activate();
}
});
var ExmexSourceFilterTabOpened = 'false';
var ExmexSourceFilterTabID = 0;
ipcRenderer.on("cardClickedSourceFilter", function(event, arg) {
if (ExmexSourceFilterTabOpened == 'false') {
//create new tab
console.log("Tab creation SourceFilter");
let tabSourceFilter = tabGroup.addTab({
title: "Filter Configuration",
src: "pages/FilterConfiguration.html",
visible: true,
active: true,
webviewAttributes: {
webSecurity: false,
plugins: true,
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
}
});
ExmexSourceFilterTabOpened = 'true';
ExmexSourceFilterTabID = tabSourceFilter.id;
tabSourceFilter.on("close", (tab) => {
ExmexSourceFilterTabOpened = 'false';
ExmexSourceFilterTabID = 0;
});
let webview4 = tabSourceFilter.webview;
webview4.addEventListener('console-message', function(e) {
var srcFile = e.sourceId.replace(/^.*[\\\/]/, '');
if (srcFile == 'renderer_init.js') {
console.log("Electron Security warning hidden from console.");
} else {
console.log('webview logged from ' + srcFile + '(' + e.line + '): ' + e.message);
}
});
} else {
let activeExmexSourceFilterTab = tabGroup.getTab(ExmexSourceFilterTabID);
activeExmexSourceFilterTab.activate();
}
});
</script>
</body>
</html>
Main.js for electron
/*jshint esversion: 8 */
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const path = require('path');
const url = require('url');
global.mainWindow = null;
/* Configuration for server is stored in these variables, accessible for all windows or tabs */
/*Test Config*/
const appversion = '0.5.0 Beta';
/*Live Config*/
global.user = 'Not available';
global.password = 'Not Set';
global.server = 'Not available';
global.serverPort = 0;
global.database = 'Not available';
global.serverInfoText = 'Server connection is not configured.';
global.installedExmexVersion = 'ExMeX | Core ? | App ' + appversion + '';
global.trustedConnectionOption = 'no';
global.userDeploy = '';
global.passwordDeploy = '';
global.serverDeploy = '';
global.databaseDeploy = '';
function createWindow() {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1080,
height: 1000,
webPreferences: {
webviewTag: true,
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
}
});
// Open the DevTools.
//mainWindow.webContents.openDevTools();
//remove the top menu from electron
//mainWindow.removeMenu();
// load the index.html of the app.
mainWindow.loadFile('index.html');
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow);
// Quit when all windows are closed.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
const {
ipcMain
} = require('electron'); // include the ipc module to communicate with render process ie to receive the message from render process
ipcMain.on("setUser", function(event, arg) {
global.user = arg;
});
ipcMain.on("setPassword", function(event, arg) {
global.password = arg;
});
ipcMain.on("setServer", function(event, arg) {
global.server = arg;
});
ipcMain.on("setServerPort", function(event, arg) {
global.serverPort = parseInt(arg, 10);
});
ipcMain.on("setDatabase", function(event, arg) {
global.database = arg;
});
ipcMain.on("setServerInfoText", function(event, arg) {
global.serverInfoText = arg;
});
ipcMain.on("setInstalledExmexVersion", function(event, arg) {
global.installedExmexVersion = 'ExMeX | Core ' + arg + ' | App ' + appversion + '';
});
ipcMain.on("setTrustedConnection", function(event, arg) {
global.trustedConnectionOption = arg;
});
const Store = require('electron-store');
Store.initRenderer();
Dashboard.html
This is the first Tab that should be opened, here the error occurs at the first time
<!doctype html>
<html lang="en" class="no-js">
<!-- <link rel="stylesheet" href="node_modules/electron-tabs/electron-tabs.css"> -->
<link rel="stylesheet" href="../css/dashboard.css">
<link rel="stylesheet" href="../css/sweetalert.css" />
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ExMeX Dashboard App</title>
</head>
<body>
<div class="grid-container-dashboard">
<header class="header">
<div class="header_server_info">
<p style="font-size:16px">Server</p>
<p style="font-size:12px" id="serverInfoText">No server connection.</p>
</div>
<!-- Button to open the serverConfigPopupWindow -->
<div class="header_server_connect">
<button id="myBtn" class="header_button"> Connect</button>
</div>
<div id="serverConfigPopupWindow" class="modal">
<div class="modal-content">
<!-- <span class="close">×</span> -->
<p style="font-size:20px ">Configure the server connection</p>
<br><br>
<div class="box">
<p class="item1">Server Name: </p> <input type="text" id="serverInputField" class="item2" placeholder="Server to connect">
</div>
<div class="box">
<p class="item1">Server Port: </p> <input type="text" id="serverPortInputField" class="item2" placeholder="Port to connect" value="1433">
</div>
<div class="box">
<p class="item1">Database Name: </p> <input type="text" id="databaseInputField" class="item2" placeholder="Your ExMeX database name">
</div>
<div class="box">
<p class="item1">Authentication Mode: </p>
<select class="item2" id="authenticationModeOptionField" onclick="showOrHideUserPWFields()">
<option>Windows Authentication</option>
<option>SQL Server Authentication</option>
</select>
</div>
<div class="box" id="userBox" style="visibility: hidden">
<p class="item1">User: </p> <input type="text" id="userInputField" class="item2" placeholder="Your user login name">
</div>
<div class="box" id="passwordBox" style="visibility: hidden">
<p class="item1">Password: </p> <input type="password" id="passwordInputField" class="item2" placeholder="Your password">
</div>
<br><br>
<textarea type="text" id="OutputTestServerConnection" name="FilterSPOutput" disabled rows="4" cols="70" style="resize: none;">Output will be shown after saving first filter.
</textarea>
<button id="testServerConfig" class="blue_button_big" onclick="testServerConfigFunction()">Connect</button>
<button id="cancelServerConfig" class="blue_button_big" onclick="cancelServerConfigFunction()">Cancel</button>
</div>
</div>
</header>
<aside class="sidenav">
<img src="../img/TedamohLogoFull.png" style=" display: block; margin-left: auto; margin-right: auto; width: 90%; height:80px; object-fit: contain;" alt="Logo" id="spin">
<ul class="sidenav_list">
<p style="font-size:20px">Quick Links</p>
<li class="sidenav_list-item" id="sidenav_Tedamoh" onclick="openTedamohHomepageInBrowser()">TEDAMOH</li>
<li class="sidenav_list-item" id="sidenav_Helpdesk" onclick="openHelpdeskInBrowser()">Helpdesk</li>
<li class="sidenav_list-item" id="sidenav_FAQ" onclick="openFAQInBrowser()">FAQ</li>
<li class="sidenav_list-item" id="sidenav_Documentation" onclick="openDocumentationInBrowser()">Documentation</li>
</ul>
</aside>
<main class="main">
<div class="main-header">
<div class="main-header_heading">
<img src="../img/ExMeX_Banner_Dashboard.png" style="width: 100%; height: 100%; " alt="ExMeX Dashboard">
</div>
<!-- <div class="main-header_updates">A powerful interface component for the Tedamoh ExMeX Framework. <br />We call it ExMeX Companion App!</div> -->
</div>
<div class="main-overview-dashboard">
<div class="overviewcard" id="cardIDExmexConfiguration">
<div class="overviewcard_icon"><img src="../img/dashboard_config.png" style="width:70px;height:70px;" alt="ConfigIcon"></div>
<div class="overviewcard_info">Exmex Configuration</div>
</div>
<div class="overviewcard" id="cardIDExmexGUI">
<div class="overviewcard_icon"><img src="../img/dashboard_threearrows.png" style="width:70px;height:70px;" alt="ThreeArrowIcon"></div>
<div class="overviewcard_info">Batch Orchestration</div>
</div>
<div class="overviewcard" id="cardIDFilterConfig">
<div class="overviewcard_icon"><img src="../img/dashboard_filter.png" style="width:70px;height:70px;" alt="FilterIcon"></div>
<div class="overviewcard_info">Filter Configuration</div>
</div>
<!-- future -->
<div class="overviewcard" id="cardIDFuture4" style=" pointer-events: none;">
<!-- <div class="overviewcard_icon">Icon</div>
<div class="overviewcard_info">Future feature</div> -->
</div>
<div class="overviewcard" id="cardIDFuture5" style=" pointer-events: none;">
<!-- <div class="overviewcard_icon">Icon</div>
<div class="overviewcard_info">Future feature</div> -->
</div>
<div class="overviewcard" id="cardIDFuture6" style=" pointer-events: none;">
<!-- <div class="overviewcard_icon">Icon</div>
<div class="overviewcard_info">Future feature</div> -->
</div>
<div class="overviewcard" id="cardIDFuture7" style=" pointer-events: none;">
<!-- <div class="overviewcard_icon">Icon</div>
<div class="overviewcard_info">Future feature</div> -->
</div>
<div class="overviewcard" id="cardIDFuture8" style=" pointer-events: none;">
<!-- <div class="overviewcard_icon">Icon</div>
<div class="overviewcard_info">Future feature</div> -->
</div>
<div class="overviewcard" id="cardIDFuture9" style=" pointer-events: none;">
<!-- <div class="overviewcard_icon">Icon</div> -->
<!-- <div class="overviewcard_info">Future feature</div> -->
</div>
<!-- future end -->
</div>
</main>
<footer class="footer">
<div class="footer_copyright">© 2019-2022 TEDAMOH GmbH</div>
<div class="footer_signature" id="footer_signature">ExMeX | Core ? | App ?</div>
</footer>
</div>
</body>
<!-- Insert this line above script imports -->
<script>
if (typeof module === 'object') {
window.module = module;
module = undefined;
}
</script>
<!-- normal script imports etc -->
<script src="../js/sweetalert.min.downloaded.js"></script>
<script src="../js/swal-messages.js"></script>
<!-- scripts for opening the links on the dashboard -->
<script>
const {
shell
} = window.require('electron');
function openDocumentationInBrowser() {
shell.openExternal("https://tedamoh.com/de/helpdesk/doc-faq/exmex-framework-book");
}
function openFAQInBrowser() {
shell.openExternal("https://tedamoh.com/de/helpdesk/doc-faq/frequently-asked-questions");
}
function openTedamohHomepageInBrowser() {
shell.openExternal("https://tedamoh.com/de/");
}
function openHelpdeskInBrowser() {
shell.openExternal("https://tedamoh.com/de/helpdesk/my-tickets");
}
</script>
<script src="../js/SQLConnectAndQuery.js"></script>
<script src="../js/dashboard.js"></script>
<!-- Insert this line after script imports -->
<script>
if (window.module) module = window.module;
actualizeVersionInfo('footer_signature');
</script>
</html>
Dashboard.js
This is the javascript for the first tab that should be opened.
/*jshint esversion: 8 */
// include the ipc module to communicate with main process.
const {
remote,
ipcRenderer
} = require('electron');
const Store = require('electron-store');
const store = new Store();
//if store file was never initialized, put defaults in it
if (store.get('serverConfigStore') == undefined) {
store.set('serverConfigStore', {
serverName: "Server to connect",
serverPort: 1433,
databaseName: "Your ExMeX database name",
authenticationMode: "Windows Authentication",
user: ""
});
}
// console.log(store.get('serverConfigStore').serverName);
// console.log(store.get('serverConfigStore').serverPort);
// console.log(store.get('serverConfigStore').databaseName);
let btnclick2 = document.getElementById('cardIDExmexGUI');
btnclick2.addEventListener('click', () => {
var arg2 = "secondparam";
//send the info to main process . we can pass any arguments as second param.
//ipcRenderer.send("btnclick", arg); // ipcRender.send will pass the information to main process
let mainWindowTest2 = remote.getGlobal('mainWindow');
if (mainWindowTest2) mainWindowTest2.webContents.send("cardClickedExmexGUI", arg2);
});
let btnclick3 = document.getElementById('cardIDExmexConfiguration');
btnclick3.addEventListener('click', () => {
var arg3 = "secondparam";
//send the info to main process . we can pass any arguments as second param.
//ipcRenderer.send("btnclick", arg); // ipcRender.send will pass the information to main process
let mainWindowTest3 = remote.getGlobal('mainWindow');
if (mainWindowTest3) mainWindowTest3.webContents.send("cardClickedExmexConfiguration", arg3);
});
let btnclick4 = document.getElementById('cardIDFilterConfig');
btnclick4.addEventListener('click', () => {
var arg4 = "secondparam";
//send the info to main process . we can pass any arguments as second param.
//ipcRenderer.send("btnclick", arg); // ipcRender.send will pass the information to main process
let mainWindowTest4 = remote.getGlobal('mainWindow');
if (mainWindowTest4) mainWindowTest4.webContents.send("cardClickedSourceFilter", arg4);
});
// Get the modal
var modal = document.getElementById("serverConfigPopupWindow");
// Get the button that opens the modal
var btn = document.getElementById("myBtn");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on the button, open the modal
btn.onclick = function() {
console.log(store.get('serverConfigStore').serverName);
console.log(store.get('serverConfigStore').serverPort);
console.log(store.get('serverConfigStore').databaseName);
console.log('The connect button clicked and onclickfunction starts');
modal.style.display = "block";
document.getElementById('OutputTestServerConnection').innerHTML = '';
document.getElementById('serverInputField').value = store.get('serverConfigStore').serverName;
document.getElementById('serverPortInputField').value = store.get('serverConfigStore').serverPort;
document.getElementById('databaseInputField').value = store.get('serverConfigStore').databaseName;
document.getElementById('userInputField').value = store.get('serverConfigStore').user;
//Make sure that authentication mode is one of the two possible values (instead a poweruser changes the config file manually...)
if (store.get('serverConfigStore').authenticationMode == "Windows Authentication" || store.get('serverConfigStore').authenticationMode == "SQL Server Authentication") {
document.getElementById('authenticationModeOptionField').value = store.get('serverConfigStore').authenticationMode;
} else {
document.getElementById('authenticationModeOptionField').value = "Windows Authentication";
}
showOrHideUserPWFields();
};
// When the user clicks on <span> (x), close the modal
// span.onclick = function() {
// modal.style.display = "none";
// };
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
function testServerConfigFunction() {
console.log("The test server config button was clicked.");
document.getElementById('OutputTestServerConnection').innerHTML = 'Wait for database response...';
const sql = require('mssql/msnodesqlv8');
var authOption = '' + document.getElementById('authenticationModeOptionField').value;
var trustedAuthBool = false;
if (authOption == 'Windows Authentication') {
trustedAuthBool = true;
}
var config;
//if trustedAuthBool is true, then WindowsAuthentification should be used (no User+PW)
if (trustedAuthBool) {
config = {
user: 'Win User',
password: 'Win User',
server: '' + document.getElementById('serverInputField').value,
database: '' + document.getElementById('databaseInputField').value,
port: parseInt(document.getElementById('serverPortInputField').value, 10),
options: {
trustedConnection: "yes"
}
};
}
//else SQL Server Authentification is available (User+PW needed)
else {
config = {
user: '' + document.getElementById('userInputField').value,
password: '' + document.getElementById('passwordInputField').value,
server: '' + document.getElementById('serverInputField').value,
database: '' + document.getElementById('databaseInputField').value,
port: parseInt(document.getElementById('serverPortInputField').value, 10)
};
}
// async function invocation - connect to db and try a query
queryDatabase(config, 'Select TOP(1) ReleaseVersion FROM [MetadataZone].[TEDAMOHExMeXRelease] Order by ReleaseInstalledDate DESC')
.then(result => {
var obj = JSON.parse(JSON.stringify(result.recordsets[0]));
console.log('Connection succesful! Your last installed ExMeX Version is: ' + obj[0].ReleaseVersion);
const {
remote,
ipcRenderer
} = require('electron');
ipcRenderer.send('setInstalledExmexVersion', '' + obj[0].ReleaseVersion);
var s = obj[0].ReleaseVersion;
if ((s.match(/2.12.*/)) || (s.match(/2.11.*/)) || (s.match(/2.10.*/)) || (s.match(/2.9.*/)) || (s.match(/2.8.*/)) || (s.match(/2.7.*/)) || (s.match(/2.6.*/)) || (s.match(/2.5.*/))) {
swal('Old ExMeX Version installed', 'On the connected database the latest installed ExMeX Version is lower than 2.13.* ! The companion App will not work stable in all features! Please install the latest ExMeX release.', 'warning');
}
//document.getElementById('footer_signature').innerHTML = "ExMeX Version: " + obj[0].ReleaseVersion;
actualizeVersionInfo('footer_signature');
})
.catch(err => {
sql.close();
console.log("A connection error happened");
document.getElementById('OutputTestServerConnection').innerHTML = 'An error occurred while trying to query the database. The detailed error message is: ' + err.message;
});
// async function invocation - connect to db and try a query
queryDatabase(config, 'SELECT SUSER_NAME() as LoggedInUser;')
.then(result => {
var obj = JSON.parse(JSON.stringify(result.recordsets[0]));
console.log('Connection succesful! Your SysUsername is: ' + obj[0].LoggedInUser);
const {
remote,
ipcRenderer
} = require('electron');
modal.style.display = "none";
var sysusername = obj[0].LoggedInUser;
saveServerConfigFunction(config, sysusername);
})
.catch(err => {
sql.close();
console.log("A connection error happened");
document.getElementById('OutputTestServerConnection').innerHTML = 'An error occurred while trying to query the database. The detailed error message is: ' + err.message;
});
}
//needed to delete some parts here for question length
I hope this is something where you can follow the code and give me an advise, on how to change my electron code to get the require function working on my tabs.
Best wishes!

Can't delete newly created list item without refreshing the page and trying again ES6

Some context: I'm trying to finish building out the delete functionality of my minimal note-taking app.
Every time I create a new note, it will appear at the end of my list of notes. However, if I try to delete the newly created note, it won't work. I have to refresh the page and try again for it to work.
I keep getting these two errors:
"Uncaught TypeError: Cannot read property 'parentNode' of null at HTMLUListElement."
"DELETE http://localhost:3000/api/v1/notes/undefined 404 (Not Found)"
Otherwise, I'm able to delete any other note with no problem.
Here is my js code:
// display list of notes on the side
const noteContainer = document.querySelector(".column is-one-quarter")
const noteList = document.querySelector(".menu-list")
fetch('http://localhost:3000/api/v1/notes')
.then(function(response) {
return response.json();
})
.then(function(notes) {
notes.forEach(function(note) {
noteList.innerHTML += `<li id="list-item" data-id=${note.id}><a id="note" data-id=${note.id} class="menu-item">${note.title}</a><i id="delete" data-id=${note.id} class="fas fa-minus-circle has-text-grey-light hvr-grow"></i></li>`
})
})
// display details of each note
const noteDetail = document.querySelector(".note-detail")
noteList.addEventListener('click', function(event) {
if (event.target.className === "menu-item") {
fetch(`http://localhost:3000/api/v1/notes/${event.target.dataset.id}`)
.then(function(response) {
return response.json()
})
.then(function(note) {
noteDetail.innerHTML = `<h1 contenteditable="true" id="title" data-id=${note.id} class="subtitle is-2">${note.title}</h1><p contenteditable="true" id="body" data-id=${note.id} class="subtitle is-6">${note.body}</p><a id="save" data-id=${note.id} class="button is-small">Save</a>`
})
}
})
// i should be able to edit the title and body of a note when i click
// on it and it should save when i click on the button.
noteDetail.addEventListener('click', function(event) {
if (event.target.id === "save") {
const noteId = event.target.dataset.id
const editTitleInput = document.querySelector(`h1[data-id="${noteId}"]`)
const editBodyInput = document.querySelector(`p[data-id="${noteId}"]`)
const singleNote = document.querySelector(`a[data-id="${noteId}"]`)
fetch(`http://localhost:3000/api/v1/notes/${noteId}`, {
method: "PATCH",
headers: {
'Content-Type': 'application/json',
'Accepts': 'application/json'
},
body: JSON.stringify({
title: editTitleInput.innerText,
body: editBodyInput.innerText
})
}).then(function(response) {
return response.json()
}).then(function(note) {
singleNote.innerText = editTitleInput.innerText
})
}
})
// when i click on the button, a form with a title and body input
// should display on the right.
const newNoteButton = document.querySelector("#create")
newNoteButton.addEventListener('click', function(event) {
fetch("http://localhost:3000/api/v1/notes")
.then(function(response) {
return response.json()
})
.then(function(note) {
noteDetail.innerHTML = `<input id="title" class="input subtitle is-5" type="text" placeholder="Title">
<textarea id="body" class="textarea subtitle is-5" placeholder="Body" rows="10"></textarea><a id="add" class="button has-text-black" style="margin-left: 594px;">Add Note</a>`
// when i click on 'add button', a new note with a title and body
// should be created and added to the list of notes.
const noteTitleInput = document.querySelector("#title")
const noteBodyInput = document.querySelector("#body")
const addNoteButton = document.querySelector("#add")
addNoteButton.addEventListener('click', function(event) {
// event.preventDefault()
fetch('http://localhost:3000/api/v1/notes', {
method: "POST",
headers: {
'Content-Type': 'application/json',
'Accepts': 'application/json'
},
body: JSON.stringify({
title: noteTitleInput.value,
body: noteBodyInput.value
})
}).then(function(response) {
return response.json()
}).then(function(note) {
noteList.innerHTML += `<li data-id=${note.id}><a id="note" data-id=${note.id} class="menu-item">${note.title}</a><i id="delete" class="fas fa-minus-circle has-text-grey-light hvr-grow"></i></li>`
})
})
})
})
// i should be able to delete a note when i click on the button.
noteList.addEventListener('click', function(event) {
// event.preventDefault()
if (event.target.id === "delete") {
const noteId = event.target.dataset.id
// const noteListItem = document.querySelector("#list-item")
const noteListItem = document.querySelector(`li[data-id="${noteId}"]`)
const singleNote = document.querySelector(`a[data-id="${noteId}"]`)
fetch(`http://localhost:3000/api/v1/notes/${noteId}`, {
method: "DELETE",
})
// debugger
// lastNote = noteList.lastElementChild
// noteList.removeChild(lastNote)
// singleNote.parentElement.remove()
noteListItem.parentNode.removeChild(noteListItem)
noteDetail.innerHTML = ""
}
})
Here is my html code:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css">
<link href="css/hover.css" rel="stylesheet" media="all">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<link rel="stylesheet" href="css/note.css">
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1 class="title is-1">Jot</h1>
<div class="columns">
<div class="column is-one-quarter">
<p class="menu-label" style="font-size:15px;">
Notes <i id="create" class="fas fa-plus-circle has-text-grey-light hvr-grow" style="margin-left: 10px; width: 20px; height: 30px; font-size: 24px;"></i>
</p>
<ul class="menu-list">
</ul>
</div>
<div class="column is-three-fifths">
<div class="note-detail">
</div>
</div>
<div class="column">
</div>
</div>
<script src="index.js"></script>
</body>
</html>
Any help would be greatly appreciated. :)
You're nesting strings on these two lines:
const noteListItem = document.querySelector(`li[data-id="${noteId}"]`)
const singleNote = document.querySelector(`a[data-id="${noteId}"]`)
Your template literal is creating a string and you're putting that inside of quotes. For example, if your noteId is say 12. your code is ending up like this:
const noteListItem = document.querySelector("li[data-id="'12'"]")
const singleNote = document.querySelector("a[data-id="'12'"]")
I'm not 100% sure that's your issue but it's the first thing that popped out to me.
You can check out MDN to brush up on your Template literals (Template strings).

POST https://stitch.mongodb.com/api/client/v2.0/app/facebookclone-tlwvi/functions/call 403 ()

Error:
MongoDB Users:
Screenshot of permitted users.
When I try to delete a document from MongoDB database deployed on Atlas, Forbidden error occurs. (Inserting works fine). Database name is- FbUsers,
Collection- ClonedFbUsers
Below is the code:
<!DOCTYPE html>
<html>
<head>
<title>myFb</title>
<link rel="stylesheet" type="text/css" href="style1.css">
<script src="https://s3.amazonaws.com/stitch-
sdks/js/library/v3/stable/stitch.min.js"></script>
<script>
let db;
let itemsCollection;
let stClient;
let clientPromise = stitch.StitchClientFactory.create('facebookclone-
tlwvi');
function onLoadConnectDB(){
clientPromise.then(stitchClient=>{
stClient=stitchClient;
db = stClient.service('mongodb', 'mongodb-atlas').db('FbUsers');
itemsCollection=db.collection("ClonedFbUsers");
});
}
function addUser(){
var n= prompt("Your username: ")
const userId = stClient.authedId();
stClient.login().then(()=>
itemsCollection.insertOne({ owner_id: stClient.authedId(), userName : n
, profilePhoto: "NULL", photos: ["NULL"],comments:
[{msg:"NULL",time:"NULL",like:0}] })
).then(() => itemsCollection.find({}).execute())
.then(docs =>
docs.forEach((doc, index) =>
console.log(`${index}: ${JSON.stringify(doc)}`)
)
);
alert("added");
}
function deleteUser(){
var d= prompt("Username to delete: ");
const userId = stClient.authedId();
stClient.login().then(()=>
itemsCollection.deleteOne({ userName: {$eq: d} })
).then(() => itemsCollection.find({}).execute())
.then(docs =>
docs.forEach((doc, index) =>
console.log(`${index}: ${JSON.stringify(doc)}`)
)
);
alert("User "+d+ " deleted.");
}
</script>
</head>
<body onload="onLoadConnectDB()">
<p>Hello My App</p>
<div id="wlcom" align="center">
<button name="adding" onclick="addUser()">Add User</button><br>
<button name="deleting" onclick="deleteUser()">Delete User</button> <br>
<button name="logging">Login</button><br>
</div>
</body>
</html>`
Spent many hours on the MongoDB user authentication, built-in roles etc which seems like less useful. Any help is appreciated

Categories

Resources