So I have a html5 form with input fields. Lets say the fields are first name, last name, phone, email, and address.
Now first, last, and address are required while phone and email are optional. I know that the backend has this configured properly. However on the html5 form it will not let me submit without phone or email otherwise it returns a 400 error.
If I remove the optional from the html5 form, it will let me submit it or I can put in a value=" " and will submit also. I can even tag the fields with CSS3 using :required and :optional and it will show appropriately but still won't let me submit.
Now I obviously can't just remove the optional from the html because some users may need those fields but I also don't want to send a default value of " " or "n/a" for users who don't need them. Am I just doing something wrong here or what? I don't get what is going on.
edit 2: This is a node.js api using Hapi.js with Joi validation, request, and couchdb.
edit: I know that 400 is a server error but if I post with a curl omitting the optional ones it goes through fine. It also goes through fine when I remove the optional ones from the html which is why it doesn't make sense. Here is the validation code server side for the api.
handler: function(req, res) {
request({
method: 'POST',
uri: 'https://127.0.0.1:6984/banned',
jar: cookieJar,
strictSSL: false,
json: {
firstn: req.payload.firstn,
lastn: req.payload.lastn,
licno: req.payload.licno,
phone: req.payload.phone,
email: req.payload.email,
address: req.payload.address,
description: req.payload.description
}
},
function(err, resp, body) {
if (err) { res(err) };
if (resp.statusCode === 401) {
res(resp.statusCode + ' Please log in.');
}
else if (resp.statusCode === 201) {
res(body);
}
});
},
validate: {
payload: {
firstn: Joi.string().required(),
lastn: Joi.string().required(),
licno: Joi.string().optional(),
phone: Joi.string().optional(),
email: Joi.string().optional(),
address: Joi.string().optional(),
description: Joi.string().required()
}
}
So a friend helped me figure it out. What is happening is that required or not the html form is sending with a value of "" if no data is put in. That is not " ", "null", "undefined" just "". This is not a valid value for the server so it throws the 400 error. The code that fixed it was by checking if the payload exists before validating and sending it through.
Related
How to use PATCH method in an html form to send data to a server?
I've already done this
Html
<form class="type-title" method="POST" id="alter">
<input type="hidden" name="_method" value="PATCH"/>
<input id="alter" type="text" name="alter"/>
<button onclick="alter_name();">update</button>
</form>
JS
function alter_name(){
fetch("http://127.0.0.1:3000/api/member", {
method: 'PATCH',
headers: {
'Content-type' :'application/json'
},
body: {
"name":alter_name.value.toString()
}
}),then((response) =>{
return response.json();
}).then((data) =>{
console.log(data);
})
}
but it still not work
The main issue is how you have addressed the input value. Your form's id: id="alter" is the same name as the input which is invalid, but in your script you are not referencing this field correctly at all, lets fix all this...
Firstly with the HTML form, do not post back as that might affect other workflows on the form. We do this by forcing the button to act as a simple standalone HTML Button instead of being the submit button for the form. Do this by setting the type attribute of the button to "button":
_I've also changed the Id of the form to be unique and removed the _method hidden input.
<form class="type-title" id="alter_form">
<input id="alter" type="text" name="alter"/>
<button onclick="alter_name();" type="button">update</button>
</form>
You were on the right track with using javascript and fetch() to send the data as your API is not likely to be setup to accept form-data if you are using PATCH as the method on a standard form submit.
The other fix is in the script itself, we need to deliberately stringify the object payload that we sent in the body, this way we can control or enforce the serialization instead of relying on javascript, we can also more easily inspect the contents when or if it goes wrong.
Notice how the field is referenced using the path formId.fieldId.value
The other issue you had was that your JSON object wasn't formed correctly, you had quotes around the property name, which would have resulted in quotes being escaped and encoded into the JSON string value, which we don't want.
Finally, I've specified the encoding in the Content-Type as it was required on my system to parse the content on the server side.
function alter_name(){
let content = {
Details: alter_form.alter.value.toString()
};
fetch("http://127.0.0.1:3000/api/member", {
method: 'PATCH',
headers: {
'Content-type': 'application/json; charset=UTF-8',
'Accept': 'application/json'
},
body: JSON.stringify(content)
}).then((response) => {
console.log('PATCH Response.status: ', response.status);
if(response.status !== 204)
return response.json();
else
return response.statusText;
}).then((data) => {
alert(data);
});
}
For a few bonus points, I've added some handling for a 204: No Content response from the server. Many PATCH implementations do not return content unless you explicitly request it with a Prefer HTML Header.
I want create API for contact form 7.
How to send data from front-end to Contact Form 7 using WP rest api?
I mean, what should the data structure be to send it via the POST method?
http://xx.xxx/wp-json/contact-form-7/v1/contact-forms/<id-form>/feedback
I trying different ways, but request always return response “validation_failed”, “One or more fields contain erroneous data. Please check them and try again.”
I did not find anything about this in the documentation.
Were you able to find the solution? I've been working with the Contact Form 7 REST API and there are a few things you need to do to be abled to get a 'success' response, instead of validation_failed.
First, you need to know what form fields you need to submit. This is set up in your CF7's contact form. The field's name is defined in contact form. Most likely, CF7 uses the naming structure your-name and your-email. So you will need to format your post body to match this.
Next, you will need to submit it using FormData() https://developer.mozilla.org/en-US/docs/Web/API/FormData. From personal experience, I found that if I send my request as a normal object by using post, CF7 sends back validation_failed.
Note: I am using Nuxt's http package to submit data, but you are able to use axios here.
// Format your body response
const emailBody = {
"your-name": this.form.name,
"your-email": this.form.email,
"your-message": this.form.message,
};
// Create a FormData object, and append each field to the object
const form = new FormData();
for (const field in emailBody) {
form.append(field, emailBody[field]);
}
// Submit your form body using axios, or any other way you would like
const response = await this.$http.post(this.getEndEndpoint, form);
This is working for me, I am no longer getting the status validation_failed. Instead I now get a spam status. Trying to solve this problem now
Good luck
add_filter( 'wpcf7_mail_components', 'show_cf7_request', 10, 3 );
function show_cf7_request( $components, $wpcf7_get_current_contact_form, $instance ) {
print_r($_REQUEST);
die();
return $components;
};
Don't try on LIVE ;)
// google recaptcha integration v3 with contact form 7 Rest API
let email = $('input.email').val();
let g_recaptcha_response = $('textarea.g-recaptcha-response').val();
let data = new FormData(form);
data.append("email", email);
data.append("_wpcf7_recaptcha_response", g_recaptcha_response);
// _wpcf7_recaptcha_response key is important and should be same
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "/wp-json/contact-form-7/v1/contact-forms/783/feedback",
data: data,
processData: false,
contentType: false,
cache: false,
timeout: 600000,
}).then((data) => {alert(data.message);});
After a successful creation of new item in my database I send:
res.status(201).json({message:"Successfully Registered"});
On my angular front end I am able to console.log(res) and receive:
{message: "Successfully Registered"}
1) How do I get the status code on the front end? res.status returns undefined. The only response I'm getting is the JSON.
2) What would be the best way to confirm successful desired api calls? For example, when I log in and credentials are correct, should I check for a 200 and then proceed? Or send a custom JSON message and check if the message for example says "Successful login" then proceed?
A little bit late, but another option is to include the status in the JSON object:
res.status(201).json({message: "Successfully Registered", status: 201})
Now you can check the status in the front end doing res.status and use this to proceed with another action.
1- You can do res.status(200).send("You message here");
2- I would say your best option when doing the login and authenticating credentials is to create a session as such
req.session.user = req.body.username //username is the name attribute of the textfield
and then redirect to any page you'd like/you can also set status to 200
res.status(200);
I'm not familiar with Angular, but looking at the docs:
See https://angular.io/api/http/Response
You'll need to do something like:
http
.request('example.com')
.subscribe(response => console.log(response.status));
Sure, checking for 200 is fine. Typically with a REST API (inferred from what you've shown), after a login you're given back a JWT along with 200 OK. And any subsequent API all with that JWT will also yield a 200 OK along with the response body which is usually JSON.
You should tell your angular http client that you want to get the response status. By default, angular deserialize the response body, but you can set request option.observe:'response' to do so.
postData(model: MyModel): Observable<HttpResponse<{status: string}>> {
return this.http.post<{status: string}>(
model, { observe: 'response' });
}
See https://angular.io/guide/http#reading-the-full-response for details.
PS: sending a { status: 'message' } is not very useful, you may return an { id } or even nothing.
res.status(200).json({
status: 'success',
results: tours.length,
data:{
tour:tours
}
});
Usually, Jsend is a good choice to response, and also by convention. Absolutely you can see the 'status' in response data and the actually data you want in the data.
according to the angular guide, we can add observe in the options of our request.
getforgetpassword(email: string): Observable<any> {
const url = this.gatewayUrl + `newPasswordFor/${email}`;
return this.http.get(url, {observe: "response"});
}
using observe type as response will give total response along with request status, which you can use in your logic of controller.
I can't seem to find any documentation on how to actually use the postabck feature. Does it call functions on the server? What does ti do with the pasees value?
%[Button label here](postback:PAYLOAD_HERE) // What is the payload?
The payload is actually whatever you want!
Postback buttons can be used as triggers to your webhook. When a user taps on your postback button, a payload will be sent to your webhook with the following data:
{
"trigger": "postback",
"postbacks":[{
...
"action": {
"_id": "571530ee4fae94c32b78b170",
"type": "postback",
"text": "Read more",
"payload": "YOUR_PAYLOAD_HERE" // <---- your payload!
}
}],
...
}
For complete payload see this reference: http://docs.smooch.io/rest/#webhooks-payload
On your side, you could have automated messages, event scheduling or anything you want.
A simple payload could be TELL_ME_JOKE and on your backend, you could fetch your database for a joke, then send a message through the Smooch API to reply back.
Another payload could be RESERVE_MONDAY. When the user taps that button, your webhook receives RESERVE_MONDAY. Then you could use that value to know what to do next (call into your application to reserve that time slot).
Here's a simple Node.js implementation:
const express = require('express');
const SmoochCore = require('smooch-core');
const smoochApi = new SmoochCore({
keyId: 'some-key',
secret: 'some-secret',
scope: 'app'
});
express.Router().post('/smooch/webhooks', (req, res) => {
const smoochPayload = req.body.postbacks[0].action.payload;
const userId = req.body.appUser._id;
if (smoochPayload === 'TELL_ME_JOKE') {
smoochApi.conversations.sendMessage(userId, {
text: 'A cow walks into a bar...',
role: 'appMaker'
});
} else if (smoochPayload === 'RESERVE_MONDAY') {
CalendarController.reserve(userId, 'monday');
}
res.end();
});
Using the payload also allows you to use different button labels, but keep the same payload (ie. different translations).
Note: it could be anything even JSON if you want!
I hope this can help you!
The payload is what you want your bot to return. I'm not sure if my way of describing it is the best since I'm new at this. Think of it this way - If you have a button labeled %[Yes](postback:YES), then when the user clicks on the button that says yes, it will be just like they typed the word "yes."
Hi I'm kind of new to Knockoutjs, I am in the scenario where I want to post a form where I have for example an email address, there is an requirement that the email address needs to be unique.
On the server I check if the email address is unique or not and then returns an validationjson class for example
{
isEmailUnique: false,
isPasswordStrongEnough: true;
}
How can I with knockoutjs validation show these errors in a neat way?
I would use two different server side validators for this, since they affect different observables in the view model.
Originally taken from the knockout validation readme
ko.validation.rules['isEmailUnique'] = {
validator: function(val, param){
var isValid = true;
$.ajax({
async: false,
url: '/validation/isEmailUnique',
type: 'POST',
data: { value: val, param: param },
success: function(response){
isValid = response === true;
},
error: function(){
isValid = false; //however you would like to handle this
}
});
return isValid;
},
message: 'The Email is not unique'
};
Then on the server you need to create an endpoint that accepts POST requests where you perform your lookup and then return true or false depending on the result of the query.
To use the above validator
this.email = ko.observable()
.extend({
isEmailUnique: {
message: 'Something else perhaps? It will override the message in the validator'
}
});
You can use the very same thing for the password strength validation.
Using validators like this will fire validation when the observable changes, which can be a useful way to do validation.
I'm a bit late, but for my 2 cents worth, I would take a more generic approach such as returning a standard JSON serialized AjaxResult class from your server endpoints (such as /Register) with properties such as Data (an arbitrary container used for, for example, an updated model to re-bind with the mapping plugin), and a collection of validation message strings, etc. Then you could have an HTML validation summary which is bound to an ObservableArray and push / map the messages from your Ajax result into there. This is essentially what I've been doing with Knockout and it works nicely.