Object Not Passing/Fetch-Post Request/API/NodeJS/Browser - javascript

Issue: An object created in JavaScript by input data from a signup form in HTML does not seem to be created.
Tried:
I checked if I was referencing the entire object with {data} rather just data
Searched other online resources to no avail
Read again on JavaScript objects to see if I did a simple mistake
adding debug strings to give me hints (I will list code below)
Relevant Code:
signup.html(each snippet is in top to bottom order):
<form id="signup-form" name ="signup-form">
<input class="login-form-field" type="text" name="user" placeholder="username">
<input class="login-form-field" type="text" name="email" placeholder="email">
<input class="login-form-field" type="password" name="dob" placeholder="date of birth">
<br>
<!--<button class="actionButton"></button>-->
<INPUT TYPE="button" NAME="button" Value="Click" onClick="signupData(this.form)">
</form>
//last of the markup body with Browserify compiled JavaScript files linked for functionality
<script src="browserify/builds/genKey.js"></script>
<script src="browserify/builds/SignUp.js"></script>
<script LANGUAGE="JavaScript">
function signupData(form) // add to this script
{
console.log("signup data is starting");
var user = form.user.value;
var email = form.email.value;
var dob = form.dob.value;
genSKey();
genPKey();
var skey = getSKey();
// var enUser = encryptMes(user);
// var enEmail = encryptMes(email);
var endob = encryptMes(dob);
var data = { name: "LifeNet", members: { user: {profilePic: {}, endob, listeners: {}, listening: {}, friends: {}, requested: {}, blocked:{}, channel: false} } }
apiPost({data});
// pass the signup function in here
// hash the variables and send to celox network
console.log(JSON.stringify({data}));
alert (`copy and save your Private Key to somewhere safe: ${skey}`);
}
</script>
signup.js (pre-Browserify build):
window.apiPost = function({data})
{
fetch("https://goldengates.club:3000/api/passData",
{
method: "post",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({data})
}
);
}
build.js (pre-Browserify build):
var eccrypto = require("eccrypto");
window.genSKey = function()
{
var secretKey = eccrypto.generatePrivate();
var SKey = JSON.stringify(secretKey);
localStorage.setItem("skey", SKey);
console.log(SKey);
alert(`your private key is ${SKey}`)
}
window.genPKey = function()
{
var skey = localStorage.getItem("skey");
var SKey = JSON.parse(skey);
let publicKey;
if(SKey != null)
{
publicKey = eccrypto.getPublic(SKey);
localStorage.setItem("pkey", JSON.stringify(publicKey));
return;
}
publicKey = eccrypto.getPublic(privateKey);
localStorage.setItem("pkey", JSON.stringify(publicKey));
return;
}
window.getPKey = function()
{
var PKey = localStorage.getItem("pkey");
var pkey = JSON.parse(PKey);
return pkey;
}
window.getSKey = function()
{
var SKey = localStorage.getItem("skey");
var skey = JSON.parse(SKey);
return skey;
}
window.encryptMes = function(data)
{
//for this you need to get the sender's public key to encrypt the message
if (localStorage.getItem("pkey") === null)
{
if (localStorage.getItem("skey") === null)
{
genSKey();
genPKey();
}
}
var pkey = getPKey();
encryptedMes = eccrypto.encrypt(pkey, Buffer.from(data));
return encryptedMes;
}
window.decryptMes = function(data)
{
if (localStorage.getItem("skey") === null)
{
genSKey();
}
var skey = getSKey();
decryptedMes = eccrypto.decrypt(SKey, data);
return decryptedMes.toString();
}
window.encryptData = function()
{
genSKey();
genPKey();
enMes = encryptedMes(/*add a document search for all fields on input form in login*/);
}
window.decryptData = function() {}
Error Code:
Browser:
It runs everything in the signup.html file besides console.log(JSON.stringify({data})); in the signupData(form) function.
Suspicious since the object that was created with user data should have been created and printed to the console.
My API Console:
I won't reference the API code since it seems to me that the object is just not being posted to it and that it isn't the problem.
TypeError: Cannot read property 'name' of undefined
at dataPool.setData (/home/main/public_html/Cypher-Network/src/app/data-Pool.js:64:27)
at /home/main/public_html/Cypher-Network/src/index.js:198:12
at Layer.handle [as handle_request] (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/layer.js:95:5)
at next (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/layer.js:95:5)
at /home/main/public_html/Cypher-Network/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/index.js:335:12)
at next (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/index.js:275:10)
at /home/main/public_html/Cypher-Network/src/index.js:62:3
Any form of help and explanation is greatly appreciated, as I am pretty new to the way JavaScript works.

Are you making use of NodeJs, and a framework like express? If yes, then you have to be sure that your backend is able to pass the incoming JSON request. If you use express, you can just use the express.json() middleware. Make sure you put it at the top of other middleware or just after the cors middleware like so
app.use(express.json())
That will parse the incoming data from the frontend.

Related

Read Message from WebApp

I am working on a WebApp Add-on in Google Sheets. Below is the Addon and webapp script. I want to read validation/error message from webapp and display to user.
Like I will send message from doPost(e) like "Check Values" and user should get this as message box.
function copyData() {
var ss_id = SpreadsheetApp.getActive().getId();
//This is the Web App URL.
var url = "https://script.google.com/macros/s/<id>/exec";
var payload = {
"ss_id" : ss_id, // Modified
}
var options = {
"method" : "POST",
"payload" : payload,
"followRedirects" : true,
"muteHttpExceptions" : true,
};
var result = UrlFetchApp.fetch(url, options);
}
function doPost(e) {
var ss_id = e.parameter.ss_id; // Modified
var response = {
"status" : "FAILED",
"ss_id" : ss_id,
};
//var ss_id = ss_id[0];
//Use your spreadsheetID to get Output Sheet
var Manager_SS=SpreadsheetApp.openById('<id>');
var Manager_Sheet=Manager_SS.getSheetByName('Consolidated_Data');
var FrontDesk_ss = SpreadsheetApp.openById(ss_id);
var FrontDesk_sheet = FrontDesk_ss.getSheetByName('Data');
//Get front desk data
var sData = FrontDesk_sheet.getRange("A2:C10").getValues();
//Copy data from Front Desk to Manager Sheet.
Manager_Sheet.getRange("A2:C10").clear();
Manager_Sheet.getRange("A2:C10").setValues(sData);
//Update done after copying data.
FrontDesk_sheet.getRange('D1:D10').setValue('Done');
var response = {
"status" : "SUCCESS",
"sData" : sData,
};
return ContentService.createTextOutput(JSON.stringify(response));
}
For this example I am using a bounded script, but this should be the same for an Editor Add-on
In the spreadsheet we want to validate, we create a custom menu to call a function that makes a POST request to our Web App. Depending on the response, we display one content or another.
const UI = SpreadsheetApp.getUi()
const onOpen = () => {
/* Adds the custom menu */
UI.createMenu('Custom Function').addItem('Is Valid?', 'checkValidity').addToUi()
}
const checkValidity = () => {
const res = UrlFetchApp.fetch
(
/* Change it for your URL */
"https://script.google.com/macros/s/<ID>/exec",
{
"method": "post",
"contentType": "application/json",
/* In this example I only send the ID of the Spreadsheet */
"payload": JSON.stringify(
{
"ss_id": SpreadsheetApp.getActiveSpreadsheet().getId()
}
)
}
)
/* Depending on the response from the Web App */
/* We show different messages */
const { MSG } = JSON.parse(res.getContentText())
UI.alert(MSG === "OK" ? "IS VALID" : "IS NOT VALID")
}
After we create a Web App that validates the ID. In this example I am only validating that the ID is contained in an array of valid IDs, but this should be replaced by whatever you need. As a response I only send a simple "OK" or "NOT OK", but this can be replaced with any kind of data.
const doPost = (e) => {
/* We perform the checks we need */
/* In this example only checking if the id is contained in an array */
/* This should be changed to perform the desired checks */
const validID = ["<VALID_ID_1>","<VALID_ID_2>"]
const { ss_id } = JSON.parse(e.postData.contents)
/* SpreadsheetApp.openById(ss_id).copy("my_new_copy") */
const checker = validID.includes(ss_id)
/* We send back the response */
/* Depending on the checker value */
return ContentService.createTextOutput(JSON.stringify(
{
"MSG": checker ? "OK" : "NOT OK"
}
)).setMimeType(ContentService.MimeType.JSON)
}
Reading Validation Error from Webapp
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form>
<input type="text" id="txt1" name="id" placeholder="Enter Numbers only"/>
<input type="button" value="submit" onClick="processForm(this.parentNode);" />
</form>
<script>
function processForm(obj) {
console.log(obj.id.value);
if(obj.id.value.match(/[A-Za-z]/)) {
google.script.run.displayError("Invalid Characters Found in id field");
} else {
google.script.run.sendData(obj);
}
}
</script>
</body>
</html>
GS:
function doPost(e) {
Logger.log(e.postData.contents);
Logger.log(e.postData.type);
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet1");
let data = JSON.parse(e.postData.contents);
let row = [];
Object.keys(data).forEach(k => row.push(data[k]));
Logger.log(JSON.stringify(row))
sh.appendRow(row);
}
function sendData(obj) {
const url = ScriptApp.getService().getUrl();
const params={"contentType":"application/json","payload":JSON.stringify(obj),"muteHttpExceptions":true,"method":"post","headers": {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}};
UrlFetchApp.fetch(url,params);
}
function displayError(msg) {
SpreadsheetApp.getUi().alert(msg);
}
function launchMyDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'),'My Dialog');
}

Creating an hour in Perl using MySql and the Websocket protocol

Good afternoon, I'm writing chat in Perl using Mysql and the Websocket protocol.
I am using the AnyEvent module and Protocol :: WebSocket.
I understand that it would be better to use Mojo or Node.js for this, but in my case it needs to be that way.
I receive data from Websocket, reverse and connect. The data entered in the input field also fits into the database.
My problem is that how can I now output this data to the web interface in real time.
#!/usr/bin/env perl
use strict;
use warnings;
use AnyEvent;
use AnyEvent::Handle;
use AnyEvent::DBI::MySQL;
use AnyEvent::Socket;
use Protocol::WebSocket::Handshake::Server;
use Protocol::WebSocket::Frame;
my $dbh = AnyEvent::DBI::MySQL->connect("DBI:mysql:chat:localhost", "admin", "admin",
{
mysql_enable_utf8 => 1,
PrintError => 0,
}) or die;
my $cv = AnyEvent->condvar;
my $hdl;
my $sth;
AnyEvent::Socket::tcp_server undef, 3000, sub {
my ($clsock, $host, $port) = #_;
my $hs = Protocol::WebSocket::Handshake::Server->new;
my $frame = Protocol::WebSocket::Frame->new;
$hdl = AnyEvent::Handle->new(fh => $clsock);
$hdl->on_read(
sub {
my $hdl = shift;
my $chunk = $hdl->{rbuf};
$hdl->{rbuf} = undef;
if (!$hs->is_done) {
$hs->parse($chunk);
if ($hs->is_done) {
$hdl->push_write($hs->to_string);
return;
}
}
$frame->append($chunk);
my $message = $frame->next;
if ($message eq ""){
$message = undef;
} else {
$sth = $dbh->do("INSERT INTO web_chat VALUES('$message')", { async => 0 });
}
my $ary_ref = $dbh->selectcol_arrayref("SELECT text FROM web_chat");
}
);
};
$cv->wait;
1;
Client is not written in Javascript
<!doctype html>
<form name="publish">
<input type="text" name="message" maxlength="50"/>
<input type="submit" value="Send"/>
</form>
<div id="messages"></div>
<script>
let socket = new WebSocket('ws://192.168.1.1:3000/websocket/');
// отправка сообщения из формы
document.forms.publish.onsubmit = function() {
let outgoingMessage = this.message.value;
socket.send(outgoingMessage);
return false;
};
socket.onopen = function () {
console.log("Websocket Connection");
};
socket.onerror = function () {
console.log("Error websocket connection ");
}
// прослушка входящих сообщений
socket.onmessage = function(event) {
let incomingMessage = event.data;
showMessage(incomingMessage);
};
socket.onclose = event => console.log(`Closed ${event.code}`);
// отображение информации в div#messages
function showMessage(message) {
let messageElem = document.createElement('div');
messageElem.textContent = message;
document.getElementById('messages').prepend(messageElem);
}
</script>
May I suggest Mojolicious and Mojo::Mysql for this?
Protocol::WebSocket is pretty “bare-bones” and doesn’t handle a lot of the protocol details like ping/pong.

JavaScript $.GET not passing through

I am building a very simple chat application, nothing too fancy just a way for multiple users to chat at once.
The problem I am having is that whilst I can read and display messages from the database, no new messages will get inserted.
I am using JavaScript to pass a $.Get with the message and the username. I have checked the console and there is no errors showing but I have an undefined index: text and undefined index: username when I use POSTMAN to test.
Can anyone help push me in the right direction to solve this?
chat.php
<div class="wrapper">
<p id='chat-user'> </p>
<div id='chat-area'></div>
<form id='send-message-area'>
<textarea name="the-textarea" id="the-textarea" maxlength="150" placeholder="Start Typing..."autofocus></textarea>
</form>
<button id='chatSend' class="btn btn-info" type="submit">Post New Message</button>
<div id="the-count">
<span id="current">0</span>
<span id="maximum">/ 150</span>
</div>
</div>
var name = prompt("Enter your name:", "Guest");
if (!name || name === ' ') {
name = "Guest";
}
window.onload = function () {
document.getElementById("chat-user").innerHTML = "Your are: " + name;
};
$(document).ready(function () {
var chatInterval = 250;
var $chatOutput = $("#chat-area");
var $chatInput = $("#the-textarea");
var $chatSend = $("#chatSend");
function sendMessage() {
var chatInputString = $chatInput.val();
$.GET("testProcess.php", {
username: name,
text: chatInputString
});
retrieveMessages();
}
process.php
<?php
error_reporting(E_ALL);
include ("connection.php");
$username = substr($_GET["username"], 0, 32);
$text = substr($_GET["text"], 0, 150);
$nameEscaped = htmlentities(mysqli_real_escape_string($conn, $username));
$textEscaped = htmlentities(mysqli_real_escape_string($conn, $text));
$timestamp = date("Y-m-d H:i:s");
$insertMessage = "INSERT INTO message (messageID, messageBody, timeSent, nickname, sent) VALUES ('', '$textEscaped', '$timestamp', '$nameEscaped')";
$result = mysqli_query($conn, $insertMessage);
Your postman request is wrong as shown in the picture
you are passing the param GET with the value send but in your php script you have $_GET["username"] and $_GET["text"] the method GET is already set in the left side of the url in the picture so you dont need to send it what you want to send is the param username and text so the url would look like this
http://xxxxxxx/testProcess.php?username=Guest&text=test
as for your javascript code the jquery method for get is $.get and not $.GET and you are missing a way to handle the submit of the form because your submit button is outside of the form so a correct way to this would be
var name = prompt("Enter your name:", "Guest");
if (!name || name === ' ') {
name = "Guest";
}
window.onload = function() {
document.getElementById("chat-user").innerHTML = "Your are: " + name;
};
$(document).ready(function() {
var chatInterval = 250;
var $chatOutput = $("#chat-area");
var $chatInput = $("#the-textarea");
var $chatSend = $("#chatSend");
//intercepting the submit event to call the sendMessage function
$("#send-message-area").on("submit", function(e) {
e.preventDefault();
sendMessage()
})
function sendMessage() {
var chatInputString = $chatInput.val();
$.get("testProcess.php", {
username: name,
text: chatInputString
});
retrieveMessages();
}
})

Failed to send the message by testing the tutorial in angularjs-chat

I get this error
TypeError: self.rooms[setup.to].publish is not a function
when sending the message. I already have the keys in pubnub, what should I do to make it work? My Angular version is 1.6.6.
// Send Messages
$scope.send = function() {
Messages.send({
data: $scope.textbox
});
};
I dunno if you use a form but try this way :
<form name="form" novalidate="true" ng-submit="send()">
$scope.send = function () {
if ($scope.form.$valid) {
var data = $scope.textbox;
$scope.textbox = null;
$scope.messages.push(data);//of push or send depend did proto
}
}

AngularJS + ASP.NET $http.post returning 401

I am trying to add a new Stop to my database. But I get a 401 error in asp.net.
.js file:
(function () {
"use strict";
angular.module("app-trips")
.controller("tripEditorController", tripEditorController);
function tripEditorController($routeParams, $http) {
var vm = this;
vm.tripName = $routeParams.tripName;
vm.stops = [];
vm.newStop = {};
vm.addStop = function () {
alert(vm.newStop.name);
$http.post("/api/trips/" + vm.tripName + "/stops", vm.newStop)
.then(function (response) {
vm.stops.push(vm.newStop);
};
}
}
.html file (input form):
<form novalidate name="newStopForm" ng-submit="vm.addStop()">
<div class="form-group">
<label for="">Date</label>
<input class="form-control" id="arrival" name="arrival" ng-model="vm.newStop.arrival" required />
</div>
<div class="form-group">
<label>Location</label>
<input class="form-control" id="name" name="name" ng-model="vm.newStop.name" required ng-minlength="3" />
</div>
<div>
<input type="submit" value="Add" class="btn btn-success" ng-disabled="newStopForm.$invalid" />
</div>
</form>
C# Post code:
[HttpPost("/api/trips/{tripName}/stops")]
public async Task<IActionResult> Post(string tripName, [FromBody]StopViewModel vm)
{
try
{
if (ModelState.IsValid)
{
var newStop = Mapper.Map<Stop>(vm);
var result =await _coordsService.GetCoordsAsync(newStop.Name);
if (!result.Succes)
{
_logger.LogError(result.Message);
}
else
{
newStop.Latitude = result.Latitude;
newStop.Longitude = result.Longitude;
}
_repository.AddStop(tripName, newStop, User.Identity.Name);
if (await _repository.SaveChangesAsync())
{
return Created($"/api/trips/{tripName}/stops/{newStop.Name}",
Mapper.Map<StopViewModel>(newStop));
}
}
}
catch (Exception ex)
{
_logger.LogError("Failed to save new Stop: {0}", ex);
}
return BadRequest("Failed to save new stop");
}
GeoCoordsService.cs:
public async Task<GeoCoordsResult> GetCoordsAsync(string name)
{
var result = new GeoCoordsResult()
{
Succes = false,
Message = "Failed to get coordinates"
};
var apiKey = _config["Keys:BingKey"];
var encodedName = WebUtility.UrlEncode(name);
var url = $"http://dev.virtualearth.net/REST/v1/Locations?q={encodedName}&key={apiKey}";
var client = new HttpClient();
var json = await client.GetStringAsync(url);
var results = JObject.Parse(json);
var resources = results["resourceSets"][0]["resources"];
if (!resources.HasValues)
{
result.Message = $"Could not find '{name}' as a location";
}
else
{
var confidence = (string)resources[0]["confidence"];
if (confidence != "High")
{
result.Message = $"Could not find a confident match for '{name}' as a location";
}
else
{
var coords = resources[0]["geocodePoints"][0]["coordinates"];
result.Latitude = (double)coords[0];
result.Longitude = (double)coords[1];
result.Succes = true;
result.Message = "Success";
}
}
return result;
}
I have read, that this is probably caused because the data is not in the right format, does anyone know what would be the right format, my webpage returns error 400, but deeper in my C# I can see that function var json = await client.GetStringAsync(url);is returning an error 401 (Unotharized). I guess I should also add username somewhere, but I don't know where.
You're getting a 400 because the request you sent isn't what the server is expecting. Find out the object the server is expecting on that endpoint. Then form your request body to match that object.

Categories

Resources