html5 websockets and long strings - javascript

I have a websocket HTML5 page that receives data from the server, but curiously the onmessage event seems to fire multiple times for long strings.
w.onmessage = function(e) {
console.log ("\n\n message received... "+e.data);
}
If I have a string 3000 characters long, the above code will print out the first 2048 characters and then whatever is left over on the second time around.
Is there anyway for me to check for something like (pseudo-code) (e.state == FINISHED) or (e.state != UPDATING) or something so I don't execute my code until I have all of the data? Right now, the onmessage function is getting called multiple times when it receives a message and this is messing up the code.

Can you split the string in the server side? Add some thing at the end to indicate that there are more characters behind.

Related

Remove last 3 letters of div (hidde also in browser page source)

this is my HTML
<div id="remove">Username</div>
and this is my JS code
function slice() {
var t = document.getElementById("remove");
t.textContent = t.textContent.slice(0, -3);
}
slice();
Username load from foreach
{foreach from=$last_user item=s}
{$s.date}
{$s.username}
{/foreach}
This code working and remove 3 letter but when right click on browser and look at page sources i can see "Username" !
I need remove three letter because of privacy and security .
something like
*** name or usern ***
Thank for help me !
The only secure way to make sure the client can't see a particular piece of information is to never send it to the client in the first place. Otherwise, there will always be a way for the client to examine the raw payloads of the network requests and figure out the information they aren't supposed to know.
You'll need to fix this on your backend - either hard-code in
<div id="remove">Usern</div>
or, for a more dynamic approach, use a template engine (or whatever's generating the HTML) and look up how to change strings with it. For example, in EJS, if user is an object with a username property, you could do
<div id="remove"><%= user.username.slice(0, -3) %></div>
Changing the content only with client-side JavaScript will not be sufficient, if you wish to keep some things truly private.
With Smarty, you can define a modifier that takes a string and returns all but the last three characters of it.
function smarty_modifier_truncate_three($string)
{
return substr($string, 0, -3);
}
and then in your template, replace
{$s.username}
with
{$s.username|truncate_three}
If you want only the first three characters, it's easier because you can use the built-in truncate.
{$s.username|truncate:3}
JS doesn't change the source, it can only change the DOM, so what you can do is to keep the element empty and add a value to it using js, but don't forget that js runs on the client's side so its better here to send the string from the server without the last 3 characters.

Posting a single quote into a Postgres database

I am currently trying to take a string submitted from a form and make an api call to submit the message into the Postgres data base. Everything works sucessfully except when dealing with single quotes. The simplified code is:
const message = form.get('message').replace(/\'/g, "E\'\'")
urlData = ...&reasoning=${message}
methodApi = ...
axios.get(methodApi + urlData);
I am currently using the .replace function above to follow the format when dealing with single quotes. And it works but the message submitted to the database has the E present
example value from db after submission:
testing single quote: E'
When I do not use the .replace function the api gets cut off and wont submit, also just replacing a single quote with \' does not work and two single quotes does not work either.
So basically I've made progress and am trying to have the "E" not show up in the db.
Most likely a simple fix but each time I push the code to the dev environment to test the db it takes about 20 minutes, so asking here while I work on it will save some time.
Thanks and let me know if this is confusing I will be sure to respond asap!

Fire HTML input-event only once when more than one character is typed

I'm creating an input field where some data should be fetched (by AJAX) and displayed every time the user enters data into that field. However, if the user types several characters, say he types "test" to get all records who contain the string "test", it would not be necessary to do 4 queries after every character pressed, but one query after he stopped typing. I can think of several solutions with a global variable where I check if the same event has been fired again, but is there a really elegant way to do this? Maybe check if there is something in the keyboard buffer and only proceed if it is empty? Or is there an event that is only fired once the keyboard buffer is empty and all characters are in the input field?
The elegant way is to use a timeout, and to keep clearing the previous timeout with each key press
var tID;
function keyUp (e) {
if (tID) clearTimeout(tID);
tID = setTimeout(function() {
... // make web call
}, 2000);
}
This will ensure that the web call is only called after the last key is pressed (you may want to adjust the timeout value)
There are ways to achieve this that I can think of:
Use timeout, from the last keyup event. This is not always the best and not that precise with users that have low typing speed.
Use space character do regconize if the user has finished typing a word. Based on changes in length and total word count, you can decide if you would want to send AJAX or not.
Depends on the type of input you are working with, you may choose the most suitable method for you. The first one is somewhat quite rigid. The second method requires user to press space every time he finishs typing. A little bit of both could be a sweet spot perhaps. In modern day, I don't think sending request every keyup will cause huge performance effect though.

onkeyup Event Firing delay

I have a input textbox for people to enter a username, it has a onkeyup event attribute attached which fires off an AJAX request to check if the username is taken.
What is the delay between the first key to the second ? Meaning if I type a 5 letter word one letter after the other. Does the AJAX fire 5 times ?
If there is no delay, would this be "computationally expensive" since there would so many database queries ? Or would there be no noticeable difference ?
If there is a difference in performance, what methods could I take using Javascript to check if the user is actually "done" typing. I still want it to automatically check after typing. Thus ruling out onblur attributes etc.
My Code: http://pastebin.com/hXfgk7nL
(code indentation wasn't working for me on stack overflow)
Yes it will fire EVERYTIME you type a character and you're not going to like that in terms of your page performance. You can implement delays on executing the call back if you like ie. it will not be executed until the user stopped typing. Here's an example:
$(document).ready(function(){
$('#txtboxid').keyup(function(){
clearTimeout(timer);
timer = setTimeout(function(){
//call your function here
}, 250) // you can change the 250 here to a higher number if you want the delay to be longer. In this case, 250 means a quarter of a second.
});});
Following are my replies/suggestion for your queries:
Yes , it will fire 5 fives because 5 times key-up event will be triggered.
it will be a performance issue, resulting in slow response from server,also since your making multiple ajax request sequentially, the response from each request may not be sequential.your code will suffer from logic issue.
instead of making ajax call for key-up, you can use it for blur event.
Suggestion: before making a ajax call validate the field for basic errors like blank string, numbers etc.,(depending on your requirement).
Yes it will fire multiple times, one for each keystroke. You are triggering multiple AJAX calls, so you are wasting network and server resources.
Additionally, you are not guaranteed on the order in which the calls will return, so if for some network reason, the first call issued return last, it will overwrite the results of the most recent request.
To tackle the problem, you are looking for something like this plugin: https://github.com/cowboy/jquery-throttle-debounce.
From the plugin usage example:
function ajax_lookup( event ) {
// Perform an AJAX lookup on $(this).val();
};
// Console logging happens on keyup, for every single key
// pressed, which is WAAAY more often than you want it to.
$('input:text').keyup( ajax_lookup );
// Console logging happens on window keyup, but only after
// the user has stopped typing for 250ms.
$('input:text').keyup( $.debounce( 250, ajax_lookup ) );
Note that despite the name the plugin can also be used stand alone, without jquery.
Yes, it will fire every key-up event. You can reduce the performance hit using following approach.
I am sure you must have a minimum character length for username. Wait until user type that number of characters to query the database.
You could always bring all the usernames starting with user typed username and process in local memory. This may not be real time but would reduce the number database queries. Also it would depend on the size of your current user list.
Double check the existence of the username before saving it to the database.
yes it will fire. if you don't need that means, you have to check conditions with a flag. check the given value with the previous value which is stored in a variable.
You can try to check if your input is modified in 500 ms. Is is not, then make only one ajax request. If the input is modified again than you must repeat the process again.
I suggest to use setInterval for that.

Bad data received from Arduino serial while reading from analog port

Maybe this is just a nonsense, but it's driving me crazy. I'm trying to read one analog port in Arduino and send the value through the serial port to JavaScript using node. When I show the data in the Arduino console, everything works fine, but when I use the terminal in Mac, some values appear splited in two lines.
460
460
4
60
460
The code I'm using is:
Arduino:
const int analogInPin = A0;
int sensorValue = 0;
void setup() {
Serial.begin(500000);
}
void loop() {
sensorValue = analogRead(analogInPin);
Serial.print(sensorValue);
delay(200);
}
Node:
var com = require('serialport').SerialPort;
var opts = {baudrate: 500000};
var serialPort = new com('/dev/tty.usbmodem641', opts);
serialPort.on('data', function(data) {
console.log(data.toString());
});
The code couldn't be simpler, but still doesn't work properly. I know I'm missing something but I can't see it. I have tested different baudrates, but nothings works. Could you please help me?
Thanks in advance
I think maybe Elias Benevedes is trying to suggest this in their answer: right now your Arduino data is not delimited at all. Suppose your sensorValue always reads as 1. In this case the output from Arduino will be
11111111111111111111111111111111111111111111111111111111111....
And so on; because you print the integer value without any delimiters. The way it is parsed into different numbers, therefore, has to do with the timing of the arrival of the data. Continuing with the example above then, sometimes your value is read as 1, sometimes as 11, sometimes as 111 and so on, just depending on the timing of the reads and the writes.
The way to begin to fix it is to insert some non-numeric data between your sensor reading outpus. One (again, this is perhaps what Elias Benevedes has in mind) is to insert line breaks between every number printed
Serial.println(sensorValue);
Another way would be to add spaces between the data
Serial.print(sensorValue);
Serial.print(" ");
Either solution would separate your numeric readings from each other, which is what you want.
I had this happen to me once also. Serial.print() sends data to the arduino. Serial.println() will send information from the arduino to the computer Serial message board (or whatever you want to call it.

Categories

Resources