So, I have a simple crud Angular web application and for some reason when i try to do an http.post to a php nothing happens. Sorry but i know nothing about web apps and php and i have to deliver this.
Service that contains the call (basically the line that calls the post php is in the update method, but i include all the file because i dont know if there is something wrong elsewhere):
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class DbService {
public headers:Headers;
constructor(public http:Http) {
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
}
getStock(){
return this.http.get('http://localhost/api/stock/read.php').map(res => res.json());
}
getSales(){
return this.http.get('http://localhost/api/ventas/read.php').map(res => res.json());
}
updateDB(member:string){
let data:Data;
data = {name:member};
console.log(data.name);
this.http.post('http://localhost/api/productos/create.php',
JSON.stringify(data),
{
method: 'POST',
headers: this.headers
});
}
}
interface CarrItem{
id: number,
name: string,
price: number,
stock: number,
quantity: number
}
interface Data{
name: string
}
And this is the php, it works when used in a web browser, i knw cause it inserts correctly into the database.
<?php
// required headers
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
header("Content-Type: application/json; charset=UTF-8");
header("Accept: application/json;");
require '../config/database.php';
$m_name = "20:23";
$pdo = Database::connect();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if(strlen($m_name)>0){
$insertMember = $pdo->prepare("INSERT INTO member(membershipType, firstName, lastName, sex, birthDate, accumulatedPurchases) values('Dorada', ?, 'M', 'Other', '2018-1-1', 50.0)");
$insertMember->execute(array($m_name));
$otra = $pdo->prepare("INSERT INTO brand(brandName) values('SI')");
$otra->execute();
}
else{
$otra = $pdo->prepare("INSERT INTO brand(brandName) values('NO')");
$otra->execute();
}
Database::disconnect();
?>
First, I think it is working in your browser because you are doing a GET (not a POST) and you are not using any request parameters in your code above. As-is, your code will run into problems getting the request data.
POST-ing JSON data to PHP is a little complex. PHP will not automatically parse the data for you. Instead, you'll have to do something like ...
$jsonEncoded = file_get_contents('php://input');
$jsonDecoded = (array) json_decode($jsonEncoded, true);
INSTEAD OF THAT, MIGHT BE EASIER ... to just let Angular send the data in old-style application/x-www-form-urlencoded format and let PHP auto-parse it into $_POST for you.
let body = new URLSearchParams();
body.set('name', member);
body.set('age', 28);
this.http.post(my_url, body);
Related
I'm new in Angular, and i'm developing a login auth service, but i'm gettin some troubles to make the post data for an backend developed in CodeIgniter.
I'm sending: username and userpassword, to URL: http://192.168.1.162/advance-managemente_2.1/login
Follow my code:
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { UserData } from './login/user.model';
#Injectable({
providedIn: 'root'
})
export class AuthService {
constructor(private http: HttpClient) { }
userData: UserData;
getUserDetails(username, userpassword) {
console.log(username, userpassword);
const userdata = JSON.stringify({user: {login: username, password: userpassword}});
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
console.log(userdata);
// post these details to API server return user info if correct.
return this.http.post(`http://192.168.1.162/advance-management_2.0/login`, userdata, {headers: headers, observe: 'response'})
.subscribe(res => {
console.log(res);
},
err => {
console.error(err);
});
}
}
And my console:
Note: my variables with username and userpassword is working.
And in codeigniter's backend project is setted these headers:
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Access-Control-Allow-Origin');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
And the function os codeigniter is:
function login(){
$json = $this->input->post('user');
echo json_encode($json);
}
If you observe, my login function have an ECHO with json_encode of i'm sending to her.
But, in console, the body is returning NULL.
I'd like to know what I might be doing wrong, and how to fix it, because it was for him to return a JSON, but it does not seem to be identifying my POST.
Thanks to anyone who can help,
Have a nice day!
I'm trying to POST data to a PHP backend and receive back the values and push it into an array. Hence, I created a function to do just that. However, I'm not to change the API on the backend (written in PHP). So I cannot change it to suit my normal methods of using POST.
This is my function
test() {
let data = "method=getThis" + "&db=myDatabase"
this.http.post("API URL", data).subscribe(data => {
this.result = data; // get data in result variable
this.items = JSON.stringify(this.result); // then convert data to json string
// console.log(this.items);
this.allData = JSON.parse(this.items); // parse json data and pass json string
// console.log(this.allData.length); // got result of particular string
this.array = [];
for (var i = 0; i < this.allData.length; i++) {
this.array.push({
data1: this.allData[i].data1,
data2: this.allData[i].data2,
})
}
console.log(this.array[0])
})
}
And this is an example function on the backend
else if($_POST['method']=="getThis"){
global $conn;
mysqli_select_db($conn, $_POST['db']);
$name="";
$result=array();
$r=mysqli_query($conn,"select data1,data2 from table");
while ($rs = mysqli_fetch_array($r,MYSQLI_ASSOC)){
array_push($result,$rs);
}
echo json_encode(array("result"=>$result));
}
So how do I actually get it to post? I'm stuck here. I usually post with JSON and then decode the JSON on the backend. But this time around I'm not developing the backend and not changing it so gotta use the one provided.
Posting using POSTMAN with this
method=getThis&db=myDatabase
works well. Not sending JSON just a text. So how do I actually achieve this in Ionic.
You could try it that way. It works for me:
First import:
import { map } from "rxjs/operators/map";
Your function:
test() {
let data = "method=getThis" + "&db=myDatabase"
this.http.post("API URL", data).pipe(
map(res => res.json())
).subscribe(response => {
//Here your code
// 'response' is json
});
}
Since the data you are sending is in plain text, you will need to add a header mentioning the content type.
import { HttpHeaders } from '#angular/common/http';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'text/html'
})
};
this.http.post("API URL", data, httpOptions).subscribe()
PHP side should be return JSON and told browser content type is application/json, please test your code base on one simple page.
//demo.php
<?php
$data = ['message' => 'Hello world.'];
header("Content-Type: application/json; charset=UTF-8");
//If allow cross domain and not configration in Ngix/Apache
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Accept-Encoding, X-Requested-With, Content-Type, Origin, Accept, Authenticationtoken");
echo json_encode($data);
And please try http access demo.php again.
This is the first time I'm making a post method request from Angular to CodeIgniter rest API.
postUsertask(Userid,TaskName)
{
let body ={
userid:Userid, taskname:TaskName
};
console.log(body);
return this.http.post("http://localhost/ci-abc/api/add_task",JSON.stringify(body) )
.map(res => res.json());
}
API method in codeigniter:
function add_task_post()
{
$obj=json_decode(file_get_contents('php://input'));
$taskname = $obj->taskname;
$userid = $obj->userid;
if (!$taskname || !$userid) {
$this->response("Enter taskname and userid to add", 400);
} else
$result = $this->todo_model->add_task($taskname, $userid);
if ($result === 0) {
$this->response("Task could not be added. Try again.", 404);
} else {
$this->response("success", 200);
}
}
Had to include to access the data
$obj=json_decode(file_get_contents('php://input'));
Because the $this->input->post and $_POST were empty and the data recieved from angular was an object so had to be accessed with -> notation. I am curious that this is not the right and ethical way to do this. Also when I didn't put JSON.stringify it gave me Cross Origin Request blocked error so that's why I put it. How should I make POST and PUT request in angular4 to rest API in CodeIgniter?
How do I get rid of CORS error which doesn't let me call the API method, if I can get rid of CORS error then I could also remove JSON.stringify which will send the data as it is and I believe the data should be accessed via input->post or $_POST.
EDIT 2:
These sort of errors while making POST PUT and DELETE API call.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://localhost/ci-abc/api/del_task?taskid=34.
(Reason: CORS preflight channel did not succeed)
EDIT (Perfect Solution):
Found out that the formdata object approach was deprecated so I just included a header in options and included in the API call http.post method which works fine and is much better solution.
constructor(public http:Http) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({ headers: headers });}
createUser(userName)
{
let body = { username:userName};
return this.http.post("http://localhost/ci-abc/api/create_user",body,this.options)
.map(res => res.json());
}
Deprecated approach (Works but deprecated/not usual practice):
Took few hours but found the solution, I created body as a new formdata object, appended parameters to it as key and their values and it worked fine now I am retrieving through $this->input->post.
let body = new FormData;
body.append('userid', Userid);
body.append('taskname', TaskName);
console.log(body);
return this.http.post("http://localhost/ci-abc/api/add_task",body)
.map(res => res.json());
Using these headers in the constructor of my codeigniters API controller
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Access-Control-Allow-Origin');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
API method:
function add_task_post()
{
$userid = $this->input->post('userid');
$taskname = $this->input->post('taskname');
if (!$taskname || !$userid) {
$this->response("Enter taskname and userid to add", 400);
} else
$result = $this->todo_model->add_task($taskname, $userid);
if ($result === 0) {
$this->response("Task could not be added. Try again.", 404);
} else {
$this->response("success", 200);
}
}
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'm trying to recreate Post JSON from angular 2 to php but it doesn't work as there's nothing in the $_REQUEST variable on php side
The code:
searchHttp({body}: any): Promise<any>
{
let headers = new Headers ({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers, method: "post" });
let test_this = {"search": "person"};
return this.http.post(this.post_url, JSON.stringify(test_this), options)
.toPromise()
.then(response =>
{
return response.text();
})
.catch(this.handleError);
}
Is there something I'm missing? I know that posts works with another format because I have that answered in another question.
Also, is http.request better than http.post?
Edit:
After much consultation with Angular/Javascript experts, they believe this is a php issue. So anyone with knowledge of how to accept JSON objects on php side will be gladly welcomed.
angular 2 client side part
ngOnInit() {
let body=Api+'product.php'+'?id=' + this.link_id;
this._callservice.callregister(body)
.subscribe( data => {
this.outputs=data;
},
error => console.log("Error HTTP Post"),
() => console.log("completed") );
}
}
call.service.ts
import {Injectable} from '#angular/core';
import {Router} from '#angular/router';
import {Http, Response, Headers, RequestOptions} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
#Injectable()
export class AuthenticationService {
constructor(private _http:Http){}
postregister(api:any){
// console.log(api);
let headers = new Headers({'Content-Type':'application/x-www-form-urlencoded'});
let options = new RequestOptions({ headers: headers, method: "post"});
return this._http.get(api,options)
.map(res => res.json())
.catch(this.handleError);
}
private handleError (error: Response) {
console.error(error);
return Observable.throw(error.json().error || ' error');
}
}
Server side PHP
make sure on server side you have these three lines in php code.
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
Php file:
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
$servername = "localhost";
$username1 = "root";
$password = "root";
$dbname = "product";
$e=array("error"=>1,"message"=>"Account Already Exists");
$accountCreated = array( "error" =>0,
"data" => array(
"username" => "amit" ,
"password" => "anypassword",
"role"=> "user",
"id" => "anyid" ) );
// Create connection
$conn = mysqli_connect($servername, $username1, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$username = $_GET["username"];
$Pass = $_GET["password"];
$role= $_GET["role"];
$sql="SELECT COUNT(*) as user FROM users WHERE username = '$username'";
$result = mysqli_query($conn,$sql);
$line = mysqli_fetch_assoc($result);
$count = $line['user'];
if($count!=0)
{
echo json_encode($e);
}
else
{
$sql="INSERT INTO users(username,password,role)VALUES('$username','$Pass','$role')";
$result=mysqli_query($conn,$sql);
$sql="select * from users where username ='$username'";
$result=mysqli_query($conn,$sql);
$line=mysqli_fetch_assoc($result);
{
$accountCreated['data']['username']=$line['username'];
$accountCreated['data']['password']=$line['password'];
$accountCreated['data']['role']=$line['role'];
$accountCreated['data']['id']=$line['id'];
}
echo json_encode($accountCreated);
}
?>
i hope this will work for you .. for json i guess you should pass as options and use json decode for values you get in options.
There doesn't appear to be anything wrong with the Angular code. The issue is in what the PHP is expecting to receive. I am not a PHP expert, but as you've mentioned that it works fine with jQuery, then that indicates that your PHP is expecting a URL-encoded value (as jQuery tends to work with that), not a JSON value.
In other words, what the server is trying to parse is:
search=person
What you are sending is:
{ "search": "person" }
Try something more like the following to send it in the format you're wanting:
let test_this = { "search": "person" };
let headers = new Headers ({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers, method: "post" });
http.post(this.post_url, test_this, options)