How do I adapt a javascript to use a database input? - javascript

I am a novice Java/CSS/HTML user with a background using SQL. For a personal website project, I want to connect a webpage i am building to a database list of questions. Currently, the questions I am using are just written in the javacode like such:
const questions = [{
question: 'What is 2 + 2?',
answers: [
{ text: '4', correct: true },
{ text: '22', correct: false },
{ text: '2.2', correct: false },
{ text: '57', correct: false }
]
},
{
question: 'What is the captial of Russia?',
answers: [
{ text: 'Helsinki', correct: false },
{ text: 'St Petersburg', correct: false },
{ text: 'Moscow', correct: true },
{ text: 'Sainsburys', correct: false }
]
},
{
question: 'How many sides does a nonagon have',
answers: [
{ text: 'As many as it wants', correct: false },
{ text: 'Nine', correct: true },
{ text: 'Seven', correct: false },
{ text: 'Twelve', correct: false }
]
},
{
question: 'What is 4 * 2?',
answers: [
{ text: '6', correct: false },
{ text: '8', correct: true },
{ text: '10', correct: false },
{ text: '12', correct: false }
]
}
]
Instead of using this hideous list, I would like to use a connection to information I have in a amazon-DynamoDB database which has 50 or so questions listed.
My question is:
What would replace the code above to create a connection to the database and to use the new data the same way?
I can reformat the sql database data to have columns: Question, Answer, Correct? in preperation
Any help would be fantastic, I've gone a bit off grid from the training material I was using!
removed question about looking for a database recommendation

Related

How to group by 2 columns, but have the values on the same row

Not sure how to exactly explain this in words, but I think with a couple of examples it will make sense
In this first example, I am grouping by just one column, location. In the location fields, I am using spaces in the path, ie location: ['Home', ''], (1 space), location: ['Home', ' '], (2 spaces) so I can have 2 other columns as "details" of the main row (ie in this example cleaner type and cleaner weight)
It looks like this:
Perhaps there is a better way to do this, but this would work in the above if I just wanted to group by the one column.
However, I actually want to group by two columns, but only have those 2 detail (child) records "nested").
In the above, I also want to group by the room, but NOT have room as a nested row.
So, in the above I have (location=Home, room=room1), but I may also have (location=Home, room=room2), ie I have room2
eg would like like this:
I have tried all sorts of things, but just cannot get this view (I always end up with unwanted nestings), eg this is what I don't want:
Plnkr link
Is there a way to do this sort of view?
I found the way to do this from this post.
So in this example, you can use a completely different property not shown in the grid at all for getDataPath to control the grouping, and then use valueGetter to put what you want in the grouped column.
So I can have the following....
var gridOptions = {
columnDefs: [
// we're using the auto group column by default!
{ field: 'room',resizable: true, },
{ field: 'cleanertype', resizable: true, },
{ field: 'cleanerweight',aggFunc: 'sum', resizable: true, },
{ field: 'totalweight', resizable: true, },
],
defaultColDef: {
flex: 1,
},
autoGroupColumnDef: {
headerName: 'location',
sortable: true,
resizable: true,
filter: 'agTextColumnFilter',
valueGetter: (params) => {
return params.node.data.location; // <--- what to show in the group column
},
cellRendererParams: {
suppressCount: true,
},
},
rowData: rowData,
treeData: true, // enable Tree Data mode
animateRows: true,
groupDefaultExpanded: -1, // expand all groups by default
getDataPath: function (data) {
return data.grouping; // <= how to group/nest
},
};
and the data...
var rowData = [
// Home/room1
{
grouping: ['1'],
location: 'Home',
room: 'room1',
cleanertype: '',
totalweight: 60
},
{
grouping: ['1', '1'],
cleanertype: 'type1',
cleanerweight:10,
},
{
grouping: ['1', '2'],
cleanertype: 'type2',
cleanerweight:10,
},
// Home/room2
{
grouping: ['2'],
location: 'Home',
room: 'room2',
cleanertype: '',
totalweight: 60
},
{
grouping: ['2', '1'],
cleanertype: 'type1',
cleanerweight:10,
},
{
grouping: ['2', '2'],
cleanertype: 'type2',
cleanerweight:10,
},
{
grouping: ['3'],
location: 'Work',
room: 'room1',
cleanertype: '',
cleanerweight: 30,
totalweight: 60
},
{
grouping: ['3', '1'],
cleanertype: 'general',
cleanerweight:10,
},
{
grouping: ['3', '2'],
cleanertype: 'heavyduty',
cleanerweight: 10,
},
];
So I am using grouping to control the grouping/nesting, and works perfectly, and is exactly what I was after.
Can see the working example here.

JQuery quiz app not resetting to show the next answer

I have a math app in JavaScript/JQuery, there will be a timer that gives the user 3 seconds to answer math questions given to them at random, if they don't answer in 3 seconds the user will lose. I can't get the next random question to display when the user selects the right answer.
I put all of the questions in an array of objects. Then I created a function that takes a random Math function as the parameter. The random function randomly picks between the indices in the array of objects.
I thought by calling this random function again in my selectAnswer() that it would reset the information fr the current question and display the next question at random. But it's only appending the current question again..
I am a beginner so my code might not be th greatest! I'm open to any insight!!
You'll also notice, that the event to reload the page when the start over button is clicked is not firing correctly. I'm working on that.
const questions = [
{
question: '80 * 20',
answ: 80 * 20,
answers: [
{ text: 1600 },
{ text: -1600 },
{ text: 16 },
{ text: 160 },
]
},
{
question: '80 / 20',
answ: 80 / 20,
answers: [
{ text: '-4', correct: false },
{ text: '50', correct: false },
{ text: '4', correct: true },
{ text: '40', correct: false },
]
},
{
question: '80 + 20',
answ: 80 + 20,
answers: [
{ text: '-100', correct: false },
{ text: '1000', correct: false },
{ text: '10', correct: false },
{ text: '100', correct: true },
]
},
{
question: '80 - 20',
answ: 80 - 20,
answers: [
{ text: '66', correct: false },
{ text: '60', correct: true },
{ text: '600', correct: false },
{ text: '20', correct: false },
]
},
{
question: '8 * -2',
answ: 8 * -2,
answers: [
{ text: '66', correct: false },
{ text: '666', correct: false },
{ text: '-16', correct: true },
{ text: '16', correct: false },
]
},
{
question: '-2 + 8',
answ: -2 + 8,
answers: [
{ text: '-6', correct: false },
{ text: '66', correct: false },
{ text: '600', correct: false },
{ text: '6', correct: true },
]
},
{
question: '14 - 66',
answ: 14 - 66,
answers: [
{ text: '52', correct: false },
{ text: '54', correct: false },
{ text: '-52', correct: true },
{ text: '-54', correct: false },
]
},
{
question: '103 * 33',
answ: 103 * 33,
answers: [
{ text: '3502', correct: true },
{ text: '3509', correct: false },
{ text: '3503', correct: false },
{ text: '3507', correct: false },
]
},
{
question: '165 / 33',
answ: 165 / 33,
answers: [
{ text: '33', correct: true },
{ text: '15', correct: false },
{ text: '5', correct: false },
{ text: '25', correct: false },
]
},
{
question: '88 * 28',
answ: 88 * 28,
answers: [
{ text: '2624', correct: false },
{ text: '2462', correct: false },
{ text: '2464', correct: true },
{ text: '2426', correct: false },
]
}
]
$(() => {
// GRABBING HTML ELEMENTS
const $startBtn = $("#start-btn")
const $timeLeft = $("#time-left")
const $quitBtn = $("#quit-btn")
const $secondsLeft = $("#seconds-left")
const $questionContainerElement = $("#question-container")
const $questionElement = $("#question")
const $answerButtonElement = $("#answer-buttons")
$secondsLeft.hide()
$quitBtn.hide()
let $buttons;
let mathAnsw;
// CREATING VARIABLES FOR RANDOM FUNCTION ANCD URRENT QUESTION
let shuffledQuestions, currentQuestionIndex
let timeLeft = 3
// START BUTTON FUNCTIONALITY
// HIDES START MENU WHEN FIRED
// INVOKES RANDOM FUNCTION
$startBtn.click(() => {
$secondsLeft.fadeIn(900)
$quitBtn.fadeIn(900)
$startBtn.fadeOut(900)
// countDown()
console.log("started")
$startBtn.hide()
// SORTS THROUGH THE ARRAY OF QUESTIONS
shuffledQuestions = questions.sort(() => Math.random() - .5)
currentQuestionIndex = 0;
$questionContainerElement.show()
showQuestion(shuffledQuestions[currentQuestionIndex])
mathAnsw = questions[currentQuestionIndex].answ
console.log("the answer", mathAnsw)
})
// NEXT BUTTON FUNCTIONALITY
// INVOKES SHOWQUESTION() EVERYTIME FIRED
const setNext = () => {
showQuestion(question)
console.log(questions)
// resetState()
}
$quitBtn.click(() => {
location.reload(true)
})
// CURRENT QUESTION
// APPEND CURRENT QUESTION TO THE QUESTION BOX
const showQuestion = (question) => {
$questionElement.append(`<h2 class="text-center">${questions[currentQuestionIndex].question}</h2>`)
console.log(questions[currentQuestionIndex].question)
// POPULATING ANSWERS
const AnswersArray = question.answers
let value
for (x in AnswersArray) {
$buttons = $(`<button id="answer${x}"class="btn" value='${questions[currentQuestionIndex].answers[x].text}'>${questions[currentQuestionIndex].answers[x].text}</button>`)
$answerButtonElement.append($buttons)
}
selectAnswer()
}
// ANSWER
const selectAnswer = () => {
$('.btn').each(function () {
$(this).on("click", function () {
let $value = $(this).attr('value')
let value = Number($value)
console.log(value)
console.log(mathAnsw)
if (value === mathAnsw) {
console.log('correct!!')
showQuestion(shuffledQuestions[currentQuestionIndex])
} else {
$("#question-container").replaceWith("<h1>You Lost</h1>")
$quitBtn.replaceWith("<button id='start-over'>Start Over</button>")
console.log("wrong")
}
})
})
}
$("#start-over").click(() => {
location.reload(true)
console.log("clicked")
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fast Math</title>
<link rel="stylesheet" href="index.css">
<script src="../fast-math/lib/jquery-3.6.0.min.js"></script>
</head>
<body>
<div class="container">
<h3 id="seconds-left">Seconds Left: <span id="time-left"></span></h3>
<div id="question-container" class="hide">
<div id="question">Question</div>
<div id="answer-buttons" class="btn-grid">
</div>
</div>
<div class="controls">
<button id="start-btn" class="start-btn btn">start</button>
<button id="quit-btn" class="quit-btn btn">quit</button>
</div>
</div>
<script src="index.js"></script>
<script src="mathProblems.js"></script>
</body>
</html>

Unable to create Intent properly in dialogflow using v2 api

I am trying to create intent by using example given in this dialogflow-nodejs-client-v2
, But problem is that it creates Intent with phrases. But it does not create action and responses . I have even tried it using exact code given in example here as below
createIntents('myprojectid')
function createIntents(projectId) {
const dialogflow = require('dialogflow');
const contextsClient = new dialogflow.ContextsClient();
const intentsClient = new dialogflow.IntentsClient();
const agentPath = intentsClient.projectAgentPath(projectId);
const pizzaOutputContexts = [
{
name: contextsClient.contextPath(
projectId,
'' / sessionId */,
'pizza_order'
),
lifespanCount: 5,
},
];
const pizzaResult = {
action: 'pizza',
parameters: [
{
displayName: 'size',
value: '$size',
entityTypeDisplayName: '#SiZe',
mandatory: true,
prompts: [
'What size pizza would you like to order?',
'Would you like a large, medium, or small pizza?',
],
},
{
displayName: 'topping',
value: '$topping',
entityTypeDisplayName: '#Topping',
mandatory: true,
prompts: ['What toppings would you like?'],
isList: true,
},
{
displayName: 'address',
value: '$address',
// The API provides a built-in entity type #sys.address for addresses.
entityTypeDisplayName: '#sys.location',
mandatory: true,
prompts: ['What is the delivery address?'],
},
],
messages: [
{
platform: 'PLATFORM_UNSPECIFIED',
text: {
text: [
'No problem. Getting a $size pizza with $topping and delivering ' +
'to $address.',
]
}
},
{
text: {
text: [
'Reply "check" to place your order. Reply "cancel" to cancel ' +
'your order. You can change your delivery address as well.',
]
}
}
],
outputContexts: pizzaOutputContexts,
};
const pizzaPhrases = [
{type: 'EXAMPLE', parts: [{text: 'Order pizza'}]},
{type: 'EXAMPLE', parts: [{text: 'Pizza'}]},
{
type: 'EXAMPLE',
parts: [
{text: 'Get me a '},
{text: 'large', entityType: '#SiZe', alias: 'size'},
{text: ' '},
{text: 'mushrooms', entityType: '#Topping', alias: 'topping'},
{text: ' for '},
{
text: '1 1st st, New York, NY',
entityType: '#sys.location',
alias: 'address',
},
],
},
{
type: 'EXAMPLE',
parts: [
{text: "I'd like to order a "},
{text: 'large', entityType: '#SiZe', alias: 'size'},
{text: ' pizza with '},
{text: 'mushrooms', entityType: '#Topping', alias: 'topping'},
],
},
{
type: 'TEMPLATE',
parts: [{text: "I'd like a #SiZe:size pizza"}],
},
];
const pizzaIntent = {
displayName: 'Pizza',
events: ['order_pizza'],
// Webhook is disabled because we are not ready to call the webhook yet.
webhookState: 'WEBHOOK_STATE_DISABLED',
trainingPhrases: pizzaPhrases,
mlEnabled: true,
priority: 500000,
result: pizzaResult,
};
const pizzaRequest = {
parent: agentPath,
intent: pizzaIntent,
};
intentsClient
.createIntent(pizzaRequest)
.then(responses => {
console.log('Created Pizza intent:');
// logIntent(responses[0]);
})
.catch(err => {
console.error('ERROR:', err);
});
}
above code creates intent but it does not set action name and responses
As i said before it is exactly same code which is given in dialogflow-nodejs-client-v2. SO is it a bug or i am doing something wrong please help

Line separator/break in discord embded

I have the following discord embed:
message.reply({
content: '',
embed: {
color: 11416728,
author: {
name: 'xx know-it-all',
icon_url: 'https://xx.png'
},
description: '',
footer: {
icon_url: client.user.avatarURL,
text: '© xx Network'
},
fields: [
{
name: '1st Line',
value: '2nd Line',
},
{
name: 'MAKE THIS JUST A SPACER',
value: 'MAKE THIS JUST A SPACER',
},
{
name: '5th Line',
value: '6th Line',
}
]
}
})
I am trying to figure out how to create a spacer of sorts. I have tried using a html space, blank space, and alt code space. None of them seem to work. Any ideas on how to accomplish this?
The issue is discord is returning the field as null, so it's not taking it when I use the invisible html space or putting \n
I got it!
All I needed to do was use the C/C++/Java encoding version of the invisible space
\u200B
Reference: https://www.fileformat.info/info/unicode/char/200B/index.htm
This can come into use for other people looking to make embeds look more clear as discord complicates it
Discord.JS has a method .addEmptyField() that uses \u200B to display a empty line.
message.reply({
content: '',
embed: {
color: 11416728,
author: {
name: 'xx know-it-all',
icon_url: 'https://xx.png'
},
description: '',
footer: {
icon_url: client.user.avatarURL,
text: '© xx Network'
},
fields: [
{
name: '1st Line',
value: '2nd Line',
},
{
name: '\u200B',
value: '\u200B',
},
{
name: '5th Line',
value: '6th Line',
}
]
}
})
Appears to be working here.
Interestingly, I figured out you can get around this by using the backspace escape-sequence too:
\b
This is useful if you want your embed fields formatted in a 2 x 2:
fields: [
{
name: 'Field1',
value: 'Value1',
inline: true
},
{
name: 'Field2',
value: 'Value2',
inline: true
},
{
name: '\b',
value: '\b',
inline: true
},
{
name: 'Field3',
value: 'Value3',
inline: true
},
{
name: 'Field4',
value: 'Value4',
inline: true
},
]

Highcharts chart not displaying data from csv file

I am working on a project that is supposed to take csv data that is being written in real time and display it on an html page. I am using Javascript, and the JQuery, HighCharts, and PapaParse libraries.
Here is my JSFiddle with my code: https://jsfiddle.net/m5n8xdo9/3/
I know it doesn't look right, but I don't know how to make it look like it looks on my computer. Should I use a different hosting site?
When I hardcode dummy data into the chart like this:
//Altitude
$(function () {
$('#altGraph').highcharts({
chart: {
type: 'line'
},
title: {
text: 'Payload Altitude'
},
subtitle: {
text: 'Altitude (m) vs. Time (s)'
},
xAxis: {
categories: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
},
yAxis: {
title: {
text: 'Altitude (m)'
}
},
plotOptions: {
line: {
dataLabels: {
enabled: true
},
enableMouseTracking: false
}
},
series: [{
name: 'Altitude',
data: //dummy data here
}]
});
});
it all works and looks nice. But when I use papaparse to parse the csv into arrays of data, and pass an array of data to the corresponding chart like so:
//Altitude
$(function () {
$('#altGraph').highcharts({
chart: {
type: 'line'
},
title: {
text: 'Payload Altitude'
},
subtitle: {
text: 'Altitude (m) vs. Time (s)'
},
xAxis: {
categories: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
},
yAxis: {
title: {
text: 'Altitude (m)'
}
},
plotOptions: {
line: {
dataLabels: {
enabled: true
},
enableMouseTracking: false
}
},
series: [{
name: 'Altitude',
data: altitude
}]
});
});
the charts show up blank.
On my computer, after you choose a file the charts show up, though empty of data points. That's my problem. I was thinking that maybe since the charts are written to the page before the data is uploaded, that would be why the data isn't showing up. I am currently at a loss as to how to fix this.
The problem is that your papaParse convert values to strings in array, instead of numbers. See "dynamicTyping" parameter and then set it as true.

Categories

Resources