Search code examples
phpangularangular-httpclient

httpClient Angular to PHP data sending issue


I have a small project I'm trying to do where some user can input some data into a text box which is then sent to a php server, I previously didn't use angular when I had it working before but am now trying to utilise angular and php together.

My issue is that once I click "submit" the data that's sent to a .txt file either prints 'array' using $_POST or nothing using $_HTTP_RAW_POST_DATA.

app.component.ts:

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
 data: string;
 userInput: any;
 @ViewChild('toSend') input: ElementRef;

 constructor(private http: HttpClient) {
 }
  toSend = JSON.stringify(this.input);
  ngOnInit(): void {

  }

  postData() {
  const newInput = {
    text: this.input.nativeElement.value
   };
  console.log(this.input.nativeElement.value);
  this.http.post('http://localhost:81/test.php', this.toSend)
  .subscribe(
    res => {
      console.log(res);
     }
    );
  }

   requestData() {
   this.http.get('http://localhost:81/test.php').subscribe(
      data => {
        const myJSON = JSON.stringify(data);
        console.log(myJSON);
      }
     );
   }
}

php:

<?php

echo $_POST;

$myfile = fopen("TestingOut.txt", "a++") or die("Unable to open file!");
$txt = $HTTP_RAW_POST_DATA."\r\n";
fwrite($myfile, $txt);
fclose($myfile);
?>

app.component.html:

 <div style="text-align: center; padding-top: 10px">
 <input    type="text"
        id="inputText"
        placeholder="Insert Input"
        #toSend
        >
    <p></p>
  <button type='submit' (click)='postData()' >Submit Data</button>
  <br>
  <hr>
  <button (click)='requestData()'>Request Data</button>
</div>

Solution

  • If You are accessing DOM element using @viewChild you need wait for the AfterViewInit lifecycle hook to access the variable, as this is when child components ,DOM Elements and directives become available. But it's not required in your case since you are using Template reference variable you can pass the value of input control as a parameter to post data method using toSend.value

       <div style="text-align: center; padding-top: 10px">
         <input    type="text"
                id="inputText"
                placeholder="Insert Input"
                #toSend
                >
            <p></p>
          <button type='submit' (click)='postData(toSend.value)' >Submit Data</button>
          <br>
          <hr>
          <button (click)='requestData()'>Request Data</button>
        </div>
    

    Component:

    import { Component, OnInit, ViewChild, ElementRef,AfterViewInit } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit,AfterViewInit{
     data: string;
     userInput: any;
     toSend:any
     @ViewChild('toSend') input: ElementRef;
    
     constructor(private http: HttpClient) {
     }
    
      ngOnInit(): void {
    
      }
      ngAfterViewInit() {
           this.toSend=this.input
     }
      postData(value) {
    
      this.http.post('http://localhost:81/test.php', value)
      .subscribe(
        res => {
          console.log(res);
         }
        );
      }
    
       requestData() {
       this.http.get('http://localhost:81/test.php').subscribe(
          data => {
            const myJSON = JSON.stringify(data);
            console.log(myJSON);
          }
         );
       }
    }
    

    Or if you want to go with @viewChild you need to use observable.

      import {Observable,fromEvent} from 'rxjs'; 
        import {pluck} from 'rxjs/operators
        export class Appcomponent implements OnInit,AfterViewInit{
        @ViewChild('toSend') input: ElementRef;
        Input$:Observable<any>;
         toSend:any
        ngAfterViewInit() {
               this.Input$=fromEvent(this.input.nativeElement,'input');
               this.Input$.pipe(pluck('target','value')).subscribe(value=>{
                this.toSend=value;
                console.log(this.data)});
             }
    
        postData() {
    
          console.log(this.input.nativeElement.value);
          this.http.post('http://localhost:81/test.php', this.toSend)
        }
    

    fromEvent: Turns event into observable sequence
    pluck:Select properties to emit.