I am trying to send data from angular to PHP. I am using Angular 5.
Here is my Angular service:
#Injectable()
export class SendDataService {
constructor(private http: HttpClient) {
}
configUrl = 'http://localhost:4200/myQuiz/testing/';
sendData(data:any) {
return this.http.post(this.configUrl, data).map(res=>res.json());
}
}
in view.component.ts
const data = {url: url};
this.sendData.sendData(data).subscribe((status) => {
this.postStatus = status;
});
and in index.php
$postdata = file_get_contents('php://input');
$req = json_decode($postdata);
print_r($postdata);
print_r returns me nothing. Whereas in the section Network of console I see this result
help please
Related
I'm using Angular with PHP and trying to post an object. Request status is 200, but $_POST array is empty. Data I'm sending is a valid JSON Object.
sendTweet(){
if(!this.username || !this.tweet){
alert("Enter username or tweet");
return;
}
const newTweet:Tweet = {
username: this.username,
tweet: this.tweet
}
//Call Service
this.testService.postTweet(newTweet).subscribe((response)=>{console.log(response)},
(err:any)=>{
console.log(err.message);
});
}
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
postTweet(tweet:Tweet):Observable<Tweet>{
const url = `${this.apiUrl}/?page=submit&action=add`;
return this.http.post<Tweet>(url,tweet, httpOptions);
}
PHP:
if (isset($_POST['tweet'])&&isset($_POST['username'])) {
//Sending tweet to the db
} else{
print_r($_POST);
}
i dont know if its a backend problem with php but in my project i have it a little bit diferent (i am using .net core for backend)
for example in my project:
//service component WebScrapLinkService
get(): Observable<Any[]> {
return this.http.get<Any[]>(this.url)
.pipe(map(res => res));
}
//main component
getRegisters() {
this.getProductsSub = this.crudService.get()
.subscribe(data => {
this.registers = data;
})
}
//variables
public registers: Array<object> = [];
//the service goes in the constructor
private crudService: WebScrapLinkService
this works fine for me, i hope it is useful for you
It was just me not knowing that in PHP you have to parse HTTP_RAW_POST_DATA in order to get the data.
Am using Angular2 as front end and php as my server script . I want to pass the user login details to server with the http.get() .
I used like..
var uname = event.email;
var pass = event.password;
this.http
.get('http://192.168.0.100:80/php/logincheck.php?user='+uname+'&pwd='+pass).subscribe();
but it can't get the 2 values. I can simply pass a single value easily.
If 2 values can be passed like this. Please help ..
I do not think it is secured to send a password without doing some sort of encrypting. but if you want to send some data to your server request it is possible to send them in the request headers as well. see below code snippet.
//on import section
import { Http, Headers, RequestOptions } from '#angular/http';
//inside your login function
let requestUrl= "http://192.168.0.100:80/php/logincheck.php"
let requestOptions = new RequestOptions();
requestOptions.headers = new Headers({ 'Content-Type': 'application/json', 'email': event.email,
'pwd': event.password });
this.http.get(requestUrl, this.requestOptions).subscribe();
Try like this :
import { URLSearchParams, BaseRequestOptions } from '#angular/http';
getLogin() {
const options: BaseRequestOptions = new BaseRequestOptions();
const params: URLSearchParams = new URLSearchParams();
params.set('uname', event.email);
params.set('pass', event.password);
options.search = params;
return this.http.get('http://192.168.0.100:80/php/logincheck.php', options)
.map(res => res.json())
}
Server side :
<?php
echo $_GET['uname'];
?>
or
$url = parse_url($url);
parse_str($url['query'], $queryParams);
echo $queryParams['uname'];
echo $queryParams['pass'];
I am using angular 2 as front end and PHP, MySQL for my back end.
PHP properly creates json data but angular 2 unable to read the file content. I am getting the below error.
XMLHttpRequest cannot load http://localhost:81/login.json.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 404.
JSON file available at http://localhost:81/login.json location. I am using XAMPP to run my php file.
My angular 2 code is below.
import { Component, OnInit, Input } from '#angular/core';
import { Http, Response } from '#angular/http';
#Component({
moduleId: module.id,
selector: 'app-header-modal',
templateUrl: './header-modal.component.html',
styleUrls: ['./header-modal.component.css']
})
export class HeaderModalComponent implements OnInit {
private data;
constructor(private http:Http){
}
ngOnInit(){
}
ngAfterViewInit() {
this.getData();
}
getData(){
this.http.get('http://localhost:81/login.json')
.subscribe(res => this.data = res.json());
console.log('User Data: '+this.data);
}
}
My PHP code is below.
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: X-Requested-With");
include 'connect.php';
$username = str_replace(" ", "", $_POST['username']);
$password = str_replace(" ", "", $_POST['password']);
$query = mysql_query("select username, password, id from registration where username='".$username."' and password='".$password."'");
$result = mysql_fetch_array($query);
if($result){
$data = array(
array('userId' => $result['id'],'userName' => $result['username'])
);
$fp = fopen('login.json', 'w');
fwrite($fp, json_encode($data));
fclose($fp);
?>
<script>
history.go(-1);
</script>
<?php
}
?>
Can somebody help!
This appears to be a CORS issue with the php server backend you are trying to use. You angular App doesn't have the ability to make a request to the php server because of CORS.
Once you have properly configured the php server the request should start working.
More information on CORS.
I am new in ionic 2 and try to get my data from php services that i have created for ionic 1. It is works on ionic 1 but when i am getting data from ionic 2 it is undefined. It is works when i am getting data from php server on some website (from tutorial) but when getting my data from my local host it is undefined. It is the problem in my php code or i need to change my services. Thanks...
Here is my php code:
<?php
header('Access-Control-Allow-Origin: *');
$db_name = 'kuliner';
$hostname = 'localhost';
$username = 'root';
$password = '';
$dbh = new PDO("mysql:host=$hostname;dbname=$db_name", $username, $password);
$sql = 'SELECT * FROM promo';
$stmt = $dbh->prepare($sql);
// execute the query
$stmt->execute();
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );
$json = json_encode( $result );
echo $json;
?>
Here is my services:
import {Injectable} from '#angular/core';
import {Http} from '#angular/http';
import 'rxjs/add/operator/map';
/*
Generated class for the PromoService provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class PromoService {
data: any = null;
constructor(public http: Http) {}
load() {
if (this.data) {
// already loaded data
return Promise.resolve(this.data);
}
// don't have the data yet
return new Promise(resolve => {
// We're using Angular Http provider to request the data,
// then on the response it'll map the JSON data to a parsed JS object.
// Next we process the data and resolve the promise with the new data.
this.http.get('http://localhost:9999/KY Mobile/Promo/selectPromo.php')
.map(res => res.json())
.subscribe(data => {
this.data = data.results;
resolve(this.data);
});
});
}
}
My home page:
import {Page} from 'ionic-angular';
import {PromoService} from '../../providers/promo-service/promo-service';
#Page({
templateUrl: 'build/pages/home/home.html',
providers: [PromoService]
})
export class Home {
public promos: any;
constructor(public promoService : PromoService) {
this.loadPromo();
};
loadPromo(){
this.promoService.load()
.then(data => {
this.promos = data;
console.log("ABCD" + data);
});
}
}
My html:
<ion-content padding class="page1">
<ion-list>
<ion-item *ngFor="let promo of promos">
<ion-avatar item-left>
<img src="{{promo.image}}">
</ion-avatar>
</ion-item>
</ion-list>
</ion-content>
Update:
Solved now, the code must be this.data = data in PromoService. Thanks..
If res in
this.http.get('http://localhost:9999/KY Mobile/Promo/selectPromo.php')
.map(res => res.json())
is undefined then you don't get a value from http.get()
Other suggestions
You can use toPromise like
return this.http.get('http://localhost:9999/KY Mobile/Promo/selectPromo.php')
.map(res => res.json())
.do(data => this.data = data.results);
.toPromise();
or just return the promise returned from http.get() and subscribe on the call site
load() {
if (this.data) {
// already loaded data
return Observable.of(this.data);
}
return this.http.get('http://localhost:9999/KY Mobile/Promo/selectPromo.php')
.map(res => res.json())
.do(data => this.data = data.results);
}
and then just use subscribe() instead of then()
loadPromo(){
this.promoService.load()
.subscribe(data => {
this.promos = data;
console.log("ABCD" + data);
});
}
See also What is the correct way to share the result of an Angular 2 Http network call in RxJs 5?
Hint map, do, toPromise, ... need to be imported to become available.
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/toPromise';
or just
import 'rxjs/Rx';
I have had some issues with Promises myself in Ionic2/Angular2. You could try to replace the Promise with an Observable instead in your service:
return Observable.create(observer => {
this.http.get('http://localhost:9999/KY Mobile/Promo/selectPromo.php').map(res =>res.json()).subscribe(data=>{
observer.next(data)
observer.complete();
});
});
Then, in the home page.
loadPromo(){
this.promoService.load().subscribe(data=>{
this.promos = data;
console.log("ABCD" + data);
});
}
While I'm experimenting with angular2 a small obstacle came up:
I have php code witch returns chunks of responses using "ob_flush".
In the front end I successfully made "xhr=XMLHttpRequest" requests and received the responses and handle it using "xhr.onprogress()" and "xhr.onreadystatechange()".
Now when I tried to get the same functionality using angular2 http.get(), I couldn't output the results as they arrive from the server! instead the results are shown by angular at the end of the process after receiving the last response.
I think the rxjs Observer object is buffering the responses!.
So how can I change this behavior?
here is my php code, testing.php:
echo date('H:i:s')." Loading data!";
ob_flush();
flush();
sleep(5);
echo "Ready to run!";
here is my angular2 code:
template: `
<div>
<h3>experimenting!</h3>
<button (click)="callServer()">run the test</button>
<div>the server says: {{msg}}</div>
</div>`
export class AppComponent {
msg:any;
constructor (private http:Http){}
callServer(){
this.http.get("localhost/testing.php")
.subscribe(res=> this.msg= res.text());
}
}
When I run this code it shows after 5 seconds:
(19:59:47 Loading data!Ready to run!).
It should instantly output: (19:59:47 Loading data!).
Then after 5 seconds replaces the previous message with:(Ready to run!)
You need to extend the BrowserXhr class to do that in order to configure the low level XHR object used:
#Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor(private service:ProgressService) {}
build(): any {
let xhr = super.build();
xhr.onprogress = (event) => {
service.progressEventObservable.next(event);
};
return <any>(xhr);
}
}
and override the BrowserXhr provider with the extended:
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
See this question for more details:
Angular 2 HTTP Progress bar
After studying rxjs and reading Angular2 source code, I came up with this solution
I found it's better to make custom_backend, I think this is the recommended approach by angular Dev team.
my_backend.ts
import {Injectable} from "angular2/core";
import {Observable} from "rxjs/Observable";
import {Observer} from "rxjs/Observer";
import {Connection,ConnectionBackend} from "angular2/src/http/interfaces";
import {ReadyState, RequestMethod, ResponseType} from "angular2/src/http/enums";
import {ResponseOptions} from "angular2/src/http/base_response_options";
import {Request} from "angular2/src/http/static_request";
import {Response} from "angular2/src/http/static_response";
import {BrowserXhr} from "angular2/src/http/backends/browser_xhr";
import {Headers} from 'angular2/src/http/headers';
import {isPresent} from 'angular2/src/facade/lang';
import {getResponseURL, isSuccess} from "angular2/src/http/http_utils"
export class MyConnection implements Connection {
readyState: ReadyState;
request: Request;
response: Observable<Response>;
constructor(req: Request, browserXHR: BrowserXhr, baseResponseOptions?: ResponseOptions) {
this.request = req;
this.response = new Observable<Response>((responseObserver: Observer<Response>) => {
let _xhr: XMLHttpRequest = browserXHR.build();
_xhr.open(RequestMethod[req.method].toUpperCase(), req.url);
// save the responses in array
var buffer :string[] = [];
// load event handler
let onLoad = () => {
let body = isPresent(_xhr.response) ? _xhr.response : _xhr.responseText;
//_xhr.respons 1 = "Loading data!"
//_xhr.respons 2 = "Loading data!Ready To Receive Orders."
// we need to fix this proble
// check if the current response text contains the previous then subtract
// NOTE: I think there is better approach to solve this problem.
buffer.push(body);
if(buffer.length>1){
body = buffer[buffer.length-1].replace(buffer[buffer.length-2],'');
}
let headers = Headers.fromResponseHeaderString(_xhr.getAllResponseHeaders());
let url = getResponseURL(_xhr);
let status: number = _xhr.status === 1223 ? 204 : _xhr.status;
let state:number = _xhr.readyState;
if (status === 0) {
status = body ? 200 : 0;
}
var responseOptions = new ResponseOptions({ body, status, headers, url });
if (isPresent(baseResponseOptions)) {
responseOptions = baseResponseOptions.merge(responseOptions);
}
let response = new Response(responseOptions);
//check for the state if not 4 then don't complete the observer
if(state !== 4){
//this will return stream of responses
responseObserver.next(response);
return;
}
else{
responseObserver.complete();
return;
}
responseObserver.error(response);
};
// error event handler
let onError = (err: any) => {
var responseOptions = new ResponseOptions({ body: err, type: ResponseType.Error });
if (isPresent(baseResponseOptions)) {
responseOptions = baseResponseOptions.merge(responseOptions);
}
responseObserver.error(new Response(responseOptions));
};
if (isPresent(req.headers)) {
req.headers.forEach((values, name) => _xhr.setRequestHeader(name, values.join(',')));
}
_xhr.addEventListener('progress', onLoad);
_xhr.addEventListener('load', onLoad);
_xhr.addEventListener('error', onError);
_xhr.send(this.request.text());
return () => {
_xhr.removeEventListener('progress', onLoad);
_xhr.removeEventListener('load', onLoad);
_xhr.removeEventListener('error', onError);
_xhr.abort();
};
});
}
}
#Injectable()
export class MyBackend implements ConnectionBackend {
constructor(private _browserXHR: BrowserXhr, private _baseResponseOptions: ResponseOptions) {}
createConnection(request: Request):MyConnection {
return new MyConnection(request, this._browserXHR, this._baseResponseOptions);
}
}
In the main component we have to provide the custom bakend like this:
providers: [
HTTP_PROVIDERS,
PostSrevice,
MyBackend,
provide(XHRBackend, {useExisting:MyBackend})
]
Now when we use http.get() it will return a stream of Observable