Contact form doesn't transfer data from AngularJS to PHP - php

I am trying to retrieve data from AngularJS file to PHP file, but I get the error that it's empty.
I can't find any good examples that are dealing with posting data from angularJS to php file and so I need help.
Angularjs file:
angular.module('myApp', ['ajoslin.promise-tracker'])
.controller('help', function ($scope, $http, $log, promiseTracker, $timeout) {
$scope.ph_numbr =/[0-9]+/;
// Form submit handler.
$scope.submit = function(form) {
// Trigger validation flag.
$scope.submitted = true;
// If form is invalid, return and let AngularJS show validation errors.
if (!$scope.toggle || $scope.toggle.length <= 0 || form.$invalid) {
return;
}
// Default values for the request.
$scope.progress = promiseTracker('progress');
var config = {
params : {
//'callback' : 'JSON_CALLBACK',
'name' : $scope.name,
'email' : $scope.email,
'toggle' : $scope.toggle,
'phone' : $scope.phone,
'comments' : $scope.comments
},
tracker : 'progress'
};
$http({
method : 'POST',
url : 'js/contact.php',
data: config,
headers : {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
.success(function(data, status, headers, config) {
if (data.success) {
$scope.name = null;
$scope.email = null;
$scope.toggle = null;
$scope.phone = null;
$scope.comments = null;
$scope.messages = 'Your form has been sent!';
$scope.submitted = false;
} else {
$scope.messages = 'Oops, we received your request, but there was an error processing it.';
$log.error(data);
}
})
.error(function(data, status, headers, config) {
$scope.progress = data;
$scope.messages = 'There was a network error. Try again later.';
$log.error(data);
});
// Hide the status message which was set above after 3 seconds.
var promise = $timeout(function() {
$scope.messages = null;
}, 3000);
$scope.progress.addPromise(promise);
};
});
php file:
<?php
/*error_reporting(E_ALL);
ini_set('display_errors', '1');
require_once 'js/PHPMailerAutoload.php';*/
ini_set('display_errors', 'On');
error_reporting(E_ALL | E_STRICT);
$data = file_get_contents("php://input");
$postData = json_decode($data);
if (isset($_POST['name']) && isset($_POST['email']) && isset($_POST['toggle']) && isset($_POST['comments'])) {
//check if any of the inputs are empty
if (empty($_POST['name']) || empty($_POST['email']) || empty($_POST['toggle']) || empty($_POST['comments'])) {
$data = array('success' => false, 'message' => 'Please fill out the form completely.');
echo json_encode($data);
exit;
}
$email = trim($_POST['email']);
$subject = trim($_POST['toggle']);
//email address settings
$my_address = "*#yahoo.com";
$headers = "From: ".$email;
$message = "Name: " . $_POST['name'] . "\r\n\r\nMessage: " . $_POST["phone"] . "\r\n\r\nMessage: " . stripslashes($_POST['comments']);
$to = $my_address;
if (isset($_POST['ref'])) {
$mail->Body .= "\r\n\r\nRef: " . $_POST['ref'];
}
if(!$mail->send()) {
$data = array('success' => false, 'message' => 'Message could not be sent. Mailer Error: ' . $mail->ErrorInfo);
echo json_encode($data);
exit;
}
mail($to, $subject, $message, $headers);
$data = array('success' => true, 'message' => 'Thanks! We have received your message.');
echo json_encode($data);
} else {
$data = array('success' => false, 'message' => 'Please fill out the form completely.');
echo json_encode($data);
}
?>
The error message that I get is: "Please fill out the form completely" - which means it doesn't get the values.
My other question is how in the AngularJS do I retrieve the data.success value from the php file?

You seem to be getting the data here:
$data = file_get_contents("php://input");
$postData = json_decode($data);
but then you're using $_POST instead. Perhaps this would work:
if (empty($postData['name']) //etc
It looks like you're accessing data.success appropriately and the value should be set to false as your code currently is.
Additional code review:
If there are errors on the server, it's best to return a status code that indicates that. As is, the server is returning 200 (default), which means everything is OK, even though the request is actually failing. That would eliminate the need for data.success. If the server sends status 200, your .success function will fire. If it returns an error status, like 404, then your .error function would fire instead.
I have doubts about your need of the Content-Type header. You might want to reconsider if that's necessary.
On your Angular form, you ought to nest those $scope properties in an object:
$scope.formData = {
name: '',
email: '',
//etc
}
Then, you can simply pass that directly to your $http call and to reset the values you can simply do $scope.formData = {}.

Related

Http failure during parsing for - angular http post to php

I am able to consume the php endpoint from postman. I try to do the same from angular post, I get this error - Http failure during parsing for. Even though everything looks perfect to me, the problem is surprising. Here is my snippet
php file
<?php
header('Access-Control-Allow-Origin: *');
// check for post
if ($_SERVER['REQUEST_METHOD']=='POST') {
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
$conn = new db_CONNECT();
$cone=$conn->con;
//escpae the strings to be inserted to DB
$escapedname = mysqli_real_escape_string($cone, $name);
$escapedemail = mysqli_real_escape_string($cone, $email);
$escapedsubject= mysqli_real_escape_string($cone, $subject);
$escapedmessage = mysqli_real_escape_string($cone, $message);
// mysql inserting a new row
$sql = "INSERT INTO contacts(name, email, subject, message) VALUES ('$escapedname', '$escapedemail', '$escapedsubject', '$escapedmessage')";
// $result= $cone -> query($sql);
// $affected = $cone -> affected_rows;
if (mysqli_query($cone,$sql)) {
echo "Information saved successfully.";
} else {
echo "Not successful";
}
} else {
echo "Some field missing.";
}
?>
here is the angular snippet
saveContactDetails = function () {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
data.append('name', this.contactDeJson.name);
data.append('email', this.contactDeJson.email);
data.append('subject', this.contactDeJson.subject);
data.append('message', this.contactDeJson.message);
this.http
.post('http://localhost:80/'+'api/create_contact.php', data.toString(), {headers: myheader})
Please why am I getting this error
{"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK","url":"http://localhost/api/create_contact.php","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://localhost/api/create_contact.php",
I believe the issue is that your angular script is expecting a json response (the default responseType), but not receiving the correct headers or data. In stead of just echoing out your result in php, I would make a function that can handle sending the response. Something like this:
function sendJsonResponse(data, status = 200) {
header('Content-Type: application/json', true, status);
echo json_encode($data);
exit();
}
In stead of of doing this:
echo "Not successful";
You can now do this:
sendJsonResponse("Not successful", 500);
This should give you more valuable information in the frontend. And the response should now be formatted correctly, and no longer produce the parse error in angular that you are getting now.
I believe you are trying to send some query parameters using data variable. You could actually send a JS object as the parameters. Try the following
private saveContactDetails() {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const data = {
'name': this.contactDeJson.name,
'email': this.contactDeJson.email,
'subject': this.contactDeJson.subject,
'message': this.contactDeJson.message
}
this.http.post('http://localhost:80/'+'api/create_contact.php', { params: data }, { headers: myheader })
}

New validation with jQuery doesn't send tha value

I want to make two verifications to Emails.
First to verify if the email is accepted ( that it is not an incorrect mail like gimil.com homail.com ... etc) and second verification to know if email existed.
I try to do with this jQuery code
$('#signup').validate({
errorElement: 'span',
rules:{
Email: {
required: true,
email: true,
remote: {
url: '/verifiyEmail',
type: 'POST', //Or whatever
data: function(){
return $("#email").val(); // The value of the email field
},
dataType: "JSON",
dataFilter: function(responseData){
alert(responseData.message); // Or whatever
return responseData.isValid; // validation result
}
}
}
}
});
and the PHP code
if(isset($_POST['email'])){
$email = $_POST['email'];
$response = null;
$isInBlackList = Member::Accepted($email);
if($isBlackList){
// User is in the blacklist
$response = array("isValid"=>false, "message"=>"This email is blacklisted!"); // Initialize $response
}
else{
$alreadyExists = ! Member::($email); // You have to implement this.
if(!$alreadyExists){
// Email already exists
$response = array("isValid"=>false, "message"=>"This email is already in user"); // Initialize $response
}
else{
// We found a valid email
$response = array("isValid"=>true);
}
}
header('Content-Type: application/json');
echo json_encode($response);
}else{
$response = array("isValid"=>'error');
header('Content-Type: application/json');
echo json_encode($response);
}
And always the response is error, which means the Email is not being sent through the PHP code
Is there any solution?

Ajax call to php mail() script failing on success, no json data is returned

I have a problem with an ajax call to php mail() script failing on success, no json data is returned. It's basically just posting a form to a php script, validating & returning some json.
If I encounter either a validation error the json is returned correctly & my jquery executes as expected.
If NO errors are encountered, PHP processes and sends mail correctly but no data is returned to my jquery script.
Here is my code:
<?php
require "gump.class.php";
$gump = new GUMP();
$mailto = 'me#mydomain.com';
$subject = 'A new form inquiry has been submitted.';
$output = array(
'status' => 'success',
'msg' => 'Mail processed successfully',
'success' => 'success',
);
function render_email($input) {
//error_log("render_email " . print_r($input,TRUE), 0);
ob_start();
include "email-template.phtml";
return ob_get_contents();
}
$input = $gump->sanitize($_POST);
$gump->validation_rules(array(
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required',
//'country' => 'required|valid_email',
//'gender' => 'required|exact_len,1',
//'company' => 'required|valid_cc|max_len,2|min_len,1',
//'bio' => 'required'
));
$gump->filter_rules(array(
'first_name' => 'trim|sanitize_string',
'last_name' => 'trim|sanitize_string',
'email' => 'trim|sanitize_string',
));
$validated = $gump->run($_POST);
if($validated === false){
error_log("GUMP: validation Error: " . print_r($gump->get_readable_errors(true),TRUE));
$output = array(
'status' => 'error',
'msg' => '<strong>Validation Error: </strong>' . $gump->get_readable_errors(true),
'error' => 'error',
);
}else{
error_log("GUMP: Successful Validation, processing mail",0);
// ghead & mail the form
$to = $mailto ;
$subject = $subject;
$body = render_email($input);
$headers = "From: Metz Tea <sales#mydomain.com>" . "\r\n";
$headers .= "Reply-To: sales#mydomain.com\r\n";
$headers .= "Return-Path: info#example.com\r\n";
$headers .= "X-Mailer: PHP\n";
$headers .= "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
if(!mail($to,$subject,$body,$headers)){
$output = array(
'status' => 'error',
'msg' => 'The system failed to send mail.',
'error' => 'error',
);
};
error_log("mail complete",0);
}
header("HTTP/1.1 200 OK");
header('Content-type: application/json');
$output = json_encode($output);
echo $output;
return;
and the jquery:
$('form').submit(function(event){
event.preventDefault();
})
$(document).on("forminvalid.zf.abide", function(event,frm) {
var modal = $('form').closest('.reveal').attr('id');
$(".success").hide();
$(".alert").show();
console.log("Form id "+event.target.id+" is invalid");
formToTop(modal);
}).on("formvalid.zf.abide", function(event,frm) {
console.log("Form id "+event.target.id+" is VALID");
var modal = $('form').closest('.reveal').attr('id');
var data = frm.serializeArray();
$.ajax({
type : 'POST',
url : 'process.php',
data : data,
dataType : 'json',
encode : true
}).done(function(data) {
console.log('completed successfully '+ data);
if (data.status != 'success') {
console.log('AJAX returned error = ' + data.msg);
$('.callout p').html(data.msg);
$('.alert').show();
formToTop(modal);
} else {
console.log( 'AJAX returned success = ' + data.status);
$('.callout p').html(data.msg);
$('#orderform').find("input[type=text], textarea, select").val("");
$('.alert').hide();
$('.success').show();
$('form').slideUp('500');
formToTop(modal);
}
}).fail(function(data) {
//error
});
event.preventDefault();
});
It must be the mail() function somehow, it does send mail on success, but no data is sent back to the ajax script.
what is my error here?
The problem is here:
function render_email($input) {
//error_log("render_email " . print_r($input,TRUE), 0);
ob_start();
include "email-template.phtml";
return ob_get_contents();
}
You've got side-effects both leaving the contents of your rendered template in the buffer, and leaving buffering enabled. You'll want to change this to:
function render_email($input) {
//error_log("render_email " . print_r($input,TRUE), 0);
ob_start();
include "email-template.phtml";
$ret = ob_get_contents();
ob_end_clean();
return $ret;
}

I cannot get the value i send using http post in Angular2 to my PHP backend

The below code is angular2 form submission code,i am sending a test username and password
logForm(formData){
console.log('Form data is ', formData.title);
var link = 'http://test/index.php/api/userAuth';
var headers = new Headers();
headers.append("Content Type","application/json");
var data = JSON.stringify({
username:'user',
password:'user123'
});
this.http.post(link,data,headers)
.subscribe(data => {
console.log(data.json());
});
}
The PHP side is in codeigniter using REST architecture, php code is given below
function userAuth_post() {
if (($this->post('username') == '') || ($this->post('password') == '')) {
$this->response(array('message' => 'Network Error! Try Again!!!'), 200);
}else{
$this->response(array('message' => 'Success'), 200);
}
}
Now i am receiving "Network Error! Try Again!!!", i should be getting "Success".
Edit: I missed the point that it's input stream
Try this instead:
$this->input->input_stream('field');
if ( ! $this->input->input_stream('username') || ! $this->input->input_stream('password')) {
$this->response(array('message' => 'Network Error! Try Again!!!'), 200);
}else{
$this->response(array('message' => 'Success'), 200);
}
this is how you can get php://input in CodeIgniter:
$this->input->raw_input_stream;
Read more: Here
I got it working by using
function userAuth_post() {
$postdata = file_get_contents("php://input");
if (isset($postdata)) {
$request = json_decode($postdata);
$userName = $request->username;
$userPass = $request->password;
}
if (($userName == '') || ($userPass == '')) {
$this->response(array('message' => 'Network Error! Try Again!!!'), 200);
}else{
$this->response(array('message' => 'Success'), 200);
}
}
In Codeigniter we can use
$postdata = $this->input->raw_input_stream;
Don't know whether this is the best answer, but i am going with it now, would be good if someone can correct it if there is an better solution.

Jquery error: Uncaught TypeError: Cannot read property 'length' of undefined

I have a form to call ajax for back-end processing, all input will stored in table and will return 'success' to to notify user the submission is success. But I facing an issue during callback, input data can saved into table but the callback is halted with error below, I have no idea what is goes wrong, the same script was applied to another form (with different form field) are working fine.
console log - Chrome:
Uncaught TypeError: Cannot read property 'length' of undefined
m.extend.each
$.ajax.success
j
k.fireWith
x
b
Firefox
TypeError: a is undefined
...rCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e...
firefox error is pointed to f=a.
Script:
$(document).ready(function() {
$("#status").hide();
$('#btn_submit').click(function(){
var params = $('#project_form').serialize();
var btn = $(this);
btn.button('loading')
$.ajax({
url: baseurl + '/process_form.php',
type: 'POST',
data: params,
dataType: 'json',
success: function(response){
if(response.success == 'success'){
$('#status').html('<b>Thank you</b>').show();
$('html,body').animate({
scrollTop: $('#top').offset().top
},500);
}else{
$('[id$="_error"]').html('');
$.each(response.error, function(key, value){
if(value){
$('#' + key + '_error').html(value);
}
});
}
},
error: function(){
console.log(arguments);
}
}).always(function(){
btn.button('reset')
});
});
});
process_form.php
header("Content-Type: application/json");
$serialized_data = serialize($_POST);
$fullname = $mysqli->real_escape_string(ucwords(strtolower($_POST['fullname'])));
$age = $mysqli->real_escape_string(ucwords(strtolower($_POST['age'])));
$email = $mysqli->real_escape_string(strtolower(trim($_POST['semail'])));
$phone = $mysqli->real_escape_string(trim($_POST['phone']));
$proj_id = preg_replace('/[^0-9]/', '', $mysqli->real_escape_string($_POST['project_id']));
$proj_name = $mysqli->real_escape_string(ucwords(strtolower($_POST['project_name'])));
$agent_id = preg_replace('/[^0-9]/', '', $mysqli->real_escape_string($_POST['agent_id']));
$agent_email = $mysqli->real_escape_string(strtolower(trim($_POST['agent_email'])));
$agent_name = $mysqli->real_escape_string(ucwords(strtolower($_POST['agent_name'])));
$captcha = $_POST['captcha_code'];
$func = new Functions();
$message = array();
// validate
if(empty($fullname) || strlen($fullname) < 2){
$message['error']['fullname'] = 'Your name is required';
}
if(empty($age)){
$message['error']['age'] = 'Your age is required';
}
if(!$func->check_email_address($email)){
$message['error']['semail'] = 'Invalid email address';
}
if(empty($phone) || strlen($phone) < 10){
$message['error']['phone'] = 'Phone num is required';
}
$securimage = new Securimage();
$securecode = $securimage->getCode();
if(strtolower($securecode) != strtolower($captcha)) {
$message['error']['captcha'] = 'Incorrect security code';
}
if(!isset($message['error'])){
// insert table
$create = $mysqli->query("INSERT INTO `xxx` ...") or die($mysqli->error);
if($create){
//send email
$to = xxx;
$subject = 'yyy';
$msg = '<html>
<body>
blah...
</body>
</html>';
$from = zzz;
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
$headers .= 'From: '.$fullname.' <'.$from.'>' . "\r\n";
if(mail($to, $subject, $msg, $headers)){
$message['success'] = 'success';
}
}
}
echo json_encode($message);
change this:
if(response.success == 'success'){
to this:
if(response[0].success == 'success'){
What seems to me, you have an array of object [{}] so response.success is not available that way, instead you can pass the index like suggested in the answer above response[0].success.
I think it is because the mail function failed, and returned false here:
if(mail($to, $subject, $msg, $headers)){
$message['success'] = 'success';
}
so your response neither has success property, nor error property, and this causes an error here:
$.each(response.error, function(key, value){
if(value){
$('#' + key + '_error').html(value);
}
});
You can try something like:
if(mail($to, $subject, $msg, $headers)){
$message['success'] = 'success';
}else{
$message['error']['mail'] = 'Mail error!';
}
or set $message['success'] = 'success'; directly after saving data into table regardless mail success.

Categories