title: Getting correct JSON formatting from an Angular form
body: <p><em>This is an updated version of my original question.</em> 
  I created a feedback form (ff) with a text input and file input, binded with [(ngModel)]="feedback.message" &amp; "feedback.screenshot". </p>
  
  <p>The console gives me this error "JSON.parse: unexpected end of data at line 1 column 1 of the JSON data" 
  either from ff-service or the ff-form component file.</p>
  
  <p>My form:</p>
  
  <pre><code>&lt;form #f="ngForm" (ngSubmit)="onSubmit(f.value)" &gt;
  
              &lt;div class="modal-body"&gt;
                  &lt;p class="lead-text"&gt;&lt;strong&gt;Bel ons&lt;/strong&gt; op &lt;/p&gt;
                  &lt;p&gt;&lt;em&gt;of&lt;/em&gt;&lt;/p&gt;
  
                      &lt;div class="form-group"&gt;
                          &lt;label for="message"&gt;Verzend bericht&lt;/label&gt;
                          &lt;textarea class="form-control" required [(ngModel)]="feedback.message" name="message" #message="ngModel" placeholder="Beschrijf uw vraag, feedback of idee" rows="3" &gt;&lt;/textarea&gt;
                          &lt;div [hidden]="message.valid || message.pristine" class="alert alert-danger"&gt;
                              Geef aub een beschrijving
                          &lt;/div&gt;
                          &lt;label for="screenshot"&gt;Schermafbeelding toevoegen&lt;/label&gt;
                          &lt;input type="file" [(ngModel)]="feedback.screenshot" name="screenshot" #screenshot="ngModel"&gt;
                      &lt;/div&gt;
  
              &lt;/div&gt;
              &lt;div class="modal-footer"&gt;
                  &lt;button type="button" class="btn btn-default" data-dismiss="modal"&gt;Annuleren&lt;/button&gt;
                  &lt;button type="submit" class="btn btn-default" [disabled]="!f.form.valid" &gt;Verzenden&lt;/button&gt;
              &lt;/div&gt;
  
          &lt;/form&gt;
  </code></pre>
  
  <p>Here's my component file. </p>
  
  <pre><code>import { Component, OnInit }    from '@angular/core';
  import { NgForm }               from '@angular/common';
  
  import { Feedback }             from './feedback';
  import { FormService }          from './feedback-form.service';
  
  @Component({
      selector: 'feedback-form',
      templateUrl: 'app/feedback-form.component.html',
      providers: [FormService]
  })
  
  export class FeedbackFormComponent implements OnInit {
      response: string;
      value: string;
  
      constructor(private _formService : FormService){  }
  
      public feedback: Feedback; 
  
      ngOnInit(){
          //initialize form
          this.feedback = {
              message: '',
              screenshot: ''
          }
      }
  
      submitted = false;
  
      onSubmit(form: Feedback) { 
          this._formService.sendMail(form)
              .subscribe(
                  response =&gt; this.response = response,
                  error =&gt; console.log(error)
              )
          this.submitted = true;
      }
  
  
      //TODO remove when we are done 
      get diagnostic(){
          return JSON.stringify(this.feedback);
      }
  }
  
  //https://angular.io/docs/ts/latest/guide/forms.html
  </code></pre>
  
  <p>my form.service.ts file:</p>
  
  <pre><code>    import { Injectable }                               from '@angular/core';
  import { Http, Response, Headers, RequestOptions, URLSearchParams }  from '@angular/http';
  import { Observable }                               from 'rxjs/Observable';
  
  @Injectable()
  
  export class FormService {
      constructor(private _http: Http) {  
         }
      private _mailUrl = 'http://app/form-mailer.php';
  
      sendMail(value: any): Observable&lt;any&gt; {
          const body = new URLSearchParams(value);
          body.set('message',value.message);
          body.set('screenshot',value.screenshot);
  
  
          let headers = new Headers();
          headers.append('Content-Type','application/x-www-form-urlencoded');
          headers.append('Accept','application/json');
          //headers.append('Access-Control-Allow-Origin','*');
          return this._http.post(this._mailUrl, body.toString(), { headers: headers })
              .map(res =&gt; {
                  res.json();
                  console.log();
              })
              .catch(this.handleError)
      }
  
      private handleError (error: any) {
          // In a real world app, we might use a remote logging infrastructure
          let errMsg = (error.message) ? error.message :
          error.status ? `${error.status} - ${error.statusText}` : 'Server error';
          console.error(errMsg); // log to console instead
          return Observable.throw(errMsg);
      }
  }
  </code></pre>
  
  <p>server side php code:</p>
  
  <pre><code>&lt;?php 
  header('Access-Control-Allow-Origin: *');
  header('Access-Control-Allow-Headers: X-Requested-With');
  header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
  header('Content-Type: application/json');
  
  error_reporting(0);
  
  $formData = json_decode(file_get_contents('php://input'));
  foreach ($formData as $key=&gt;$value) {
          $_POST[$key]=$value;
      }
  
  $formMsg            = $_POST['message'];
  $formScreenshot     = $_POST['screenshot'];
  
  $msg = "Message:\n $formMsg\n Screenshot:\n $formScreenshot";
  mail('info@bla.be','Feedback',$msg);
  echo json_encode($formData); 
  ?&gt;
  </code></pre>
  
  <p>Thanks for your help!
  Fred</p>