-2

I'm working on an angular project and I want to develop a form, validate it, and save data in my database with php and mysql. I tried to do this but it doesn't work. I got these errors.

Property 'dataService' does not exist on type 'AppComponent'.
'data' is declared but its value is never read.
Parameter 'data' implicitly has an 'any' type.
Property 'router' does not exist on type 'AppComponent'.
'error' is declared but its value is never read.
Parameter 'error' implicitly has an 'any' type.

register.component.html

<h2 class="text-center">Registration</h2>
<div class="row">
<div class="col-md-3">
</div>
<div class="col-md-6 col-md-offset-3">
<div class="jumbotron">
<form [formGroup]="angForm" autocomplete="off" >
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" formControlName="name" autocomplete="off" class="form-control input-sm"  required minlength="1" maxlength="250" placeholder="Name"
[class.is-invalid]="name.invalid && (name.dirty || name.touched)">
<div *ngIf="name.invalid && (name.dirty || name.touched)" class="invalid-feedback">
  <div *ngIf="name.errors?.['required']">
    This field is required.
  </div>
</div></div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" formControlName="email" autocomplete="off" required minlength="1" maxlength="250" class="form-control input-sm" placeholder="Email"
[class.is-invalid]="email.invalid && (email.dirty || email.touched)">
<div *ngIf="email.invalid && (email.dirty || email.touched)" class="invalid-feedback">
  <div *ngIf="email.errors?.['required']">
    This field is required.
  </div>
  <div *ngIf="!email.errors?.['required'] && email.errors?.['emailValidator']">
    Invalid email format.
  </div>
</div></div>
<div class="form-group">
<label for="Password">Password</label>
<input type="password" name="Password" formControlName="password"  required minlength="15" autocomplete="off" class="form-control input-sm" placeholder="Password"
[class.is-invalid]="password.invalid && (password.dirty || password.touched)">
            <button type="button" class="btn btn-outline-secondary" (click)="user.showPassword = !user.showPassword">
              <i class="bi" [ngClass]="{'bi-eye-fill': !user.showPassword, 'bi-eye-slash-fill': user.showPassword}"></i>
            </button>
            <div *ngIf="password.invalid && (password.dirty || password.touched)" class="invalid-feedback">
              <div *ngIf="password.errors?.['required']">
                This field is required.
              </div>
              <div *ngIf="password.errors?.['minlength']">
                This field must have at least 8 characters.
              </div>
            </div></div>
<button type="submit" class="btn btn-success"  (click)="validate(angForm1)">Register</button>
</form>
</div>
</div>
<div class="col-md-3">
</div>
</div>

register.component.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators, NgForm, AbstractControl} from 
'@angular/forms';
import { first } from 'rxjs/operators';
import { Router } from '@angular/router';
import { ApiService } from '../api.service';
import { emailValidator } from './email-validator.directive';

interface IUser {
   name: string;
   email: string;
   password: string;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {

angForm!: FormGroup;
user: IUser;

constructor() {
this.user = {} as IUser;
}

ngOnInit(): void {
 this.angForm = new FormGroup({
  name: new FormControl(this.user.name, [
    Validators.required
  ]),
  email: new FormControl(this.user.email, [
    Validators.required,
    EmailValidator,
  ]),
  password: new FormControl(this.user.password, [
    Validators.required,
    Validators.minLength(8),
  ]),
});
}

get name() {
  return this.angForm.get('name')!;
}

get email() {
  return this.angForm.get('email')!;
}

get password() {
  return this.angForm.get('password')!;
}

public validate(angForm1:any): void {
  if (this.angForm.invalid) {
    for (const control of Object.keys(this.angForm.controls)) {
    this.angForm.controls[control].markAsTouched();
  }
  return;
}

else{ this.dataService. userregistration(angForm1.value.name,angForm1.value.email, 
 angForm1.value.password).pipe(first()).subscribe(
    data => {
      this.router.navigate(['login']);
    },

    error => {
    });
  }
  this.user = this.angForm.value;
  console.info('Name:', this.user.name);
  console.info('Email:', this.user.email);
  console.info('Password:', this.user.password);
  }
 }

register.php

<?php
  include_once "database.php";
  $postdata = file_get_contents("php://input");
  if (isset($postdata) && !empty($postdata)) {
    $request = json_decode($postdata);
    $name = trim($request->name);
    $pwd = mysqli_real_escape_string($mysqli, trim($request->pwd));
    $email = mysqli_real_escape_string($mysqli, trim($request->email));
    $sql = "INSERT INTO users(name,password,email) VALUES ('$name','$pwd','$email')";
    if ($mysqli->query($sql) === true) {
       $authdata = [
        "name" => $name,
        "pwd" => "",
        "email" => $email,
        "Id" => mysqli_insert_id($mysqli),
    ];
    echo json_encode($authdata);
     }
   }
   ?>

api.service.ts

import {
Injectable,
Output,
EventEmitter
}
from '@angular/core';
import {
map
 }
from 'rxjs/operators';
import {
HttpClient
 }
 from '@angular/common/http';
   import {
   Users
  }
 from './users';

 @Injectable({
  providedIn: 'root'
 })

 export class ApiService {
   redirectUrl: string;
   baseUrl: string = "http://localhost/angular_admin/php";
   @Output() getLoggedInName: EventEmitter < any > = new EventEmitter();
   constructor(private httpClient: HttpClient) {}
    public userlogin(username: any, password: any) {
   alert(username)
   return this.httpClient.post < any > (this.baseUrl + '/login.php', {
    username,
    password
  })
  .pipe(map(Users => {
    this.setToken(Users[0].name);
    this.getLoggedInName.emit(true);
    return Users;
  }));
 }

  public userregistration(name: any, email: any, pwd: any) {
    return this.httpClient.post < any > (this.baseUrl + '/register.php', {
    name,
    email,
    pwd
  })
  .pipe(map(Users => {
    return Users;
  }));
 }

  //token
  setToken(token: string) {
   localStorage.setItem('token', token);
  }
  getToken() {
    return localStorage.getItem('token');
  }
  deleteToken() {
   localStorage.removeItem('token');
  }
  isLoggedIn() {
   const usertoken = this.getToken();
   if (usertoken != null) {
  return true
  }
  return false;
 }
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Paolo.
  • 27
  • 4
  • 2
    **Warning:** Your code is vulnerable to SQL Injection attacks. You should use parameterised queries and prepared statements to help prevent attackers from compromising your database by using malicious input values. http://bobby-tables.com gives an explanation of the risks, as well as some examples of how to write your queries safely using PHP / mysqli. **Never** insert unparameterised data directly into your SQL. The way your code is written now, someone could easily steal, incorrectly change, or even delete your data. mysqli_real_escape_string is obsolete and doesn't guard against everything. – ADyson Jan 26 '23 at 15:22
  • 1
    https://phpdelusions.net/mysqli also contains good examples of writing safe SQL using mysqli. See also the [mysqli documentation](https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php) and this: [How can I prevent SQL injection in PHP?](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) . Parameterising your queries will also greatly reduce the risk of accidental syntax errors as a result of un-escaped or incorrectly quoted input values. If you learnt your current technique from a tutorial or book, please don't use that resource again. – ADyson Jan 26 '23 at 15:22
  • 1
    Also, please don't store passwords in plain text - that is another security risk. Learn about [password hashing](https://www.php.net/manual/en/faq.passwords.php) instead. See also [How to use PHP's password_hash to hash and verify passwords](https://stackoverflow.com/questions/30279321/how-to-use-phps-password-hash-to-hash-and-verify-passwords) – ADyson Jan 26 '23 at 15:23
  • What does this have to do with PHP or MySQL? – Dharman Jan 26 '23 at 15:31

1 Answers1

1
In your constructor in your ts:

constructor(private router: Router,private apiservice: ApiService) {
this.user = {} as IUser;
}
public validate(angForm1:any): void {
  if (this.angForm.invalid) {
    for (const control of Object.keys(this.angForm.controls)) {
    this.angForm.controls[control].markAsTouched();
  }
  return;
}

else{ this.apiservice. userregistration(angForm1.value.name,angForm1.value.email, 
 angForm1.value.password).pipe(first()).subscribe(
    (data: any) => {
      this.router.navigate(['login']);
    },

    error => {
    });
  }
  this.user = this.angForm.value;
  console.info('Name:', this.user.name);
  console.info('Email:', this.user.email);
  console.info('Password:', this.user.password);
  }

In your html:
<h2 class="text-center">Registration</h2>
<div class="row">
<div class="col-md-3">
</div>
<div class="col-md-6 col-md-offset-3">
<div class="jumbotron">
<form [formGroup]="angForm" autocomplete="off" >
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" formControlName="name" autocomplete="off" class="form-control input-sm"  required minlength="1" maxlength="250" placeholder="Name"
[class.is-invalid]="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)">
<div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="invalid-feedback">
  <div *ngIf="angForm.controls['name'].errors?.required">
    This field is required.
  </div>
</div></div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" formControlName="email" autocomplete="off" required minlength="1" maxlength="250" class="form-control input-sm" placeholder="Email"
[class.is-invalid]="angForm.controls['email'].invalid && (angForm.controls['email'].dirty || angForm.controls['email'].touched)">
<div *ngIf="angForm.controls['email'].invalid && (angForm.controls['email'].dirty || angForm.controls['email'].touched)" class="invalid-feedback">
  <div *ngIf="angForm.controls['email'].errors.required">
    This field is required.
  </div>
  <div *ngIf="!email.errors?.['required'] && email.errors?.['emailValidator']">
    Invalid email format.
  </div>
</div></div>
<div class="form-group">
<label for="Password">Password</label>
<input type="password" name="Password" formControlName="password"  required minlength="15" autocomplete="off" class="form-control input-sm" placeholder="Password"
[class.is-invalid]="angForm.controls['password'].invalid && (angForm.controls['password'].dirty || angForm.controls['password'].touched)">
            <button type="button" class="btn btn-outline-secondary" (click)="user.showPassword = !user.showPassword">
              <i class="bi" [ngClass]="{'bi-eye-fill': !user.showPassword, 'bi-eye-slash-fill': user.showPassword}"></i>
            </button>
            <div *ngIf="angForm.controls['password'].invalid && (angForm.controls['password'].dirty || angForm.controls['password'].touched)" class="invalid-feedback">
              <div *ngIf="angForm.controls['password'].errors.required">
                This field is required.
              </div>
              <div *ngIf="angForm.controls['password'].errors.minlength">
                This field must have at least 8 characters.
              </div>
            </div></div>
<button type="submit" class="btn btn-success"  (click)="validate(angForm1)">Register</button>
</form>
</div>
</div>
<div class="col-md-3">
</div>
</div>