I'm creating a chat but I was inspired by a source, when I "Log-In" and the chat appears, this appears in the URL:
chat.html?username=rr&room=JavaScript
How do I make sure that when I enter the chat it simply sees "Chat.html"?
I tried to add this code to it, but the problem would be the same if someone changed, it's like it's a GET. How do I do it in POST? It doesn't come easy with javascript
Code:
const chatForm = document.getElementById('chat-form');
const chatMessages = document.querySelector('.chat-messages');
const roomName = document.getElementById('room-name');
const userList = document.getElementById('users');
// Get username and room from URL
const { username, room } = Qs.parse(location.search, {
ignoreQueryPrefix: true,
});
const socket = io();
socket.emit('joinRoom', { username, room });
socket.on('roomUsers', ({ room, users }) => {
outputRoomName(room);
outputUsers(users);
});
socket.on('message', (message) => {
console.log(message);
outputMessage(message);
chatMessages.scrollTop = chatMessages.scrollHeight;
});
chatForm.addEventListener('submit', (e) => {
e.preventDefault();
let msg = e.target.elements.msg.value;
msg = msg.trim();
if (!msg) {
return false;
}
socket.emit('chatMessage', msg);
// Clear input
e.target.elements.msg.value = '';
e.target.elements.msg.focus();
});
// Output message to DOM
function outputMessage(message) {
const div = document.createElement('div');
div.classList.add('message');
const p = document.createElement('p');
p.classList.add('meta');
p.innerText = message.username;
p.innerHTML += `<span> - ${message.time}</span>`;
div.appendChild(p);
const para = document.createElement('p');
para.classList.add('text');
para.innerText = message.text;
div.appendChild(para);
document.querySelector('.chat-messages').appendChild(div);
}
function outputRoomName(room) {
roomName.innerText = room;
}
function outputUsers(users) {
userList.innerHTML = '';
users.forEach((user) => {
const li = document.createElement('li');
li.innerText = user.username;
userList.appendChild(li);
});
}
document.getElementById('leave-btn').addEventListener('click', () => {
const leaveRoom = confirm('Sei sicuro di voler uscire dalla chatroom?');
if (leaveRoom) {
window.location = '../index.html';
} else {
}
});
I hope I have explained myself well, I just need to add security to the website because then they could enter random "rooms", could I put the sessions?
Related
I'm new to async and await. I'm working on a recipe website using an api and fetch. need help to add async await to the fetch. I'm using spoonacular api.
there are no errors just want to add async await.
function retrieve(e) {
newsList.innerHTML = "";
e.preventDefault();
const apiKey = "my api key";
let topic = input.value;
let url = `https://api.spoonacular.com/recipes/complexSearch?query=${topic}&apiKey=${apiKey}&cuisine=&fillIngredients=false&addRecipeInformation=true&maxReadyTime=120&ignorePantry=flase&number=20&intolerances=gluten&sourceUrl=http://www.foodista.com`;
fetch(url)
.then((res) => {
return res.json();
})
.then((data) => {
console.log(data);
data.results.forEach((results) => {
let li = document.createElement("li");
let a = document.createElement("a");
let div = document.createElement("div");
let img = document.createElement("img");
let btn = document.createElement("button");
// styling
div.className = "newsdiv";
img.className = "newsimg";
btn.className = "btns";
li.style.width = "300px";
a.setAttribute("href", results.sourceUrl);
a.setAttribute("target", "_blank");
img.setAttribute("src", results.image);
div.textContent = results.title;
// btn.prepend(br);
div.appendChild(a);
div.prepend(img);
li.prepend(div);
btn.textContent = "Get Recipe";
div.appendChild(btn);
a.appendChild(btn);
newsList.appendChild(li);
});
})
.catch((error) => {
console.log(error);
});
}
Look at below snippet. This will be useful to your solution. In the function you may do whatever operations you want.
const retrieve = async (e) => {
newsList.innerHTML = "";
e.preventDefault();
const apiKey = "my api key";
let topic = input.value;
let url = `https://api.spoonacular.com/recipes/complexSearch?query=${topic}&apiKey=${apiKey}&cuisine=&fillIngredients=false&addRecipeInformation=true&maxReadyTime=120&ignorePantry=flase&number=20&intolerances=gluten&sourceUrl=http://www.foodista.com`;
const response = await fetch(url);
const myJson = await response.json(); //extract JSON from the http response
console.log(myjson);
}
retrieve(null);
I'm trying to have some sort of real-time dashboard that can subscribe to AWS IoT core topics and maybe publish too.
I have found a couple of items online, but I can't figure it out.
This is what I currently have:
function p4(){}
p4.sign = function(key, msg) {
const hash = CryptoJS.HmacSHA256(msg, key);
return hash.toString(CryptoJS.enc.Hex);
};
p4.sha256 = function(msg) {
const hash = CryptoJS.SHA256(msg);
return hash.toString(CryptoJS.enc.Hex);
};
p4.getSignatureKey = function(key, dateStamp, regionName, serviceName) {
const kDate = CryptoJS.HmacSHA256(dateStamp, 'AWS4' + key);
const kRegion = CryptoJS.HmacSHA256(regionName, kDate);
const kService = CryptoJS.HmacSHA256(serviceName, kRegion);
const kSigning = CryptoJS.HmacSHA256('aws4_request', kService);
return kSigning;
};
function getEndpoint() {
const REGION = "eu-west-1";
const IOT_ENDPOINT = "blablablabla-ats.iot.eu-west-1.amazonaws.com";
// your AWS access key ID
const KEY_ID = "My-key";
// your AWS secret access key
const SECRET_KEY = "my-access-token";
// date & time
const dt = (new Date()).toISOString().replace(/[^0-9]/g, "");
const ymd = dt.slice(0,8);
const fdt = `${ymd}T${dt.slice(8,14)}Z`
const scope = `${ymd}/${REGION}/iotdevicegateway/aws4_request`;
const ks = encodeURIComponent(`${KEY_ID}/${scope}`);
let qs = `X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=${ks}&X-Amz-Date=${fdt}&X-Amz-SignedHeaders=ho
const req = `GET\n/mqtt\n${qs}\nhost:${IOT_ENDPOINT}\n\nhost\n${p4.sha256('')}`;
qs += '&X-Amz-Signature=' + p4.sign(
p4.getSignatureKey( SECRET_KEY, ymd, REGION, 'iotdevicegateway'),
`AWS4-HMAC-SHA256\n${fdt}\n${scope}\n${p4.sha256(req)}`
);
return `wss://${IOT_ENDPOINT}/mqtt?${qs}`;
}
// gets MQTT client
function initClient() {
const clientId = Math.random().toString(36).substring(7);
const _client = new Paho.MQTT.Client(getEndpoint(), clientId);
// publish method added to simplify messaging
_client.publish = function(topic, payload) {
let payloadText = JSON.stringify(payload);
let message = new Paho.MQTT.Message(payloadText);
message.destinationName = topic;
message.qos = 0;
_client.send(message);
}
return _client;
}
function getClient(success) {
if (!success) success = ()=> console.log("connected");
const _client = initClient();
const connectOptions = {
useSSL: true,
timeout: 3,
mqttVersion: 4,
onSuccess: success
};
_client.connect(connectOptions);
return _client;
}
let client = {};
function init() {
client = getClient();
client.onMessageArrived = processMessage;
client.onConnectionLost = function(e) {
console.log(e);
}
}
function processMessage(message) {
let info = JSON.parse(message.payloadString);
const publishData = {
retailer: retailData,
order: info.order
};
client.publish("sc/delivery", publishData);
}
$(document).ready(() => {
init();
client.subscribe("sc/orders/");
});
I keep getting the same error; AMQJS0011E Invalid state not connected., but I do see in the requests pane of chrome that there is an connection or so... What am I doing wrong here?
I don't see any of the logs anyhow...
I am trying to add the link on the image or title. when I click on the image/text it should take me to another page index.html.
How can I do that?
const apiUrl = 'https://api.themoviedb.org/3/discover/movie
sort_by=popularity.desc&api_key=04c35731a5ee918f014970082a0088b1&page=1;
const IMGPATH = "https://image.tmdb.org/t/p/w1280";
const SEARCHAPI = "https://api.themoviedb.org/3/search/movie?
&api_key=04c35731a5ee918f014970082a0088b1&query=";
const main = document.getElementById("main");
const form = document.getElementById("form");
const search = document.getElementById("search");
showMovies(apiUrl);
function showMovies(url){
fetch(url).then(res => res.json())
.then(function(data){
console.log(data.results);
data.results.forEach(element => {
const el = document.createElement('div');
const image = document.createElement('img');
const text = document.createElement('h2');
text.innerHTML = `${element.title}`;
image.src = IMGPATH + element.poster_path;
el.appendChild(image);
el.appendChild(text);
main.appendChild(el);
});
});
}
form.addEventListener("submit", (e) => {
e.preventDefault();
main.innerHTML = '';
const searchTerm = search.value;
if (searchTerm) {
showMovies(SEARCHAPI + searchTerm);
search.value = "";
}
});
Fixed your code, the tick was to add a element instead of with the desired href
const apiUrl =
"https://api.themoviedb.org/3/discover/moviesort_by=popularity.desc&api_key=04c35731a5ee918f014970082a0088b1&page=1";
const IMGPATH = "https://image.tmdb.org/t/p/w1280";
const SEARCHAPI =
"https://api.themoviedb.org/3/search/movie? &api_key=04c35731a5ee918f014970082a0088b1&query=";
const main = document.getElementById("main");
const form = document.getElementById("form");
const search = document.getElementById("search");
showMovies(apiUrl);
function showMovies(url) {
fetch(url)
.then((res) => res.json())
.then(function (data) {
console.log(data.results);
data.results.forEach((element) => {
el = document.createElement("a");
el.href = "https://example.com"
const image = document.createElement("img");
const text = document.createElement("h2");
text.innerHTML = `${element.title}`;
image.src = IMGPATH + element.poster_path;
el.appendChild(image);
el.appendChild(text);
main.appendChild(el);
});
});
}
form.addEventListener("submit", (e) => {
e.preventDefault();
main.innerHTML = "";
const searchTerm = search.value;
if (searchTerm) {
showMovies(SEARCHAPI + searchTerm);
search.value = "";
}
});
Im working on a voice recognition system where a voice command can pull up NASA's Astronomy Picture of the Day through their NASA API. I've made some simple code just to test it out by saying "Check Steve" and it'll check the check box named Steve. However when I say "Astronomy Picture of the Day", it returns "undefined" rather than the picture or text from the NASA API. Why is that?
var message = document.querySelector('#message');
var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition;
var SpeechGrammarList = SpeechGrammarList || webkitSpeechGrammarList;
var grammar = '#JSGF V1.0;'
var recognition = new SpeechRecognition();
var speechRecognitionList = new SpeechGrammarList();
speechRecognitionList.addFromString(grammar, 1);
recognition.grammars = speechRecognitionList;
recognition.lang = 'en-US';
recognition.interimResults = false;
recognition.onspeechend = function() {
recognition.stop();
};
recognition.onerror = function(event) {
message.textContent = 'Error occurred in recognition: ' + event.error;
}
document.querySelector('#btnGiveCommand').addEventListener('click', function(){
recognition.start();
sendApiRequest()
});
async function sendApiRequest(){
let API_KEY = "7RTzkUMJOC8QYxM4COFoVha8NvAhxcZH2Ca7Px0G"
let response = await fetch(`https://api.nasa.gov/planetary/apod?api_key=${API_KEY}`);
console.log(response)
let event = await response.json()
console.log(event)
// how do i call the line of code right below this comment to this function?
}
recognition.onresult = function(event) {
var last = event.results.length - 1;
var command = event.results[last][0].transcript;
message.textContent = 'Voice Input: ' + command + '.';
if(command.toLowerCase() === 'astronomy picture of the day'){
document.querySelector("#chkSteve").innerHTML = event.explanation
}
else if (command.toLowerCase() === 'select tony'){
document.querySelector('#chkTony').checked = true;
}
else if (command.toLowerCase() === 'select bruce'){
document.querySelector('#chkBruce').checked = true;
}
else if (command.toLowerCase() === 'select nick'){
document.querySelector('#chkNick').checked = true;
}
}
I'm creating an application (chat app) and I'm pushing each username to an array. Using socket.io, whenever I call an event to push the username to the client side array, multiple instances of the array are created.
For example, the first user I log is fine, Then when another user is added, the array will double, then triple and so on. Thank you in advance for the help . The emit event in which I'm doing this is in the USERS_CONNECTED event.
I am also sorry for the terrible sloppiness of the code below.
Server
const express = require('express');
const fs = require('fs');
const path = require('path');
const http = require('http');
const socketIO = require('socket.io');
const publicPath = path.join(__dirname, 'public');
const port = process.env.PORT || 3001;
let app = express();
let server = http.createServer(app);
var io = socketIO(server);
let username;
app.use(express.static(publicPath));
let usersOnline = []; //keeps track of current users online
io.on('connection', (socket) => {
let user = socket.id;
socket.emit('user', user);
socket.id = "anon";
socket.on('new user', function(data,callback) {
//if user name is taken
if(usersOnline.indexOf(data) != -1 || data == ''){
callback(false);
}else{
//if username is not taken
callback(true);
socket.id = data;
username = data;
//pushes data(username) to data
usersOnline.push(socket.id);
//sends back to client usersOnline array
io.sockets.emit('USERS_CONNECTED', {usersOnline: usersOnline, user: socket.id});
console.log(usersOnline.length)
}
});
socket.on('disconnect', () => {
usersOnline.splice(usersOnline.indexOf(socket.id), 1);
//emits count users, sets current user
io.sockets.emit('USERS_CONNECTED', {usersOnline: usersOnline, user: socket.id});
console.log(usersOnline.length)
});
socket.on('send msg' , function(data){
io.sockets.emit('send msg', {msg: data, user: socket.id});
})
});
server.listen(port, () => {
console.log('server is running master')
});
Client
let socket = io();
let input = document.querySelector('#input_username');
let form = document.querySelector('form')
let userName_page = document.querySelector(".userName_page");
let chat_page = document.querySelector(".chat_page");
let chatWrapper = document.querySelector(".chat_wrapper")
let counter = document.getElementById("counter");
let users = document.querySelector(".users_online")
let join_btn = document.querySelector(".button-effect")
let msg_input = document.querySelector("#sendMsg");
let btn_send = document.querySelector("#send_btn");
let onlineUsers = [];
let sent_ = document.querySelector(".sent_");
let receive_ = document.querySelector(".receive_");
let newUser_text = document.querySelector(".welcome_box")
let user;
let isTyping = document.querySelector('#isTyping')
let welcome_header = document.querySelector("#welcome_header");
let users_online_container = document.querySelector(".users_online");
join_btn.addEventListener("click", function(e){
e.preventDefault();
user = input.value;
//sets user name to input.value
socket.emit('new user', input.value, function(data){
if(data){
userName_page.style.display = "none"
chat_page.style.display = "flex";
welcome_header.innerHTML = input.value + ' has joined the party';
addAnimation();
}else{
if(input.value == ''){
input.classList.add("input_error");
let error_msg = document.getElementById('error_input');
error_msg.innerHTML = '*Invalid, Please Type a Username'
error_msg.style.display = "block";
input.style.border = "2px solid #d9534f";
}else{
input.classList.add("input_error");
let error_msg = document.getElementById('error_input');
error_msg.style.display = "block";
error_msg.style.border = "2px solid #d9534f"
error_msg.innerHTML = "Woops, sorry but that user name is already taken, please try again";
}
}
});
//sets up new user
socket.on('USERS_CONNECTED' , function (data){
//counts online users currently
counter.innerHTML = (data.usersOnline.length + " Online");
for(let i = 0; i < data.usersOnline.length; i++){
onlineUsers.push(data.usersOnline);
let h = document.createElement("h3");
fish.appendChild(h);
}
console.log(onlineUsers)
});
});
//msg send
btn_send.addEventListener('click', function(){
socket.emit('send msg', msg_input.value);
});
//checks if enter is pressed, if so emits message to chat
function search(ele) {
if(event.key === 'Enter') {
socket.emit('send msg', msg_input.value);
}
}
//send message events
socket.on('send msg', function(data){
if(data.user == user){
//sender logic
msg_input.value = '';
let p = document.createElement('p');
receive_.append(p);
p.innerHTML = "<span class = 'er'>" + 'You' + "</span>" + ": " + data.msg;
p.style.textAlign = 'right';
p.style.backgroundColor = "#5cb85c";
p.style.justifyContent = "flex-end";
p.style.paddingRight = "2em";
}
else{
//receiver logic
msg_input.value = '';
let p = document.createElement('p');
receive_.append(p);
p.innerHTML = "<span class = 'er'>" + data.user + "</span>" + ": " + data.msg;
p.style.textAlign = 'left';
p.style.backgroundColor = "#5bc0de";
p.style.paddingLeft = "2em";
};
//makes sure scroll stays at bottom
receive_.scrollTop = receive_.scrollHeight;
});
function addAnimation(){
newUser_text.classList.add("act");
}
$( document ).ready(function(){
let header = document.querySelector(".feedback");
var timeout;
function timeoutFunction() {
typing = false;
socket.emit("typing", false);
}
$('#sendMsg').keyup(function() {
typing = true;
socket.emit('typing', 'typing...');
clearTimeout(timeout);
timeout = setTimeout(timeoutFunction, 5000);
});
socket.on('typing', function(data) {
if (data) {
$('#isTyping').html(data);
$('#isTyping').classList.add('act')
} else {
$('#isTyping').html("");
}
});
})
You should replace whole array on client side instead of push. Just stack trace your code:
Firstable on connection on server side you pushes new user id to usersOnline array and emits that array in object via USERS_CONNECTED event in usersOnline property. Client receives that object and pushes object of users (NOT exactly one new user) to onlineUsers array. So eg. 1 user connects to server, usersOnline array would be:
[ 'user1' ]
Then second user connects to server:
[ 'user1', 'user2' ]
And that array is being sent to user2, that is whole object sent by USERS_CONNECTED event would be:
{ usersOnline: [ 'user1', 'user2' ], user: 'user2' }
Now in client instead of replacing you are pushing whole new array, so instead [ 'user1', 'user2' ] you gets [ [ 'user1', 'user2' ] ]