Check server response after a iron-form submit - javascript

I am submitting a form using iron-form. However, when the server responds, I want to see what the response is so that I can:
Either close the form (if everything was OK)
Or highlight the "broken" fields (if the response was an error)
I realise I can easily listen to iron-form-error to see if there were any problems. The error comes back as Json, where I have key/value where the key is the field name, and the value is the error message.
In case the response was indeed an error, do I have to go through the response manually? Or is there a shorthand version to display the error messages automagically?
Thank you!

Are you doing any pre-validation with validators attached to the inputs? These will provide error messages that you have put in the error-message attribute of the input. When the response comes back you can just set the paper-input to invalid.
I have a password change dialog that is like this. It uses a validator to check that password 1 and password 2 are the same, but the server also checks this too. In this case it sends a valid json response (ie not an error) with the response json object containing an field that tells me that particular field is wrong (as a boolean). Here is a fragment of my response after earlier I have done var response = e.detail.response;
if (response.status) {
this.$.profiledialog.close();
this._setNopass(false); //just get this back to its default state
} else {
if (!response.passwd1) {
if (response.passwd2) {
this.$.pw1.invalid = true;
this.$.pw1.focus();
} else {
throw new Error('Profile Update Server Failure');
}
}
if (!response.passwd2) {
this.$.pw2.invalid = true;
this.$.pw2.focus();
}
}

Related

Using axios post with Express send a new html instead of a variable

I want to check username/password with a post request using axios like this :
function axiosCall() {
axios.post('/login', {
username: document.getElementById("username").innerText,
password: document.getElementById("password").innerText
})
.then(function (problem) {
if (problem.toString() === "username") {
lespanUsername.innerHTML = "Pseudo incorrect !";
} else if (problem.toString() === "password") {
lespanPassword.innerHTML = "Votre mot de passe est incorrect !";
}
})
}
But my express post :
app.post('/login', urlEncodedParser, (req, res) => {
let username = req.body.username;
let password = req.body.password;
if (users.existUser(username)) {
if (users.validUser(username, password) === true) {
res.status(200)
res.redirect("/");
} else {
res.status(401)
res.send("password")
}
} else {
res.status(401)
res.send("username")
}
});
Sending html instead of a variable and reloading my page. :
Does anyone have an answer, I haven't found a solution despite a lot of searching. The send("username") works on the examples I found online. Thanks in advance !
You have six separate problems here.
reloading my page
The code you've supplied won't do that.
The most likely reason is that you are calling axiosCall when a form is submitted (or when a submit button is clicked, which amounts to the same thing) and failing to prevent the default behaviour for that.
HTML
See the documentation for send:
When the parameter is a String, the method sets the Content-Type to “text/html”
In HTML, a number of tags (including the start and end tags for html, head and body`) are optional. The browser is generating them when it parses the HTML document you are supplying.
Use res.json instead. axios will parse a JSON response automatically.
Problems you have but haven't discovered yet
Form encoding
You have urlEncodedParser.
A form submission (see the first part of this answer) will, by default, use URL encoding.
Axios will use JSON encoding. You'll need to change the middleware when you get your Axios request to replace the form submission request.
innerText
You are, presumably, reading the data from input elements.
They don't have innerText, they have values.
response object
.then(function (problem) {
if (problem.toString() === "username") {
The resolve value of the promise will be a response object.
You need to access its data property. If you stringify the response you'll get "[Object object]" which won't match "username".
redirecting
res.redirect("/");
A redirect means "What you asked for can be found here".
It does not mean "The browser viewport should navigate to this URL".
That will cause the browser to request / (which I'm assuming is your homepage, an HTML document) and supply it to your JavaScript. It won't display it.

Liferay 7 MVC Resource Command: react with JS on return value

I have a Liferay 7.3 MVC Resource Command which is something like this:
public boolean serveResource(
ResourceRequest resourceRequest, ResourceResponse resourceResponse) {
try {
// my code goes here
return false;
}catch(Exception e){
return true;
}
}
I call this Command from JavaScript with this:
var req = new XMLHttpRequest();
req.open("POST", '${upload}', true)
req.onload = function (event) {
console.log("success");
}
req.onerror = function (event) {
console.log("error");
}
// do request
req.send(form_data);
The problem now is that always the "onload" function is called also when the MVC ResourceCommands sends back true in the catch clause.
So my question: How can I know in JavaScript when my ResourceCommand was succesfull or not?
Javadoc isn't all that clear about the purpose of the boolean return type. Especially as GenericPortlet.serveResource has a void return type.
However, thinking about what can happen within your // my code goes here block makes it clearer what to expect: The client can't rely on the boolean result to be signaled back: You could (and typically do) access the ResourceResponse's output stream, send all the data you like, and it can long be at the client when you finally return true; from this code. That means that the framework has no chance to intercept or redirect any communication that has been made already.
Also, a simple true/false return value wound not give you any control over what kind of error is signaled to the client. Is it 401? 404? 418? 500? Or would it return 200 with a HTML error message? A JSON encoded error?
If you rely on the result of this operation: Keep control over it. I can't tell you what the boolean return value is for, but it ain't for the benefit of the browser. You decide if you use a HTTP status code for your error signalling, or a specific payload. And once you implement that, you know what to expect on the JS side.
Remember that you'll have to decide for either "ok case" or "error case" before you ever send any data back to the client. If you started delivering the "ok" result to the client and suddenly run into an Exception, you might have delivered half of it to the client, but can't rely on changing horses, e.g. you can't start over, sending an error message as the response might already be (half) on the way to the browser.

how to pass a custom error through rails backend to JavaScript front end with fetch()

I have a small NPC generator (non-player character) for D&D. I've set up a rails API backend with a Javascript front end and have been able to pass a custom message to alert my user when they delete. I am now trying to protect from bad data when they create a new NPC. I have validated my backend so that to create a new NPC they need to input a "name". that portion works and I had the alert come up. however, the custom JSON message I passed doesn't come up. it would either alert with "undefined" or an uncaught reference error since the name wasn't present.
I have tried using catch and with an, if response.ok to get it working but just can't wrap my head around getting that custom error to show up on the alert.
see below the code for the CREATE from my controller and the fetch() for my post request from my adapter. as well as a link to my full git repo if needed.
https://github.com/Santiago548/NPC_Generator
below is my CREATE from the controller with the render JSON error that I am trying to pass to the user when they do not enter a name.
def create
npc = Npc.new(npc_params)
if npc.save
render json: NpcSerializer.new(npc)
else
render json: {errors: 'NPC could not be created'}
end
end
below is my fetch() function from my javascript that does create
fetch(this.baseUrl, configNpcRand)
.then(res => res.json())
.then(json => {
let npc = new Npc(json.data.attributes)
npc.attachToDomNpcList()
})
randomNpcForm.reset()
npcForm.reset()
}
As a first measure, your form must contain validations to inform users that the details are incomplete without requiring to POST to the back. See here
In the back, the key is to have proper error handling. I would try the following:
def create
npc = Npc.new(npc_params)
if npc.save!
begin
render json: NpcSerializer.new(npc)
rescue ActiveRecord::RecordInvalid => invalid
render json: { error: invalid }, status: :unprocessable_entity
end
end
end
Here, you attempt to save! which will raise errors when the record is invalid. (assuming you have validations on the model)
In the front, the call also requires proper error handling
async function postNPC(baseUrl, configNpcRand) {
try {
const response = await fetch(baseUrl, configNpcRand);
if(response.ok){
npcData = await response.json()
return npcData // Don't handle NPC creation here
}
// This handles the case where the fetch is successful,
// but the server doesn't return status OK, as will happen when
// everything is fine but the NPC params are incomplete.
return { error: 'Please fill in all the NPC details' };
}
catch(e) {
// This error would handle other errors
// for example, when there is no response from the server
return { error: e };
}
}
The async/await synthax increase readability

how to notify client that reCaptcha is successful

Hello i have simple form where i have google reCaptcha v2 and when user submits form i am validating recaptcha but i also send email to user inputted email and i need to send status 200 two times here is first time where i need to send it
request(verifyURL, (err, res, body)=>{
body = JSON.parse(body);
if(body.success !== undefined && !body.success){
return res.status(409).send({
success: false,
message: 'დადასტურება ვერ ვოხერხდა'
})
}
return res.status(200).send({success: true})
})
so if i send status code 200 and use return statement, won't it cause
Can't set headers after they are sent
error?
if it will how can i fix it?
Thank you!
You cannot send multiple response for a single request. You can go with either:
1. Send the mail in the same controller, and when its done successfully, then only send the response back to client. Your response will be based on both factors ie. captcha validation and email sent response
or 2. if you don't wanna wait for the email process.. Just send response once your captcha is verified.. and keep the mail process execution in background. In this case you need to remove the return keyword or else your request will end there and mail process won't execute.
However, I'll suggest you to go with the first approach. Hope this helps :)

How to handle ajax call when there is no response from the server

I have an ajax call for some data (using jQuery). after the user clicks "submit" (and the ajax call has been sent) I am displaying a "Please wait..." message that disables everything until the request returns (so the user won't double click or click other things and mess things up).
It works great when there is any kind of error - the "Please wait..." disappears and I am displaying the user what went wrong.
But what happens if the server don't return me anything back because of communication error?
The solution I found for that is to set a timeout of 10 seconds for the "Please wait.." message that after that time it disappears and displays and error that "The communication failed". I assume that if the server didn't respond after 10 seconds then it will not respond at all - but that it false assumption.
The problem is - how can I be sure that after 20 seconds the server won't return something back? The scenario that might happen is that the user click submits --> 10 seconds later he get an error message --> 5 seconds later server response and confuses the user
How do I make sure that after I hide the "Please wait.." message nothing will pop up from the server?
when you send a request to a server. a connection is opened and its kept open unless the server responds.
1.if due to some error on the server side it cannot respond then a response code of 5xx is sent back generally (503)
2.if due to some connection issues the connection is terminated prematurely then also jquery would take that as an error.
1.so if you wanna wait for the server to send a request or connection termination (which ever occurs earlier) then u can use the completed option in the jquery ajax.
2.and if you are in a condition in which server isnt responding even after 20 secs and you think that it should have responded by now use timeout.
3.finally if your problem is that you are using some kind of customized(hand made http server) which doesn't end a request even if it encounters some error then atleast customize it enough so that it sends back some response code(because this is HTTP model of request and response)
You can handle something like this
if ( request.readyState == 4 ){ // 4 is "complete"
if ( request.status == 200 ){
// HTTP OK, carry out your normal Ajax processing
// ...
}else{
// something went wrong, report the error
error( "HTTP "+request.status+". An error was »
encountered: "+ request.statusText );
}
}
(or)
$.ajax({
type: "post",
url: "somepage.html",
success: function (data, text) {
//...
},
error: function (request, status, error) {
alert(request.responseText);
}
});
Generate a unique token when you fire a request,
keep a list of valid tokens,
remove tokens when the request times out/fails,
check if token is still valid before executing success/error callbacks.
The same pattern can be adapted for a situation when you need to send frequent repeating requests (e.g. autocompletion/result filtering) and only the latest one's handler should fire.

Categories