2

I am attempting to post data to a server using Angular $http and I am having no success. I have two issues:

1) The form does nothing when the button is clicked. No POST request is sent. When I add action="include/index.php" to the form element, the POST request is sent, but the page redirects to the PHP script and displays the response. I have tried setting action="".

enter image description here

I have also attempted removing ng-submit from the form and added ng-click on the submit button with no success. I have confirmed that the data is correctly binding to the controller.

2) PHP is not able to read the POST data. Even when using action="include/index.php" on the form and entering valid data, the PHP returns validation errors. It seems PHP is not able to access the data properly.

I've already added json_decode(file_get_contents('php://input')); to the PHP script. I have also tried changing the request content type to 'application/x-www-form-urlencoded'. I have using jQuery's .param on the form data in the controller.

HTTP POST using Angular.js

Angular HTTP post to PHP and undefined

I realize that this question has been asked before, but none of the solutions have worked for me. Any assistance with this would be greatly appreciated.

index.php --the form

<body ng-app="contactApp">
 <div class="col-md-12" ng-controller="contactController">

        <form id="contactForm" ng-submit="submitForm()" role="form" method="POST">

        <legend>Send A Message</legend>

        <div id="result" ng-show="result">{{ result }}</div>

            <div class="form-group" ng-class="{ 'has-error' : errorName }">
                <label for="name">Name</label>
                <input ng-model="formData.name" type="text" class="form-control" name="name" id="name" placeholder="Your Name"> 
                <span class="help-block" ng-show="errorName">{{ errorName }}</span> 
          </div>

            <div class="form-group" ng-class="{ 'has-error' : errorEmail }">
                <label for="email">Email Address</label>
                <input type="email" ng-model="formData.email" class="form-control" name="email" id="email" placeholder="Email">
                <span class="help-block" ng-show="errorEmail">{{ errorEmail }}</span> 
            </div>

           <div class="form-group" ng-class="{ 'has-error' : errorMessage }">
                <label for="message">Message</label>
                <textarea class="form-control" ng-model="formData.message" rows="5" name="message" id="message"></textarea>
                <span class="help-block" ng-show="errorMessage">{{ errorMessage }}</span> 
            </div>

            <div class="form-group" ng-class="{ 'has-error' : errorHuman }">            
                <label for="human">What is 6 + 6 ?</label>
                <input type="text" ng-model="formData.human" class="form-control" id="human" name="human" placeholder="Your Answer">
                <span class="help-block" ng-show="errorHuman">{{ errorHuman }}</span> 
            </div>

         <input type="submit" name="submit" id="submit" value="submit" class="btn btn-default center-block">

    </form>


    </div>

app.js

angular.module('contactApp', [])
.controller('contactController', ['$scope', '$http', function($scope, $http) {
    "use strict";
    $scope.formData = {};
    $scope.submitForm = function() {
        $http({
                method  : 'POST',
                url     : 'include/mail.php',
                data    :  $scope.formData,
                headers : {'Content-Type': 'application/json'} 
        })
        .then(function(response) {
            if (!response.data.success) {     
              $scope.errorName = response.data.errors.name;
              $scope.errorEmail = response.data.errors.email;
              $scope.errorMessage = response.data.errors.message;
              $scope.errorHuman = response.data.errors.human;     
              $scope.message = response.data.result;      
            }     
            else {
              $scope.message = response.data.result;      
            }
        });
    };
}]);

mail.php

<?php
include 'config.php';

$errors = array();
$data = array();

$input = json_decode(file_get_contents('php://input'));

$name = check_input($input -> name);
$email = check_input($input -> email);
$message = check_input($input -> message);  
$human = intval($input -> human);

    // Check if name is entered and only letters
    if ($name === '') {
        $errors['name'] = 'Name is required.';
    } 
    else if (!preg_match("/^[a-zA-Z ]*$/", $name)) {
        $errors['name'] = 'Only letters and spaces allowed.';
    }   
    // Check if email is entered and is a valid email address
    if ($email === '') {
        $errors['email'] = 'Please enter your email address.';
    } 
    else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors['email'] =  'Please enter a valid email address';
    }
    //Check if message is entered
    if ($message === '') {
        $errors['message'] = 'Please enter your message.';
    }
    //Check if anti-bot test is entered and is correct
    if ($human === '') {
        $errors['human'] = "Please enter the answer.";
    }
    else if ($human !== 12) {
        $errors['human'] = 'Wrong answer. Please try again.';
    }

    if (!empty($errors)) {
        $data['success'] = false;
        $data['errors']  = $errors;
        $data['result'] = 'Please correct the errors.';

    }
    else{   
        $to = $toEmail;
        $subject = 'Message from mydomain.com';
        $body = "From: $name\n" . 
                        "E-Mail: $email\n" .
                        "Phone: $phone\n" .
                        "Message: $message\n" . 
                        "IP address: $ip";
        $headers = "From:$email\r\nReply-to:$email";



        if (!mail($to, $subject, $body, $headers)) { 
            $data['success'] = false;
            $data['result'] = 'Message could not be sent. Please try again later';
        }
        else {
            $data['success'] = true;
            $data['result'] = 'Thank you. Your message has been sent.';
        }
    }
    header('Content-Type: application/json');
    echo json_encode($data);


//sanitize data inputs   
function check_input($data) {
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   return $data;
}
?>

EDIT: I have updated my code based on the comments, but this still does not resolve my issues.

Community
  • 1
  • 1
webhead
  • 33
  • 1
  • 3
  • 8
  • Access properties from the `$input` using `->` operator. i.e. `$name = check_input($input -> name);` – Debug Diva Nov 05 '16 at 19:16
  • Thanks for your comment. When I use this format, I get a 500 response: Reload the page to get source for: mydomain.com/include/mail.php – webhead Nov 05 '16 at 20:17
  • 1
    why are you sending $http as param in your submit function, that is unnecessary! you already injected in your controller, so try removing the param from your submit function. – ngCoder Nov 05 '16 at 20:30
  • Check your browser's *Network* console. Can you see the POST request being made? If so, check the request's post data, what does it look like? – Phil Nov 07 '16 at 03:26
  • Also (and I think this is actually your problem), you need to read the response data from the `response.data` property, eg `if (response.data.success)`. See https://docs.angularjs.org/api/ng/service/$http#general-usage – Phil Nov 07 '16 at 03:28
  • With no action attribute set on the form, the POST request never happens. When adding `action="include\mail.php"`, the POST request is valid. Probably because it is bypassing the controller. – webhead Nov 07 '16 at 03:29
  • Forms handled by AngularJS should **not** have an `action` attribute. Are you saying that when you remove it, you're not seeing any POST request in your *Network* console? And you're not seeing any errors in the console? Try enabling "Preserve log" in the console to make sure you're not missing any errors – Phil Nov 07 '16 at 04:31
  • FYI, you don't need to add the `Content-Type` header in Angular. `application/json` is the default – Phil Nov 07 '16 at 04:32
  • @Phil, that is correct. Without the action attribute, there is no POST request, and there are no errors in the log. – webhead Nov 07 '16 at 18:34
  • It looks like you are injecting your dependencies in the wrong order. With `['$scope', '$http', function($http, $scope)`, you are assigning $http to $scope, and $scope to $http. The order is important! I would think that you would see an error in your console stemming from this but perhaps not. Replace that bad boy with `['$scope', '$http', function($scope, $http)` and report back. – jmdarling Nov 21 '16 at 15:16
  • @jmdarling, thanks for the point. I've changed the injection order, but still no POST. I set a breakpoint on the submitForm() call that is not being hit. – webhead Nov 22 '16 at 15:22

0 Answers0