angular 2 app response from Slim php is net::ERR_EMPTY_RESPONSE - rest

Hi everyone,
this is the code in slim php:
$app->post('/checkSignIn', function () use ($app) {
$params = $app->request->post()['body'] ;
if(!empty($params))
{
$jsonRequest = json_decode($params);
//echo $jsonRequest->email;
$delikatesDbConnect = new DelikatesDbConnect ('localhost', 'gontar_delikates', 'DgDgDg11', 'gontar_delikates');
$id = $delikatesDbConnect->findUserIdByMail($jsonRequest->email);
//echo $id;
if ($id>0) // if $id exists fetch hashed password and email_verfied values
{
$hashed_password = $delikatesDbConnect->findPasswordById($id);
$email_verified = $delikatesDbConnect->findEmailVerifiedById($id);
if (password_verify($jsonRequest->password,$hashed_password) and ($email_verified))
{
$arr = $delikatesDbConnect->json_user_details($id);
$jsonResponse = json_encode($arr);
$response = new HttpResponse($jsonResponse,202);
return $response;
}
else
{
return '';
}
}
else
{
return '';
}
}
else
{
return '';
}
})->name('register');
this is the request code in typscript ng2:
sendUserAndPass(userDetails:JSON)
{
const body = JSON.stringify(userDetails);
console.log(body);
const headers = new Headers();
headers.append('Content-Type','application/json');
this.http.post("http://www.delikates.co.il/backend/checkSignIn", body, {headers: headers})
.subscribe((data:Response)=>console.log(data));
}
Why do i get in chrome console err message like that :
OPTIONS http://www.delikates.co.il/backend/checkSignIn net::ERR_EMPTY_RESPONSE
EXCEPTION: Response with status: 0 for URL: null
Uncaught Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers…}

This seems like an issue with how you are handling the response. What is HttpResponse?
A typical way of handling responses is to use the existing response object and write to that.
return $response->withJson($arr, 202);
https://www.slimframework.com/docs/objects/response.html#returning-json

Related

Why is Flutter Dart application throwing an XMLHttpRequest error when test programme and POSTMAN do not?

I have an application that was working doing http.get requests on an Ubuntu virtual machine hosting a postgres DB and an API using Hapi/node. The VM disk become corrpupted and following the rebuild, the http.get now throws an XMLHttpRequest error. However, a test programme doing the same request works fine and a test GET using POSTMAN works fine as well. I'm stumped as to why this is the case.
The code that is throwing the error is as follows (the getScores() function):
import 'package:noxo/functions.dart' as func;
import 'dart:convert';
import 'package:http/http.dart' as http;
class DataManager {
Map<dynamic, dynamic> results = {}; // Return values from DB parameter query
double difficulty = 5; // Level of difficulty (1- easiest to 5-hardest)
// Address of API for data requests
final _apiAddress = 'http://192.168.1.201:4044/';
bool _httpAvailable = true; // Assume that http is available
int getHumanScore() {
func.debugPrint('httpAvailable is $_httpAvailable');
if (_httpAvailable && results.isNotEmpty) {
func.debugPrint('Returning HUMAN score');
return results['humanwin'];
} else {
return 0;
}
}
int getDrawScore() {
if (_httpAvailable && results.isNotEmpty) {
return results['draws'];
} else {
return 0;
}
}
int getComputerScore() {
if (_httpAvailable && results.isNotEmpty) {
return results['computerwin'];
} else {
return 0;
}
}
void setDifficulty(double value) {
func.debugPrint('Set difficulty = $value');
difficulty = value;
}
double getDifficulty() {
func.debugPrint('Get difficulty is $difficulty');
return difficulty;
}
void getScores(Function() updateScores) async {
if (_httpAvailable) {
// If we haven't had a previous http error - read the scores
try {
dynamic _parsedAddress = Uri.parse(_apiAddress);
final response = await http.get(_parsedAddress);
func.debugPrint(
'doing getScores. Address = $_apiAddress. statusCode = ${response.statusCode}');
Map decodedResponse = jsonDecode(response.body) as Map;
if (response.statusCode == 200) {
func.debugPrint('getScores response: $decodedResponse');
results = decodedResponse;
updateScores(); // Update scores on main.dart
} else {
throw Exception('Unable to fetch products from the REST API');
}
} catch (e) {
func.debugPrint('getScores. Error is $e.');
_httpAvailable = false; // Disable http checks because we had an error
results =
{}; // Return an empty map if the internet connection is not available
}
}
}
// Put data about scores into the database
Future<void> putScores(String resultPath) async {
// Only try to put the scores if http is available
if (_httpAvailable) {
try {
String address = '$_apiAddress$resultPath';
func.debugPrint('http address: $address');
var response = await http.post(Uri.parse(address));
func.debugPrint('http response: ${response.body.toString()}');
// Check for sucess, throw an error if it didn't work
if (response.statusCode == 200 ||
response.statusCode == 201 ||
response.statusCode == 204) {
return;
} else {
throw Exception(
'Unable to update results from the REST API. Status Code: ' +
response.statusCode.toString());
}
} catch (e) {
_httpAvailable = false; // Disable http requests
}
}
}
}
The output when "getScores()" is called is:
getScores. Error is XMLHttpRequest error..
The Hapi interface code is as follows:
'use strict';
const Hapi = require('#hapi/hapi');
const { options } = require('#hapi/hapi/lib/cors');
const Inert = require('#hapi/inert');
const HapiPostgresConnection = require('hapi-postgres-connection');
const path = require('path');
const debug = true;
const init = async () => {
const server = Hapi.server({
port: 4044,
host: '192.168.1.201',
//host: '0.0.0.0',
routes: {
cors: false
/*
{
origin: ['192.168.*'], // an array of origins or 'ignore'
headers: ['Authorization'], // an array of strings - 'Access-Control-Allow-Headers'
exposedHeaders: ['Accept'], // an array of exposed headers - 'Access-Control-Expose-Headers',
additionalExposedHeaders: ['Accept'], // an array of additional exposed headers
maxAge: 60,
credentials: false // boolean - 'Access-Control-Allow-Credentials'
*/
}
});
await server.register([{
plugin: HapiPostgresConnection
},
{
plugin: Inert
}]);
server.route({
method: 'GET',
path: '/',
handler: async function (request, h) {
let id = '1';
let statement = `SELECT * FROM scores WHERE id = ${id}`;
debugPrint(`Doing GET. Statement = ${statement}`);
try {
const result = await request.pg.client.query(statement);
debugPrint(`After GET. Result = ${result}. Response = ${h.response()}`);
return h.response(result.rows[0]);
} catch (err) {
console.log(err);
}
}
});
server.route({
method: 'GET',
path: '/noxo',
handler: (request, h) => {
return h.file('/home/mike/programming/noxo/index.html');
}
});
server.route({
method: 'GET',
path: '/fwebtest',
handler: (request, h) => {
return h.file('index.html', options [{confine: false}]);
},
options: {
files: {
relativeTo: path.join(__dirname, 'fwebtest')
},
},
});
server.route({
method: 'GET',
path: '/webtest',
handler: (request, h) => {
return h.file('./webtest/index.html', options [{confine: false}])
}
});
server.route({
method: ['PUT', 'POST'],
path: '/',
handler: async function (request, h) {
let statement = 'update scores set';
var jsonData = request.payload;
if (jsonData.hasOwnProperty('id')) {
delete jsonData.id;
}
var first = true
for (var key of Object.keys(jsonData)) {
if (!first) {
statement = statement + ",";
}
statement = statement + ' ' + key + ' = ' + jsonData[key];
first = false;
}
statement = statement + ' where id = 1'
debugPrint(`Doing PUT. Statement = ${statement}`);
try {
const result = await request.pg.client.query(statement);
return h.response(result.rows[0]);
} catch (err) {
console.log(err);
}
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
function buildStatement(element, index, array) {
if (index != 'id') {
statement = statement + index + ' = ' + value + ' ';
}
return this;
}
function debugPrint(value){
if (debug == true){
console.log(value);
}
}
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
The test dart programme, which works, is as follows:
import 'dart:convert';
import 'package:http/http.dart' as http;
// Address of API for data requests
final _apiAddress = 'http://192.168.1.201:4044/';
// Global variables
bool _httpAvailable = true; // Has http conect worked? Assume yes.
const bool debug = true; // Global bebug print variable.
void main() async {
// Get the scores from the API
Map scores = await _getScores();
}
// Function to get the scores using http command
Future<Map> _getScores() async {
debugPrint('Doing GET...');
dynamic response;
Map decodedResponse = {};
try {
dynamic _parsedAddress = Uri.parse(_apiAddress);
response = await http.get(_parsedAddress);
decodedResponse = jsonDecode(response.body) as Map;
} catch (e) {
debugPrint('getScores. Error is $e.');
_httpAvailable = false; // Disable http checks because we had an error
decodedResponse =
{}; // Return an empty map if the internet connection is not available
}
if (response.statusCode == 200) {
debugPrint('response.body:');
debugPrint(response.body);
debugPrint('GET successful... code: ' + response.statusCode.toString());
debugPrint(' ');
return decodedResponse;
} else {
throw Exception('Unable to fetch products from the REST API. Error code: ' +
response.statusCode.toString());
}
}
debugPrint(String message) {
if (debug == true) {
print(message);
}
}
The output from this programme is:
D:\Sync\Programming\Flutter\http_get>dart run
Building package executable...
Built http_test:http_test.
Doing GET...
response.body:
{"id":1,"humanwin":3,"draws":0,"computerwin":0}
GET successful... code: 200
The POSTMAN results are:
I assume that this is a CORS issue from what I have read about XMLHttpRequest errors, but believe I have disabled CORS in the Hapi interface. The application class, test programme and POSTMAN test all pre-date the Ubuntu VM rebuild so the only thing that has changed is the VM. The Hapi code was backed up so that shouldn't have changed either, although I can't quite remember when I took the last backup.
Does anyone have any ideas about why the test programme and POSTMAN work, but my DataManager class in my application doesn't?
In the routes definition for Hapi, cors needs to be set to true as below.
const server = Hapi.server({
port: xxxx,
host: 'xxx.xxx.xxx.xxx',
routes: {
cors: true
}
});

Angular 2 Http Post with Promise failing, not sending data

I am attempting to make a http.post call with angular 2. I have tested the call in postman, so I know that the api is working. I get an error, input empty which means that it isn't getting the data. I've read a few answers and articles, but not able to make a successful call with the data.
Can anyone give me some insight into what I am missing?
public upload(name: string, data: any, result, contentType: string) : Promise<Response> {
let headers = new Headers({ 'Content-Type': contentType });
let options = new RequestOptions({ headers: headers });
return this.http
.post(this.urlAPI, data, options)
.toPromise()
.then(this.extractData)
.catch(this.handleError);
}
extractData(res:Response) {
console.log('res: ', res);
let body = res.json();
return Promise.resolve(res);
}
handleError(err: any): Promise<any> {
console.error('An Error has occured: ', err);
return Promise.reject(err);
}
I am not sure what is the type of your 'data'. Data has to be stringified before sent. Below is a workable version for me.
saveNote(note: ApprovalNoteModel): Observable<ApprovalNoteModel> {
let body = JSON.stringify(note);
let headers = this.utilsSvc.getAuthHeaders();
headers.set('Content-Type', 'application/json');
return this.http.post('cloud/api/approval/note', body,
{ headers: headers }
).map(response => response.json());
}
If it is a file, then you can not do that thru 'http', I believe. Here is my workable version.
addFileRequest(referenceId: number, licenseId: number, url: string, files: File[]): Observable<any> {
return Observable.create(observer => {
this.progressObserver = observer;
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();
formData.append('referenceId', referenceId);
formData.append('licenseId', licenseId);
for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
observer.next(xhr.response);
observer.complete();
} else {
if (xhr.response.status)
observer.error(xhr.response);
else
observer.error({ 'status': xhr.status, '_body': xhr.response });
}
}
};
xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);
this.progressObserver.next(this.progress);
};
xhr.open('POST', url, true);
xhr.setRequestHeader('Authorization', this.utilsSvc.getToken());
xhr.send(formData);
});
}

Angular2 Stripe integration stripeResponseHandler cannot access this

I'm integrating Stripe payments with Angular2 (actually Ionic but the code is the same)
the call to Stripe.card.createToken is successful and returns a token
but in stripeResponseHandler which is an async callback, I cannot access any of the "this" variables. for example I cannot set this.amount = 10 and I cannot call this._http.post
how can I access the "this" variables ? I'm trying to http post the token and the amount to an API to make the payment
constructor(private _navController: NavController,
private _http: Http) { }
submitPayment() {
Stripe.setPublishableKey(this.key);
this.card = new Card();
this.card.number = this.cardNumber;
this.card.cvc = this.cardCVC;
this.card.exp_month = this.cardExpMonth;
this.card.exp_year = this.cardExpYear;
this.card.address_zip = this.cardAddressZip;
try {
Stripe.card.createToken(this.card, this.stripeResponseHandler);
}
catch (e) {
alert(e.message);
}
// Prevent the form from being submitted:
return false;
}
stripeResponseHandler(status, response) {
if (response.error) { // Problem!
alert(response.error);
} else { // Token was created!
// Get the token ID:
alert(response.id);
try {
this.amount = 10;
let payment = new Payment();
payment.token = response.id;
payment.amount = this.amount;
let body = JSON.stringify(payment);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this._http.post(this.url, body, options)
.map(res => res.json())
.catch(this.handleError);
}
catch (e) {
alert(e.message);
}
}
}
handleError(error: Response) {
// may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
alert('error' + error.text + " " + error.statusText);
return Observable.throw(error.json().error || 'Server error');
}
If you just pass the function reference, then JavaScript doesn't keep the this reference. You have to take care of this explicitely:
Instead of
Stripe.card.createToken(this.card, this.stripeResponseHandler);
use
Stripe.card.createToken(this.card, (status, person) => this.stripeResponseHandler(status, person));
See also https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
or
Stripe.card.createToken(this.card, this.stripeResponseHandler.bind(this));

ionic 2 http request after oauth not working

I have a button redirect to this function
loginGoogle() {
this.cordovaOauthG.login().then((success) => {
console.log("Google Login DONE ");
if (success != null) {
console.log(JSON.stringify(success));
//alert(success.access_token);
if (success.access_token != null && success.access_token != '') {
var params = "google_id=" + success.access_token;
// var token = success.access_token;
// this.postLoginGoogle(params);
this.tesLogin();
}
}
}, (error) => {
alert(error);
});
}
and this is the function for http request
tesLogin(){
// var params = "google_id="+gid;
var params = "google_id="+'ya29.Ci_4ApeVHCD7av30Y82JRZPLG4T9ZUgmU1SNLUGIlVV_ufAcCoBc4ILqsY6Ah55i-g';
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
console.log(params);
this.http.post(Config.base_url + 'api/user-account/login-google', params, {headers: headers})
.map(res => res.json()).subscribe(data => {
console.log(data);
if (data.success) {
this.local.set('access_token', data.message);
this.menu.enable(true);
this.nav.setRoot(HomePage);
}
else {
this.doAlert("Incorrect email or password");
}
});
}
My problem is, whenever I tried to call using success.access_token, it doesnt work
but If I am calling the request without any parameters(just throwing in some random strings) then it works
I tried to debug it using mobile inspector from chrome, either way it is returning a error like this (working post & not working post both returning error)
EXCEPTION: SyntaxError: Unexpected token < in JSON at position 1
I suggest to send the authentication token in the header not in the parameters. Something like that:
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Authorization', 'Bearer ' + authToken);

Drupal JSON POST from PhoneGap

I am trying to send a POST request to Drupal's Services module & JSON_Server module, however I am getting
{ "#error": true, "#data": "Invalid method " }
Since PhoneGap runs html files from locally on the phone, should i need to worry about JSONP. The issue I have with that is that I must POST data, and JSONP only allows for GET. Any ideas would be helpful. Thanks!
//SEND REQUEST AND CALLBACK FUNCTION
var req;
DrupalService.prototype.request = function(dataObject, callback){
req = false;
var url = DRUPAL_JSON_URL;
var params = "data="+dataObject;
try {
req = new XMLHttpRequest();
} catch(e) {
req = false;
}
if(req) {
req.onreadystatechange = function() {//Call a function when the state changes.
if(req.readyState == 4 && req.status == 200) {
console.log(">> "+req.responseText);
}
}
req.open("POST", url, false);
req.send(params);
}
}
So i figured it out, It had to do with conflicting content types
make sure you set it as
Content-Type = application/x-www-form-urlencoded;
var DRUPAL_JSON_URL = "http://myDrupalsSite.com/services/json";
var req;
DrupalService.prototype.request = function(dataObject, callback){
var url = DRUPAL_JSON_URL;
req = false;
var params = "method=system.connect";
try {
req = new XMLHttpRequest();
} catch(e) {
req = false;
}
if(req) {
req.onreadystatechange = function() {//Call a function when the state changes.
if(req.readyState == 4 && req.status == 200) {
alert("test " + req.responseText)
console.log("RESPONSE "+req.responseText);
}
}
req.open("POST", url, true);
req.setRequestHeader("Content-length", params.length);
req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
req.send(params);
}
}