Making Angular 6 php mysql api calls - php

I'm new to the Angular World (I have been using Angularjs all the while).
I want to make a login app and would like to make an api call to the backend (the php and mysql server, running locally on my computer).
In Angularjs, I would write a service like:
(function () {
'use strict';
angular.module('module name').service('userService', user);
function user ($resource) {
return $resource('api/users', {}, {update: {method: PUT}});
}
})();
With that, I could make calls to the server by simply calling
$onInit = function () {
var user = new userService();
user.$save(.....) //post request.
user.$update(....) //put request.
}
In angular, I see things are different. I can't seem to connect to the server using the same code I wrote for AngularJS.
Making an api call like:
this.http.post('api/users', userAccess.value).subscribe(data => {
console.log(data);
}
gives me post http://localhost:3001/api/users 404 not found error.
PS. userAccess is the ReactiveForm formGroup object containing an email address and a password.
The api code sits in a folder under src folder, next to app folder. It has 3 files, api.php, rest.inc.php and the htaccess file. It's my own implementation of an api interface.
Here is my LoginComponent.ts..
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from "#angular/forms";
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.sass']
})
export class LoginComponent implements OnInit {
hide: boolean = true;
constructor(
private fb: FormBuilder,
private http: HttpClient
) { }
ngOnInit() {
}
userAccess: FormGroup = this.fb.group({
email: ['', [Validators.email, Validators.required]],
password: ['', [Validators.required]]
})
onSubmit = () => {
this.http.post('api/users',
{
username: this.userAccess.value.email,
encryption: this.userAccess.value.password
}
).subscribe(data => {
console.log(data);
});
}
getEmailMessage = () => {
return this.userAccess.controls['email'].hasError('required') ? 'Please enter an email address' : this.userAccess.controls['email'].hasError('email') ? 'Not a valid email' : '';
}
}
And here is the folder structure..
Here is the snapshot of the api folder..
This is the error I get no matter what path I put...
How should I go about doing this the right way?

You are getting 404 error that does mean you are able to call HTTP service from your angular code. Please check whether the URL for your API is correct or not. (Hint: Use Browser tools)
In Angular, to access API it is recommended to create a separate service class which can be later injected wherever you require it e.g. component.
You can create service class using following CLI command
ng g s NameOfYourService
Later int the constructor of your service simply inject a reference of HttpClient. Refer below example
constructor(private httpClient:HttpClient)
you can use this reference as shown below
public performUserLogin(cred:Credentials):Promise<void> {
return this.httpClient.post<void>('http://yourhost:yourport/api_path', cred).toPromise();
}
Note you have choice to either return promise or Observable.
For more details you can go through the official documentation.

path you have defined here is incorrect.
this.http.post('http://localhost/project_name/api/api.php',
{
username: this.userAccess.value.email,
encryption: this.userAccess.value.password
}
).subscribe(data => {
console.log(data);
});
change the path of the api folder, bring it to the root folder(at the same level of e2e folder), then do as mentioned.
add these lines to the php file
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');
and to get the data in post request use this
$data = json_decode(file_get_contents("php://input"));

From what I see in the error log, you get this 404 because you are not calling the good url, you try to reach localhost:4200 but you want to call localhost:3001.
On localhost:4200 you certainly have your angular app running if you launched it using the "ng serve" command, because ng serve uses port 4200.
Since you are not specifying the full path in your post, it is trying to reach the url from where you are calling it, here 4200.
So to fix that you should specify the full path in your post like this:
this.http.post('http://localhost:3001/api/users', userAccess.value).subscribe(data => {console.log(data);}
this should fix it, at least it should call your php api.

I got it working. I just added a proxy configuration and run the server on a different port

Related

Problem with CORS loading data from cakephp restapi implementation into angular app

I'm trying to comunicate with an already working RestAPI server developed in PHP (CakePHP framework); i'm trying to make a simple login action in Angular 7 application and if success i will proceed with the implementations.
This is the Angular App call code:
constructor(protected cli: HttpClient) {
this.tablet_couple = new TabletCoupleModule();
}
ngOnInit() {
this.cli.get('http://work.local/grai/api-angular/api/v1/tablet_couples/1.json')
.subscribe(
data => { console.log(data) }
)
this.cli.post('http://work.local/grai/api-angular/api/v1/tablet_couples/login.json',{
username: 'xxxxxxxx',
passoword: '123456789',
})
.subscribe(
data => { console.log(data) }
)
}
The actual problem is that the GET call work fine, but the POST call still no working.
I'm sure the REST API is working correctly because if i use tool like Insomnia the response is correct for both calls.
I try to find why but the problem is every time the CORS implementation:
I have try to force headers in Cakephp as you can see above but still not working.
public function beforeFilter(\Cake\Event\Event $event)
{
parent::beforeFilter($event);
if($this->request->is('OPTIONS')) {
$this->response->header('Access-Control-Allow-Origin','*');
$this->response->header('Access-Control-Allow-Methods','*');
$this->response->header('Access-Control-Allow-Headers','Content-Type, Authorization');
}
else {
$this->response = $this->response->withHeader("Access-Control-Allow-Origin","*");
$this->response = $this->response->withHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
$this->response = $this->response->withHeader("Access-Control-Allow-Methods","*");
}
}
UPDATE 1
I had find a library to integrate CORS with cakephp : cakephp-cors
This help but i still have a problem: i can't use Rest API if they are not on the same domain (ok is CORS) but i need.
IF i deploy the application and put my Angular App on the same domain it works; but i want deploy app that can access remote REST API.
Any suggestion?
Ok, i had a "solution" tanks to the #JensV.
1th :: cakephp 3.1.x is too old
I'm using an OLD version of CakePHP (3.1.14); the 3.1.x is simply too old to manager correctly an OPTIONS Method Call.
Using CakePHP 3.7.* with the plugin cakephp-cors it works correctly and now i can make remote call from localhost:4200 .
2nd :: the Method OPTIONS
This is a method that give me so much pain; this method is called by browsers before a POST method call.
The correct response at this method is a HTTP Code 200 from the server.
If you don't manage this call correctly the browser truncate the POST call.
Again i post some reference about this call and how to find a solution:
CakePHP, preflight & CORS
Handling “XMLHttpRequest” OPTIONS Pre-flight Request in Laravel
I hope it helps someone.

How to connect reactJS front-end with PHP?

I am developing a front-end with ReactJS.
How can I serve this app via PHP (plain PHP or Yii1)?
I suppose you'd want to go through the HTTP Protocol to create communication between the two.
In ReactJSX you want to make a fetch/get call that is provided with an EndPoint/REST from your backend.
// at the beginning of your file
import axios from 'axios';
// in your component constructor
state = {
yourStateWithTheRecievedData: "",
}
// as a component method
componentDidMount = () => {
axios
.get('http://localhost:8080/YourBackendAPI')
.then(response => {
this.setState({
yourStateWithTheRecievedData: response.data.yourStateWithTheRecievedData
})
console.log(response.data.yourStateWithTheRecievedData)
})
}
You should now have a state with the data you've recieved. If you have a hard time doing this, i suggest you start off by first applying it to a public API.
You can find a list of public API's here

Chatbot - Botman functions not working

I am using Botman 2.0 to build a Facebook Messenger chatbot.
Everything is fine with webhook verification and the hear() and reply() methods work well.
But, it looks like other methods don't work.
i.e.
Whenever I use the say() method, it never works. My server receives the request from Messenger, but it does not respond with the message response.
I have test with Botman's main example:
$botman->hears('Hello BotMan!', function($bot) {
$bot->reply('Hello!');
$bot->ask('Whats your name?', function($answer, $bot) {
$bot->say('Welcome '.$answer->getText()); //this never works
});
});
Additionally, when I try to use ButtonTemplate it raises an exception:
PHP Fatal error: Uncaught Error: Class 'ButtonTemplate' not found
Even though Botman's Facebook Driver is loaded:
DriverManager::loadDriver(\BotMan\Drivers\Facebook\FacebookDriver::class);
And my composer.json file looks right:
"require": {
"botman/driver-facebook": "^1.7"
}
What am I missing here?
You need add in your header the following classes:
use BotMan\Drivers\Facebook\Commands\AddStartButtonPayload;
use BotMan\Drivers\Facebook\Commands\AddGreetingText;
use BotMan\Drivers\Facebook\Extensions\ButtonTemplate;
use BotMan\Drivers\Facebook\Extensions\ElementButton;
This works for me. I added the below Facebook extensions immediately after the controller class
use BotMan\Drivers\Facebook\Extensions\Element as Element;
use BotMan\Drivers\Facebook\Extensions\ElementButton as ElementButton;
use BotMan\Drivers\Facebook\Extensions\ButtonTemplate as ButtonTemplate;
use BotMan\Drivers\Facebook\Extensions\GenericTemplate as GenericTemplate;
use BotMan\Drivers\Facebook\Extensions\ListTemplate as ListTemplate;
$botman = resolve('botman');
$botman->hears('Hello BotMan!', function($bot) {
$bot->reply('Hello!');
$bot->ask('Whats your name?', function($answer, $bot) {
$bot->say('Welcome '.$answer->getText()); //this works
});
});
You can check from this link as well https://www.gitmemory.com/issue/botman/botman/1055/522233149

How to solve 'Access-Control-Allow-Origin' header is present on the requests Error in Angular 2? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am getting this Error:
XMLHttpRequest cannot load https://heroku-app-php.herokuapp.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access.
test.service.ts
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class testService {
constructor (
private http: Http
) {}
getUser() {
var tries = this.http.get(`https://heroku-app-php.herokuapp.com/`)
.map((res:Response) => res.json());
console.log("Res done");
return tries;
}
}
test.component.ts
import { Component } from '#angular/core';
import { testService } from './test.service';
#Component({
selector: 'home-page',
template: `
<div>
<button (click)="loadUser()">Load profile</button>
{{ profile | json }}
</div>
`
})
export class testComponent {
constructor(private testService: testService) {}
profile = {};
loadUser() {
this.testService.getUser().subscribe(data => this.profile = data);
}
}
By default no server side allow requests from external domains you should enable cors. Read this article.
https://enable-cors.org/server_expressjs.html
And remember cors enable before you pass anything to app.use.
You need to add 'withCredentials' as an header to the request.
Something like :
this.http.get(`https://heroku-app-php.herokuapp.com/`,{ 'withCredentials': true})
More on that you can read here
This happens when the app is running on a different server than the backend.
I assume you try to make the api request while running on your local machine using ng serve. This however will work just fine when the code is uploaded on the same server as the backend API.
https://github.com/angular/angular-cli/issues/2872
As of now there is a ticket for providing support for CORS via Angular-cli but until then you You can fix this by using reverse-proxy or proxy middleware to bypass this.

how to use angularJS with PHP class and call a specific function of PHP?

I am totally new in AngularJS and I am using PHP as the server script.
I have a PHP class with connection() and getUsers() functions:
public function connect()
{
$this->connection = new PDO("mysql:host={$this->db_host};dbname={$this->db_name}", $this->db_user, $this->db_pass);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $this->connection;
}
public function getUsers()
{
this->connect = this->connect();
$sql = "SELECT * FROM login";
$stmt = this->connect->prepare($sql);
$stmt->execute();
$res = $stmt->fetchAll();
return json_encode($res);
}
I am stuck at the angular part. How to call a function inside a url using $http.get() ?
$http.get('/angular/conn.php')
.success(function(result)
{
$scope.user = result;
})
.error(function(data, status)
{
$log.log(status);
});
And another question on the side: when using angular with php their is no need to call the class and the function that we should use at the top of each html page ?
You have to understand how the client/server architecture works for Angular. Angular is built to work along a web service, which is responsible for providing among other things, database access. The way you communicate with a web service is through API calls often made with AJAX. You can't simply call a php method from an Angular app like you would from another php class/script. You would have to design a web service in php in order to communicate with it.
Since you are trying to access a resoutce using a GET method on '/angular/conn.php', then your PHP web service should have a way to parse requests and respond accordingly considering the HTTP method, resource name, HTTP headers, etc. Since Angular is meant to work along REST web services, I would recommend you to use a PHP framework that fits such purpose. For example: Slim Framework
Here are some references you might find useful:
What exactly is RESTful programming?
REST Web Services
well the examples i saw where using then when you use GET method for example:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http({
method : "GET",
url : "your url here"
}).then(function mySucces(response) {
$scope.myWelcome = response.data;
}, function myError(response) {
$scope.myWelcome = response.statusText;
});
});
try to put your complete url like: localhost:8080/mypage.php
and print in console the result,
you can first make the request in the browser to check if the server is responding the request

Categories