uploading and retrieving image using angular 6 php mysql - php

I want to upload an image using angular 6 via php to mysql. After that, I want to retrieve the image
from the database to display it in the html. Here is my code:
export class Student {
idCard : string;
fname : string;
mname : string;
lname : string;
gender : string;
studentPhoto?: File; //what type of data should I use
}
For displaying the photo
student-details.component.html
<div class="col-xs-4">
<img class="imageClass" src="student.studentPhoto" alt="Image not Recognized"/>
</div>
<!-- how can I set the src attribute -->
So, what data type should I use in the angular and also in the MYSQL to store the image? and How can I display the image
by fetching it from MYSQL?

Here is the full implementation that solves the problem:
In the component class:
import { StudentService } from '../student-service.service';
import { DomSanitizer } from '#angular/platform-browser';
export class StudentRegistrationComponent implements OnInit {
imageUrl = null;
photo: Blob;
constructor(private _service: StudentService,
public _DomSanitizationService: DomSanitizer) { }
setPhoto(event){
this.photo = event.target.files[0];
}
onClickSubmit(){
const fd = new FormData();
fd.append('stphoto',this.photo);
this._service.postImage(fd).subscribe(res => console.log(res));
}
showImage(){
this._service.getImage().subscribe((res) => {
this.photo = res;
var myReader:FileReader = new FileReader();
myReader.onloadend = (e) => {
this.imageUrl = this._DomSanitizationService.bypassSecurityTrustUrl(<string>myReader.result);
}
myReader.readAsDataURL(this.photo);
});
}
}
In the template:
<input id="photo" name="studentPhoto" type="file" (change)="setPhoto($event)" class="form-control">
<button class="btn btn-primary" (click) = "onClickSubmit()">submit</button>
<button (click)="showImage()">showImage</button>
<img [src]="imageUrl" height="200" width="200" class="img-thumnail">
StudentService:
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class StudentService {
constructor(private httpClient: HttpClient) { }
postImage(fd : FormData): Observable<string>{
return this.httpClient.post<string>('http://localhost:4000/files/postImage.php', fd );
}
getImage(): Observable<Blob> {
return this.httpClient.get( 'http://localhost:4000/files/getImage.php', { responseType: 'blob' })
}
}
postImage.php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, DELETE, PUT');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization');
header('Access-Control-Allow-Credentials: true');
$con = mysqli_connect("localhost:3306","root","","students");
mysqli_set_charset($con, "utf8");
if($_FILES["stphoto"])
{
$tmporary = $_FILES["stphoto"]["tmp_name"];
$file_name = $_FILES["stphoto"]["name"];
//don't forget to change 'ABDU' to your username.
if(move_uploaded_file($tmporary,"C:\Users\ABDU\AppData\Local\_"."$file_name"))
{
if($file = addslashes(file_get_contents("C:\Users\ABDU\AppData\Local\_"."$file_name")))
{
$sql = "INSERT INTO imagedb (`imagefile`) VALUES ('$file')";
mysqli_query($con,$sql);
mysqli_query($con,"ALTER TABLE imagedb AUTO_INCREMENT = 1");
echo json_encode("successfully injected");
}
}
else
echo json_encode("error");
}
?>
getImage.php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, DELETE, PUT');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization');
header('Access-Control-Allow-Credentials: true');
$con = mysqli_connect("localhost:3306","root","","students");
mysqli_set_charset($con, "utf8");
$sql = "SELECT imagefile FROM imagedb";
$result = mysqli_query($con,$sql))
$row = mysqli_fetch_assoc($result);
echo $row['imagefile'];
?>
imagedb table has two columns:
'id' and 'imagefile' (type = LongBlob)

Related

CORS block the request

i am using react as frontend and php as backend, frontend previously i was uploading on aws amplify and backend upload on lightsail, however due to amplify is https but lightsail is http api which wont let me pass the info so I changed to aws s3 as frontend, every function works fine but only update function will show error
Access to XMLHttpRequest at 'http://3.222.98.25/api/Update.php' from origin 'http://post-fetch-api.s3-website-ap-southeast-2.amazonaws.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
anyone knows reason? i put every CORS functions i can in the update file, is works on local enviorment, but not online enviorment
//this is php update page
<?php
// if request is OPTIONS, disconnect
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: token, Content-Type');
header('Access-Control-Max-Age: 1728000');
header('Content-Length: 0');
header('Content-Type: text/plain');
die();
}
// Headers
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: Access-Control-Allow-Headers,Content-Type,Access-Control-Allow-Methods, Authorization, X-Requested-With');
include_once '../config/Database.php';
include_once '../models/Post.php';
// Instantiate DB & connect
$database = new Database();
$db = $database->connect();
// Instantiate blog post object
$post = new Post($db);
// Get raw posted data
$data = json_decode(file_get_contents("php://input"));
// Set ID to update
$post->id = $data->id;
$post->title = $data->title;
$post->body = $data->body;
// Update post
if($post->update()) {
echo json_encode(
array('message' => 'Post Updated')
);
} else {
echo json_encode(
array('message' => 'Post Not Updated')
);
}
// here is react update page
import { useState, useEffect } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
import { useNavigate, useParams } from "react-router-dom";
export default function Update() {
const [inputs, setInputs] = useState({});
//const[post,setPost]=useState({});
const navigate = useNavigate();
const { id } = useParams();
useEffect(() => {
getSinglePost();
}, []);
function getSinglePost() {
axios
.get(`http://3.222.98.25/api/read_single.php?id=${id}`)
.then((res) => {
console.log(res.data);
setInputs(res.data);
})
.catch((err) => console.log(err));
}
const handleChange = (e) => {
const name = e.target.name;
const value = e.target.value;
setInputs((values) => ({ ...values, [name]: value }));
};
const handleSubmit = (e) => {
e.preventDefault();
axios
.put("http://3.222.98.25/api/Update.php", inputs)
.then((response) => {
console.log(response.data);
navigate("/read");
})
.catch((err) => console.log(err));
};
return (
<div>
<Link to="/">Show Posts</Link>
<h1 style={{ marginTop: "150px" }}>Update a post</h1>
<form onSubmit={handleSubmit}>
<div className="marginBottom">
<label className="marginRight">Title:</label>
<input
type="text"
value={inputs.title}
name="title"
onChange={handleChange}
required
></input>
</div>
<div className="marginBottom bodyCenter">
<label className="marginRight">Body:</label>
<textarea
style={{ height: "50px" }}
type="text"
name="body"
value={inputs.body}
onChange={handleChange}
required
></textarea>
</div>
<button>update</button>
</form>
</div>
);
}

Php : get formData base64 image string and upload to local folder

I have base64 image string sending in my API calling to a .php file
Request URL :
http://localhost/server/index.php?saveImageToFolder=true?id=1&name=fdsfsdf
My HTML form looke like below
Below is my code for sending base64 from Input type file which is in reactjs
function getBase64(file) {
return new Promise(function (resolve, reject) {
const reader = new FileReader();
reader.onload = function () {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
const onChangeImage = (e, id, slotname) => {
const formData = new FormData();
formData.append('file', e.target.files[0]);
const fileFound = e.target.type === 'file' && e.target.files[0];
const promise = fileFound && getBase64(fileFound);
promise.then(function(result) {
uploadImage({ 'id': id, 'slotname': slotname, 'slotimage': result });
})
}
And then i have formData in my payload. Below is the complete network tab payload
My index.php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
include("connect.php");
error_reporting(0);
session_start();
if(isset($_GET['saveImageToFolder'])){
var_dump($_POST['file']); //This is showing NULL
var_dump($_FILES['file']); //This is also showing NULL
$data = $_POST['file'];
list($type, $data) = explode(';', $data);
list(, $data) = explode(',', $data);
$data = base64_decode($data);
file_put_contents('image.png', $data);
}
Image file is creating with PNG and 0KB. Not getting how to fetch values of formData and then further in index.php
const fileFound = e.target.type === 'file' && e.target.files[0];
evaluates to true or false and in the next step you pass a boolean to getBase64() instead of the filename.
const promise = fileFound && getBase64(fileFound);
So change it to
const promise = fileFound && getBase64(file);
instead.

Ionic 3 - How do I pass id parameter into “http delete” function and delete specific user only?

I am trying to delete data from the DB server. How do I pass a specific user id into an HTTP delete request so that way I can delete only one user and not all user data? I am using core PHP DB and Ionic 3.
Below is my code:
Home.html
<ion-content padding>
<ion-list>
<ion-item *ngFor="let user of (users | async)?.users" (click)="viewItem(user._id)">
<ion-avatar item-left>
<img src="assets/imgs/logo.png">
</ion-avatar>
<h1>{{user.id}}</h1>
<h2>{{user.name}}</h2>
<p>{{user.bday}}</p>
<ion-icon name='trash' (click)="deleteitem(user._id)" item-end color="secondary"></ion-icon>
</ion-item>
</ion-list>
</ion-content>
home.ts
deleteitem(id: number){
let users = {
userId: id
};
this.restProvider.deleteItem(users)
.subscribe(data => {
this.items = data;
}, err => {
console.error(err);
});
}
provider.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { Headers, RequestOptions } from '#angular/http';
.
.
baseUrl = 'http://url/project_folder';
.
.
deleteItem(user) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return new Promise((resolve, reject) => {
this.http.delete(this.baseUrl+'/delete_info.php'+'/?id=' + '{user.userId}')
.subscribe(res => {
resolve(res);
}, (err) => {
reject(err);
});
});
}
delete.php
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
$id=$_GET['id'];
$servername = "servername";
$username = "username";
$password = "password";
$database = "database";
// Create connection
$conn = new mysqli($servername, $username, $password, $database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql="delete from tbl_userinfo where id=$id";
if ($conn->query($sql))
{
echo "delete data";
}
else
{
echo "Try again";
}
?>
If i enter like this working:
http://url/project_folder/delete.php/?id=6
When i click on delete button, showing error like this:
core.js:1449 ERROR Error: Uncaught (in promise): [object Object]
at c (polyfills.js:3)
at polyfills.js:3
at SafeSubscriber._error (rest.ts:56)
at SafeSubscriber.__tryOrUnsub (Subscriber.js:242)
at SafeSubscriber.error (Subscriber.js:201)
at Subscriber._error (Subscriber.js:132)
at Subscriber.error (Subscriber.js:106)
at MapSubscriber.Subscriber._error (Subscriber.js:132)
at MapSubscriber.Subscriber.error (Subscriber.js:106)
at FilterSubscriber.Subscriber._error (Subscriber.js:132)
Network Response:
http://url/project_folder/delete_info.php/?id={user.userId}
Attach click to icon not a good idea
provider.ts: ...id=' + '{user.userId}' should be ...id=' + user.userId.
provider.ts: if you want to return Promise, should be return this.http.delete().toPromise(), and you must use 'then' not subscribe at home.ts
provider.ts: if you not want to return promise, return this.http.delete() is ok, then use subscribe at home.ts
php must return json data.
example below:
<ion-button (click)="deleteitem(user)">
<ion-icon name='trash' slot="icon-only"></ion-icon>
</ion-button>
function deleteitem(user) {
this.restProvider.deleteitem(user._id).subscribe(data => {
for(let i = 0, l = this.users.length; i < l; i++)
if (this.users[i]._id == user._id)
this.users.splice(i, 1);
}, err => {
console.error(err);
});
}
function deleteitem(userId) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.delete(`${this.baseUrl}/delete_info.php?id=${userId}`);
}

Anuglar 6 .post .subscribe inserting record twice

I am trying to put an Angular 6 CRUD together. My addCoins method seems to be adding the record twice.
addCoin(name, price) {
const obj = {
name: name,
price: price
};
const uri = 'http://localhost/ng6crud/api/post-coins/' + name + '/' + price;
this
.http
.post(uri, obj)
.subscribe(res =>
console.log('Done'));
}
I have created a simple PHP api that sits in the ng6crud directory. The following is the code for the api/post-coins/ - If I use postman to post to the API, then it only inserts the data once.
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
$path = ltrim($_SERVER['REQUEST_URI'], '/'); // Trim leading slash(es)
$elements = explode('/', $path); // Split path on slashes
global $name, $price;
if(!empty($elements[3]))
{
$name = $elements[3];
}
if(!empty($elements[4]))
{
$price = $elements[4];
}
global $server;
$server = "localhost";
global $user;
$user = "someU";
global $pwd;
// $pwd = "someP"; // production
$pwd = "someP"; // local
global $db;
$db = "someDb";
//open connection to mysql db
$connection = mysqli_connect($server,$user,$pwd,$db) or die("Error " . mysqli_error($connection));
//fetch table rows from mysql db
$sql = "INSERT into coins (name, price) VALUES('" . $name . "','" . $price . "')";
// echo $sql;
// die();
if ($connection->query($sql) === TRUE) {
// echo "Record updated successfully";
} else {
// echo "Error updating record: " . $connection->error;
}
$connection->close();
?>
The combination of an .htaccess file and the "" tag in the httpd-vhosts.conf file allows the api/post-coins/ to accept two parameters for "name" and "price" to be included in the sql insert statement - for example api/post-coins/rupple/1.00 would insert a row into the db.
The following is the .htaccess file:
IndexIgnore * # prevent directory listing
Order deny,allow
Allow from *
# ------------------------------------------
# Rewrite so that php extentions are not shown
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php%{REQUEST_URI} [QSA,L]
The following is the Location tag within the "" tag in the httpd-vhosts.conf file:
<Location /post-coins>
ForceType appllication/x-http-php
</Location>
Once more, if I use postman to post to api/post-coins/rupple/1.00 then only one entry will be in the db. When using the service within Angular 6, it is inserting the data twice. I have tried removing the .subscribe, but then nothing is inserted and I have tried to remove the two parameters at the end of the URL, but that results is two empty entries.
Thanks in advance
To answer #Vikas question as to how I implement, the following is the create.component.html:
<div class="panel panel-primary">
<div class="panel-heading">
{{ title }}
</div>
<div class="panel-body">
<form [formGroup]="angForm" novalidate>
<div class="form-group">
<label class="col-md-4">Coin Name</label>
<input type="text" class="form-control" formControlName="name" #name />
</div>
<div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['name'].errors.required">
Name is required.
</div>
</div>
<div class="form-group">
<label class="col-md-4">Coin Price</label>
<input type="text" class="form-control" formControlName="price" #price/>
</div>
<div *ngIf="angForm.controls['price'].invalid && (angForm.controls['price'].dirty || angForm.controls['price'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['price'].errors.required">
Price is required.
</div>
</div>
<div class="form-group">
<button (click)="addCoin(name.value, price.value)" [disabled]="angForm.pristine || angForm.invalid" class="btn btn-primary">Add</button>
</div>
</form>
</div>
</div>
The creat.component.ts:
import { Component, OnInit } from '#angular/core';
import { CoinService } from '../../service/coin.service';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
#Component({
selector: 'app-create',
templateUrl: './create.component.html',
styleUrls: ['./create.component.css']
})
export class CreateComponent implements OnInit {
title = 'Add Coin';
angForm: FormGroup;
constructor(private coinservice: CoinService, private fb: FormBuilder) {
this.createForm();
}
createForm() {
this.angForm = this.fb.group({
name: ['', Validators.required ],
price: ['', Validators.required ]
});
}
addCoin(name, price) {
this.coinservice.addCoin(name, price);
}
ngOnInit() {
}
}
And the coin.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable()
export class CoinService {
result: any;
constructor(private http: HttpClient) {}
addCoin(name, price) {
const obj = {
name: name,
price: price
};
const uri = 'http://localhost/ng5crud/api/post-coins/' + name + '/' + price;
this
.http
.post(uri, obj)
.subscribe(res =>
console.log('Done'));
}
getCoins() {
const uri = 'http://localhost/ng5crud/api/get-coins/';
return this
.http
.get(uri);
}
editCoin(id) {
const uri = 'http://localhost/ng5crud/api/get-coins-id/' + id;
return this
.http
.get(uri);
}
updateCoin(name, price, id) {
const uri = 'http://localhost/ng5crud/api/put-coins/' + id;
const obj = {
name: name,
price: price
};
this
.http
.post(uri, obj)
.subscribe(res => console.log('Done'));
}
deleteCoin(id) {
const uri = 'http://localhost/ng5crud/api/delete-coins/' + id;
return this
.http
.get(uri);
}
}
And the routerConfig.ts
import { Routes } from '#angular/router';
import { CreateComponent } from './components/create/create.component';
import { EditComponent } from './components/edit/edit.component';
import { IndexComponent } from './components/index/index.component';
import { DeleteComponent } from './components/delete/delete.component';
export const appRoutes: Routes = [
{ path: 'create',
component: CreateComponent
},
{
path: 'edit/:id',
component: EditComponent
},
{ path: 'index',
component: IndexComponent
},
{ path: 'delete/:id',
component: DeleteComponent
}
];
#Debojyoti, I just saw your response. I ended up creating the following, which returned nothing, but I took a look in network panel - see screen shot below:
import { HttpErrorResponse } from '#angular/common/http';
import { throwError } from 'rxjs';
import { catchError} from 'rxjs/operators';
addCoin(name, price) {
const obj = {
name: name,
price: price
};
const uri = 'http://localhost/ng5crud/api/post-coins/' + name + '/' + price;
this
.http
.post(uri, obj)
.pipe(
catchError(this.handleError) // then handle the error
)
.subscribe(res =>
console.log('Done'));
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError(
'Something happened; please try again later.');
};
I figured it out and I thank each of you for helping me to step through it over and over again.
Since my PHP API is, for all intensive purposes a "GET":
const uri = 'http://localhost/ng5crud/api/post-coins/' + name + '/' + price;
Then calling a "POST" function would fire off the API twice - see attached screen shot below:
const obj = {
name: name,
price: price
};
const uri = 'http://localhost/ng5crud/api/post-coins/' + name + '/' + price;
this
.http
.post(uri, obj)
So, I changed it to a "GET" function and it works perfectly, with only one entry
addCoin(name, price) {
const obj = {
name: name,
price: price
};
const uri = 'http://localhost/ng5crud/api/post-coins/' + name + '/' + price;
this
.http
.get(uri)
.pipe(
catchError(this.handleError), // then handle the error
map(res => {
console.log(res);
})
)
.subscribe(res =>
console.log('Done'));
}
Through this journey, I discovered from (another stackoverflow post - see #nodirabegimxonoyim 's answer), that map is imported differently in Angular 6 and used differently within the .get method
Instead of importing with
import 'rxjs/add/operator/map';
You use the following:
import { map } from 'rxjs/operators';
Instead of .get().map()
this
.http
.get(uri)
.map(res => {console.log(res)});
You use map, within .pipe
this
.http
.get(uri)
.pipe(
catchError(this.handleError), // then handle the error
map(res => {
console.log(res);
})
)
All together, the following is my new working coin.service.ts:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { HttpErrorResponse } from '#angular/common/http';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { map } from 'rxjs/operators';
#Injectable()
export class CoinService {
constructor(private http: HttpClient) {}
addCoin(name, price) {
const obj = {
name: name,
price: price
};
const uri = 'http://localhost/ng5crud/api/post-coins/' + name + '/' + price;
this
.http
.get(uri)
.pipe(
catchError(this.handleError), // then handle the error
map(res => {
console.log(res);
})
)
.subscribe(res =>
console.log('Done'));
}
getCoins() {
const uri = 'http://localhost/ng5crud/api/get-coins/';
return this
.http
.get(uri)
.pipe(
catchError(this.handleError), // then handle the error
map(res => {
console.log(res);
})
);
}
editCoin(id) {
const uri = 'http://localhost/ng5crud/api/get-coins-id/' + id;
return this
.http
.get(uri)
.pipe(
catchError(this.handleError), // then handle the error
map(res => {
console.log(res);
})
);
}
updateCoin(name, price, id) {
const uri = 'http://localhost/ng5crud/api/put-coins/' + id;
const obj = {
name: name,
price: price
};
this
.http
.post(uri, id)
.pipe(
catchError(this.handleError), // then handle the error
map(res => {
console.log(res);
})
)
.subscribe(res => console.log('Done'));
}
deleteCoin(id) {
const uri = 'http://localhost/ng5crud/api/delete-coins/' + id;
return this
.http
.get(uri)
.pipe(
catchError(this.handleError), // then handle the error
map(res => {
console.log(res);
})
);
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError(
'Something happened; please try again later.');
}
}
Seriously, thank you for all your help. This takes me back to the early nineties, when programmers were nice and we would help each other.
It looks like the PHP application and Angular application are running on a separate combination of protocol (http/https), domain, and port. I see the CORS headers have been added in the PHP code.
This leads me to believe 2 requests are being made, one to see if the request is allowed according to CORS (an OPTIONS) request and the normal POST request. Hence, the record being inserted twice. You could detect the request method and return the CORS headers and set the response body to nothing as appropriate on the CORS OPTIONS request and do an insert on a POST request similar to the following (not tested).
<?php
if ($_SERVER['method'] === 'OPTIONS') {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
header("HTTP/1.1 200 OK");
exit;
}
if ($_SERVER['method'] === 'POST') {
header("HTTP/1.1 200 OK");
$path = ltrim($_SERVER['REQUEST_URI'], '/'); // Trim leading slash(es)
$elements = explode('/', $path); // Split path on slashes
global $name, $price;
if (!empty($elements[3])) {
$name = $elements[3];
}
if (!empty($elements[4])) {
$price = $elements[4];
}
global $server;
$server = "localhost";
global $user;
$user = "someU";
global $pwd;
// $pwd = "someP"; // production
$pwd = "someP"; // local
global $db;
$db = "someDb";
//open connection to mysql db
$connection = mysqli_connect($server, $user, $pwd, $db) or die("Error " . mysqli_error($connection));
//fetch table rows from mysql db
$sql = "INSERT into coins (name, price) VALUES('" . $name . "','" . $price . "')";
// echo $sql;
// die();
if ($connection->query($sql) === true) {
// echo "Record updated successfully";
} else {
// echo "Error updating record: " . $connection->error;
}
$connection->close();
exit;
}
header("HTTP/1.1 404 Not Found");
exit;
?>
Make php not to accept the first pre flight request (OPTIONS)
Just modify your php code like
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
if ($_SERVER['REQUEST_METHOD'] != "OPTIONS") {
$path = ltrim($_SERVER['REQUEST_URI'], '/'); // Trim leading slash(es)
$elements = explode('/', $path); // Split path on slashes
global $name, $price;
if (!empty($elements[3])) {
$name = $elements[3];
}
if (!empty($elements[4])) {
$price = $elements[4];
}
global $server;
$server = "localhost";
global $user;
$user = "someU";
global $pwd;
// $pwd = "someP"; // production
$pwd = "someP"; // local
global $db;
$db = "someDb";
//open connection to mysql db
$connection = mysqli_connect($server, $user, $pwd, $db) or die("Error " . mysqli_error($connection));
//fetch table rows from mysql db
$sql = "INSERT into coins (name, price) VALUES('" . $name . "','" . $price . "')";
// echo $sql;
// die();
if ($connection->query($sql) === TRUE) {
// echo "Record updated successfully";
} else {
// echo "Error updating record: " . $connection->error;
}
}
$connection->close();
?>

Object Object Error received when submitting form in ionic

Every time I clicked on submit button in my login page, the message it return is [Object Object]. I am trying to get users login details from the database using http request but it failed every time I run it.
I have applied to it different approach but I am still getting the same error.
I am still new to ionic and how it works, all I am doing is following some tutorials online which are not that much detailed.
My main issue is getting users details from mysql, accessing it and validate all the imputs.
Below are my Login form details:
Login.html
<ion-content class="login-content" padding>
<ion-row class="logo-row">
<ion-col></ion-col>
<ion-col >
<img src="../assets/imgs/logo.png" class="img-responsive " id="img2">
</ion-col>
<ion-col></ion-col>
</ion-row>
<div class="login-box">
<form (ngSubmit)="login()" #registerForm="ngForm">
<ion-row>
<ion-col>
<ion-list inset>
<ion-item>
<ion-input type="text" placeholder="Email" name="email" [(ngModel)]="data.email" required></ion-input>
</ion-item>
<ion-item>
<ion-input type="password" placeholder="Password" name="password" [(ngModel)]="data.password" required></ion-input>
</ion-item>
</ion-list>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="signup-col">
<div align="center">
<button ion-button class="submit-btn" full type="submit" [disabled]="!registerForm.form.valid">Login</button>
<span class="tell">- or -</span>
<button ion-button class="register-btn" type="button" block clear (click)="createAccount()">Create New Account</button>
</div>
</ion-col>
</ion-row>
</form>
</div>
</ion-content>
Login.ts
import { Component } from '#angular/core';
import { NavController, AlertController, LoadingController, Loading, IonicPage } from 'ionic-angular';
import { Myprovider } from '../../providers/myprovider/myprovider';
import { Storage } from '#ionic/storage';
#IonicPage()
#Component({
selector: 'page-login',
templateUrl: 'login.html',
providers: [Myprovider]
})
export class LoginPage {
loading: Loading;
data: any;
public local : Storage;
constructor(private nav: NavController, private auth: Myprovider, private alertCtrl: AlertController, private loadingCtrl: LoadingController, private service: Myprovider)
{
this.data = {};
this.data.email = "";
this.data.password = "";
//this.local = new Storage();
}
ionViewDidLoad() {
this.createLoader();
}
createLoader(message: string = "Please wait...") { // Optional Parameter
this.loading = this.loadingCtrl.create({
content: message
});
}
public createAccount() {
this.nav.push('RegisterPage');
}
public login() {
this.showLoading()
let email = this.data.email;
let password = this.data.password;
let data = JSON.stringify({email, password});
this.service.login(data);
this.auth.login(this.data).subscribe(allowed => {
if (allowed) {
this.nav.setRoot('DashboardPage');
} else {
this.showError("Access Denied");
}
},
error => {
this.showError(error);
});
}
showLoading() {
this.loading = this.loadingCtrl.create({
content: 'Please wait...',
dismissOnPageChange: true
});
this.loading.present();
}
showError(text) {
this.loading.dismiss();
let alert = this.alertCtrl.create({
title: 'Fail',
subTitle: text,
buttons: ['OK']
});
//alert.present(prompt);
alert.present();
}
}
MyProvider.ts
import { HttpClient } from '#angular/common/http';
import { Http } from '#angular/http';
import { Storage } from '#ionic/storage';
import { Injectable } from '#angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
export class User {
name: string;
email: string;
}
#Injectable()
export class Myprovider {
public local : Storage;
mydata: any;
constructor(private http: HttpClient) {
this.http = http;
//this.local = new Storage()
}
currentUser: User;
public login(credentials) {
let link = "http://localhost:90/mySchool/api/securelogin.php";
return this.http.post(link, credentials)
.map(credentials => {
this.mydata = credentials;
console.log("data")
}, error =>{
console.log(error)
})
}
public register(credentials) {
if (credentials.email === null || credentials.password === null) {
return Observable.throw("Please insert credentials");
} else {
// At this point store the credentials to your backend!
return Observable.create(observer => {
observer.next(true);
observer.complete();
});
}
}
public getUserInfo() : User {
return this.currentUser;
}
public logout() {
return Observable.create(observer => {
this.currentUser = null;
observer.next(true);
observer.complete();
});
}
}
Lastly, the php file
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
$conn = new mysqli("localhost", "root", "", "cihmeeting");
//http://stackoverflow.com/questions/18382740/cors-not-working-php
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
//http://stackoverflow.com/questions/15485354/angular-http-post-to-php-and-undefined
$postdata = file_get_contents("php://input");
if (isset($postdata)) {
$request = json_decode($postdata);
$email = $request->email;
$password = $request->password;
$data = array();
if ($password != "" && $email != "") {
$sel="SELECT * FROM users WHERE email='$email' AND password='$password'";
$result=$conn->query($sel);
$numrow=$result->num_rows;
if($numrow == 1){
include 'http://localhost:90/mySchool/api/tokengenerate.php';
$token = generateRandomString();
$update = "update users set token='$token' WHERE email='$email' AND password='$password'";
$qr = $conn->query($update);
if($qr){
$st = "SELECT email, token FROM users WHERE email='$email' AND password='$password'";
$query = $conn->query($st);
while($row = $query->fetch_assoc()){
$data[] = array(
"email" => $row['email'],
"token" => $row['token']
);
echo json_encode($data);
}
}
}
}
else {
header('HTTP/1.1 401 Unauthorized', true, 401);
}
}
else {
echo "Not called properly with email parameter!";
}
?>

Categories