8

I'm trying to send form values from Ionic2(Angular2 typescript) project to a php server in which I will send contact mail.

I can't get the values I'm supposed to...

Here is my form.service.ts:

import {Injectable}               from 'angular2/core';
import {Http, Response}           from 'angular2/http';
import {Headers, RequestOptions}  from 'angular2/http';
import {Observable}               from 'rxjs/Observable';

@Injectable()
export class FormService {
  constructor (private _http: Http) {}

  private _contactUrl = 'http://localhost:8888/Server/email.php';
  // private _contactUrl = '/email';

  sendMail(value: Object): Observable<any> {
    const body = JSON.stringify(value);
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-urlencoded');
    return this._http.post(this._contactUrl, body, {
      headers : headers
    }).map(res => res.json());
  }
}

Which is used from my onSubmit function in my form.ts:

import { Page, NavController } from 'ionic-angular';
import { Component } from 'angular2/core';
import { FORM_DIRECTIVES, FormBuilder,  ControlGroup, Validators, AbstractControl } from 'angular2/common';
import { Http, Response, Headers } from 'angular2/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import { FormService} from './form.service';

@Page({
    templateUrl: 'build/pages/form/form.html',
    directives: [FORM_DIRECTIVES],
    providers: [FormService]
})

export class Form {

  contactForm: ControlGroup;
  company: AbstractControl;
  name: AbstractControl;
  prenom: AbstractControl;
  phone: AbstractControl;
  email: AbstractControl;
  website: AbstractControl;
  message: AbstractControl;

  arrivee: AbstractControl;
  projet: AbstractControl;

  projets = [
    { id: 1, label: 'Site Internet' },
    { id: 2, label: 'Site Intranet/Extranet' },
    { id: 3, label: 'Développement PHP' },
    { id: 4, label: 'Développement C#' },
    { id: 5, label: 'Conception Base de Données' },
    { id: 6, label: 'Tiers Maintenance Applicative' },
    { id: 7, label: "Recrutement d'un collaborateur Handicapé" }
  ];
  arrivees = [
    { id: 1, label: 'Internet' },
    { id: 2, label: 'Recommandation' },
    { id: 3, label: 'Evênement' }
  ];

  response: string;
  value: any;

  constructor(public nav: NavController, fb: FormBuilder, private _http: Http, private _formService: FormService) {
        this.nav = nav;

        // New controlGroup instance
        this.contactForm = fb.group({
          // Validators Rules for each field
          // Champ XXX: ['', ...] correspondants au [ngFormControl]="XXX" de la vue HTML (inpput)
          name: ['', Validators.compose([Validators.required, Validators.minLength(3), this.checkFirstCharacterValidator])],
          prenom: ['', Validators.compose([Validators.minLength(3), this.checkFirstCharacterValidator])],
          company: ['', Validators.compose([Validators.required, Validators.minLength(3), this.checkFirstCharacterValidator])],
          projet: ['', Validators.required],
          arrivee: ['', Validators.required],
          phone: ['', Validators.compose([Validators.required, Validators.minLength(10)])],
          email: ['', Validators.required],
          website: ['', Validators.minLength(3)],
          message: ['', Validators.compose([Validators.required, Validators.minLength(20)])]
        });

    this.name =     this.contactForm.controls['name'];
    this.prenom =   this.contactForm.controls['prenom'];
    this.company =  this.contactForm.controls['company'];
    this.projet =   this.contactForm.controls['projet'];
    this.arrivee =  this.contactForm.controls['arrivee'],
    this.phone =    this.contactForm.controls['phone'],
    this.email =    this.contactForm.controls['email'],
    this.website =  this.contactForm.controls['website'],
    this.message =  this.contactForm.controls['message']
  }

// Check if firt character is a number
  checkFirstCharacterValidator(control: Control): { [s: string]: boolean } {
      if (control.value.match(/^\d/)) {
          return { checkFirstCharacterValidator: true };
      }
  }

  onSubmit(value) {
    this._formService.sendMail({value})
      .subscribe(
        response => this.response = response,
        error => console.log(error)
      );
  }
}

And in my email.php file I'm trying to get the POST:

<?php
header('Content-type: application/json');

    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
            header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
            header("Access-Control-Allow-Headers:        {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
        exit(0);
    }

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

// for test     
echo $value->name;

?>

I checked in chrome's console, I'm getting something: Screenshot from console

How can I get the post from angular2 into my php? Am I missing something?

3 Answers 3

8

I can see two problems in your code:

  • You create a JSON content with JSON.stringify but for forms, you need to use the URLSearchParams class or create the string content by hand.
  • You content type value isn't correct. It's application/x-www-form-urlencoded and not application/x-www-urlencoded.

Here is what you should use instead:

sendMail(value: Object): Observable<any> {
  const body = new URLSearchParams();
  Object.keys(value).forEach(key => {
    body.set(key, value[key]);
  }

  let headers = new Headers();
  headers.append('Content-Type',
     'application/x-www-form-urlencoded');
  return this._http.post(this._contactUrl, body.toString(), {
    headers : headers
  }).map(res => res.json());
}
Sign up to request clarification or add additional context in comments.

15 Comments

Which properties am I supposed to add in the URLSearchParams? Do the content-type is 'application/application/x-www-form-urlencoded' or 'application/x-www-form-urlencoded'? Merci!
Regarding the properties, I suppose of the ones from your value object... What do you want to send to the server: JSON content or form? I also updated my answer...
I'm building a contact form, so yes it's a form.
Do you import both Headers and URLSearchParams classes from the angular2/http module?
Could you provide what you have within the dev tools in the network tab? To see what is actually sent... Will be helpful to debug your problem
|
4

I managed to get it working, it was only:

  sendMail(value: any): Observable<any> {
    const body = new URLSearchParams(value);
    body.set('name', value.name);
    body.set('company', value.company);
    body.set('projet', value.projet);
    body.set('arrivee', value.arrivee);
    body.set('phone', value.phone);
    body.set('email', value.email);
    body.set('website', value.website);
    body.set('message', value.message);
    body.set('name', value.name);

    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    return this._http.post(this._contactUrl, body.toString(), {
      headers : headers
    }).map(res => res.json());
  }

And in the form.php:

<?php header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');

$formData = json_decode(file_get_contents('php://input'));
    foreach ($formData as $key=>$value) {
        $_POST[$key]=$value;
    }

$formObject = $_POST['name'];
(...) ?>

Thanks to Thierry Templier for his precious help.

Comments

1

Maybe for someone it will be useful. I had a problem with nested objects - with passing to PHP objects like this:

var obj = {
        value: 1,
        innerObj: {
            title: "title",
            innerObject: {
                value: 1
            }
        }
    };

I resolved it by using querystring parser

Example of using:

//at top of you .ts file
let qs = require('qs');

return this.http.post(url, qs.stringify(data), {headers: this.postHeader})
    .map((resp: Response) => resp.json())
    .catch((error: any) => Observable.throw(error) || 'Server error');

It is also will be useful for not nested objects

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.