Do not speak Portuguese? Translate this site with Google or Bing Translator
Tutorial FullStack Angular 10 + Laravel 8 + MySQL

Posted on: February 10, 2023 06:58 PM

Posted by: Renato

Categories: Laravel angular angularjs

Views: 410

Tutorial FullStack – Angular 10 + Laravel 8 + MySQL

Angular 10 ( Frontend )

Instala Angular 10

npm install -g @angular/cli@10

ng version

1 – Create app / Crear app

ng new app-tutofox
Would you like to add Angular routing? (y/N): y

Solução de erro
 

https://es.stackoverflow.com/questions/450769/error-en-ng-new-angular-cli

2 – Install bootstrap / Instalar bootstrap

ng add @ng-bootstrap/ng-bootstrap

3 – Create module / Crear module

ng generate module person --routing

4 – Create component / Crear componente

ng generate component person/index
ng generate component person/create
ng generate component person/edit

5 – Create routes / Crear rutas

src/app/person/person-routing.module.ts

/.../
import { IndexComponent } from './index/index.component';
import { CreateComponent } from './create/create.component';
import { EditComponent } from './edit/edit.component';

 
const routes: Routes = [
  { path: 'person', redirectTo: 'person/index', pathMatch: 'full'},
  { path: 'person/index', component: IndexComponent },
  { path: 'person/create', component: CreateComponent },
  { path: 'person/edit/:idPerson', component: EditComponent } 
];
/.../

6 – Create interface / Crear interface

ng generate interface person/person

src/app/person/person.ts

export interface Person {
    id: number;
    name: string;
    email: string;
    phone: number;
}

7 – Create services / Crear servicios

src/app/person/person.service.ts

ng generate service person/person

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import {  Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Person } from './person';
@Injectable({
  providedIn: 'root'
})
export class PersonService {
  private apiURL = "http://localhost:8000/api/person/";
  httpOptions = {
     headers: new HttpHeaders({
       'Content-Type': 'application/json'
     })
  }
  constructor(private httpClient: HttpClient) { }
  getAll(): Observable<Person[]> {
   return this.httpClient.get<Person[]>(this.apiURL)
   .pipe(
     catchError(this.errorHandler)
   )
 }
 create(person): Observable<Person> {
   return this.httpClient.post<Person>(this.apiURL, JSON.stringify(person), this.httpOptions)
   .pipe(
     catchError(this.errorHandler)
   )
 }
 find(id): Observable<Person> {
   return this.httpClient.get<Person>(this.apiURL + id)
   .pipe(
     catchError(this.errorHandler)
   )
 }
 update(id, person): Observable<Person> {
   return this.httpClient.put<Person>(this.apiURL + id, JSON.stringify(person), this.httpOptions)
   .pipe(
     catchError(this.errorHandler)
   )
 }
 delete(id){
   return this.httpClient.delete<Person>(this.apiURL + id, this.httpOptions)
   .pipe(
     catchError(this.errorHandler)
   )
 }
 errorHandler(error) {
   let errorMessage = '';
   if(error.error instanceof ErrorEvent) {
     errorMessage = error.error.message;
   } else {
     errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
   }
   return throwError(errorMessage);
 }
}

8 – Components / Componentes

Component Index

src/app/person/index/index.component.ts

import { Component, OnInit } from '@angular/core';
import { PersonService } from '../person.service';
import { Person } from '../person';
@Component({
  selector: 'app-index',
  templateUrl: './index.component.html',
  styleUrls: ['./index.component.css']
})
export class IndexComponent implements OnInit {
  persons: Person[] = [];
  // constructor() { }
  constructor(public personService: PersonService) { }
  ngOnInit(): void {
    this.personService.getAll().subscribe((data: Person[])=>{
      this.persons = data;
      console.log(this.persons);
    })
  }
  deletePerson(id){
    this.personService.delete(id).subscribe(res => {
         this.persons = this.persons.filter(item => item.id !== id);
         console.log('Person deleted successfully!');
    })
  }
}

src/app/person/index/index.component.html

<section>
    <div class="d-flex justify-content-between">
      <h4>List person</h4>
      <a routerLink="/person/create" class="btn btn-success">Create New Person</a>
    </div>
    <br>

 
    <table class="table ">
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Email</th>
        <th>Phone</th>
        <th width="220px">Action</th>
      </tr>
      <tr *ngFor="let person of persons">
        <td>{{ person.id }}</td>
        <td>{{ person.name }}</td>
        <td>{{ person.email }}</td>
        <td>{{ person.phone }}</td>
        <td>
          <a href="#" [routerLink]="['/person/', 'edit', person.id  ]" class="btn btn-primary">Edit</a>
          <button type="button" (click)="deletePerson(person.id)" class="btn btn-danger">Delete</button>
        </td>
      </tr>
    </table>
 </section>

Component Create

src/app/person/create/create.component.ts

import { Component, OnInit } from '@angular/core';
import { PersonService } from '../person.service';
import { Router } from '@angular/router';
import { FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
  selector: 'app-create',
  templateUrl: './create.component.html',
  styleUrls: ['./create.component.css']
})
export class CreateComponent implements OnInit {
  form: FormGroup;
  constructor(
    public personService: PersonService,
    private router: Router
  ) { }
  ngOnInit(): void {
    this.form = new FormGroup({
      name:  new FormControl('', [ Validators.required, Validators.pattern('^[a-zA-ZÁáÀàÉéÈèÍíÌìÓóÒòÚúÙùÑñüÜ \-\']+') ]),
      email: new FormControl('', [ Validators.required, Validators.email ]),
      phone: new FormControl('', [ Validators.required, Validators.pattern("^[0-9]*$") ])
    });
  }
  get f(){
    return this.form.controls;
  }
  submit(){
    console.log(this.form.value);
    this.personService.create(this.form.value).subscribe(res => {
         console.log('Person created successfully!');
         this.router.navigateByUrl('person/index');
    })
  }
}

src/app/person/create/create.component.html

<div>
  <div class="d-flex justify-content-between">
    <h4>Form customer</h4>
    <a href="#" routerLink="/person/index" class="btn btn-primaryt">Back</a>
  </div>
  <hr/>
    <form [formGroup]="form" (ngSubmit)="submit()">
        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="title">Name:</label>
              <input
                formControlName="name"
                id="name"
                type="text"
                class="form-control">
              <div *ngIf="f.name.touched && f.name.invalid" class="alert alert-danger">
                  <div *ngIf="f.name.errors.required">*Name is required.</div>
                  <div *ngIf="f.name.errors.pattern">*The name must only contain letters.</div>
              </div>
            </div>
        </div>
        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="email">Email:</label>
              <input
                formControlName="email"
                id="email"
                type="text"
                class="form-control">
              <div *ngIf="f.email.touched && f.email.invalid" class="alert alert-danger">
                  <div *ngIf="f.email.errors.required">*Email is required.</div>
                  <div *ngIf="f.email.errors.email">*The email must be a valid email address.</div>
              </div>
            </div>
        </div>
        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="phone">Phone:</label>
              <input
                formControlName="phone"
                id="phone"
                type="text"
                class="form-control">
              <div *ngIf="f.phone.touched && f.phone.invalid" class="alert alert-danger">
                  <div *ngIf="f.phone.errors.required">*Phone is required.</div>
                  <div *ngIf="f.phone.errors.pattern">*The phone must only contain numbers.</div>
              </div>
            </div>
        </div>
        <button class="btn btn-primary" type="submit" [disabled]="!form.valid">Submit</button>
    </form>
</div>

Component Edit

src/app/person/edit/edit.component.ts

import { Component, OnInit } from '@angular/core';
import { PersonService } from '../person.service';
import { ActivatedRoute, Router } from '@angular/router';
import { FormGroup, FormControl, Validators} from '@angular/forms';
import { Person } from '../person';
@Component({
  selector: 'app-edit',
  templateUrl: './edit.component.html',
  styleUrls: ['./edit.component.css']
})
export class EditComponent implements OnInit {
  id: number;
  person: Person;
  form: FormGroup;
  constructor(
    public personService: PersonService,
    private route: ActivatedRoute,
    private router: Router
  ) { }
  ngOnInit(): void {
    this.id = this.route.snapshot.params['idPerson'];
    this.personService.find(this.id).subscribe((data: Person)=>{
      this.person = data;
    });
    this.form = new FormGroup({
      name:  new FormControl('', [ Validators.required, Validators.pattern('^[a-zA-ZÁáÀàÉéÈèÍíÌìÓóÒòÚúÙùÑñüÜ \-\']+') ]),
      email: new FormControl('', [ Validators.required, Validators.email ]),
      phone: new FormControl('', [ Validators.required, Validators.pattern("^[0-9]*$") ])
    });
  }
  get f(){
    return this.form.controls;
  }
  submit(){
    console.log(this.form.value);
    this.personService.update(this.id, this.form.value).subscribe(res => {
         console.log('Person updated successfully!');
         this.router.navigateByUrl('person/index');
    })
  }
}

src/app/person/edit/edit.component.html

<div class="container">

 
    <div class="d-flex justify-content-between">
      <h4>Edit person</h4>
      <a href="#" routerLink="/person/index" class="btn btn-primaryt">Back</a>
    </div>
    <hr>
    <form [formGroup]="form" (ngSubmit)="submit()">
        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="title">Name:</label>
              <input
                formControlName="name"
                [(ngModel)]="person.name"
                id="name"
                type="text"
                class="form-control">
              <div *ngIf="f.name.touched && f.name.invalid" class="alert alert-danger">
                  <div *ngIf="f.name.errors.required">*Name is required.</div>
                  <div *ngIf="f.name.errors.pattern">*The name must only contain letters.</div>
              </div>
            </div>
        </div>
        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="email">Email:</label>
              <input
                formControlName="email"
                [(ngModel)]="person.email"
                id="email"
                type="text"
                class="form-control">
              <div *ngIf="f.email.touched && f.email.invalid" class="alert alert-danger">
                  <div *ngIf="f.email.errors.required">*Email is required.</div>
                  <div *ngIf="f.email.errors.email">*The email must be a valid email address.</div>
              </div>
            </div>
        </div>
        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="phone">Phone:</label>
              <input
                [(ngModel)]="person.phone"
                formControlName="phone"
                id="phone"
                type="text"
                class="form-control">
              <div *ngIf="f.phone.touched && f.phone.invalid" class="alert alert-danger">
                  <div *ngIf="f.phone.errors.required">*Phone is required.</div>
                  <div *ngIf="f.phone.errors.pattern">*The phone must only contain numbers.</div>
              </div>
            </div>
        </div>
        <button class="btn btn-primary" type="submit" [disabled]="!form.valid">Update</button>
    </form>
</div>

9 – Configure person module / Configurar modulo person

src/app/person/person.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PersonRoutingModule } from './person-routing.module';
import { IndexComponent } from './index/index.component';
import { CreateComponent } from './create/create.component';
import { EditComponent } from './edit/edit.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
  declarations: [
    IndexComponent,
    CreateComponent,
    EditComponent
  ],
  imports: [
    CommonModule,
    PersonRoutingModule,
    FormsModule,
    ReactiveFormsModule
  ]
})
export class PersonModule { }

10 – Configure App / Configurar App

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { PersonModule } from './person/person.module';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    PersonModule,
    HttpClientModule,
    NgbModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

src/app/app.component.html

<div class="container" style="padding:20px;">
    <h1 style="text-align:center;">
        <a href="/person/index"> Full Stack - Angular 10 & Laravel 8 </a>
    </h1>
    <hr>
  <main>
  <router-outlet></router-outlet>
  </main>
</div>

Laravel 8 ( Backend )

1 – Create project / Crear proyecto

composer create-project --prefer-dist laravel/laravel backend

2 – Configure Database / Configurar Base de datos

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=name_database
DB_USERNAME=user_database
DB_PASSWORD='password_database'

3 – Create migrate / Crear migracion

php artisan make:migration create_person_table 

database/migrations/2021_05_17_011217_create_person_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePersonTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('person', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email');
            $table->bigInteger('phone');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('person');
    }
}

Run migrate / ejecutar migrate

 php artisan migrate

4 – Create Model / Crear Modelo

php artisan make:model Person

app/Models/Person.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
    use HasFactory;
    protected $table = "person";
    protected $fillable = [
      'name',
      'email',
      'phone'
    ];

 
}

5 – Create Controller / Crear Controlador

php artisan make:controller API/PersonController

app/Http/Controllers/API/PersonController.php

<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
Use App\Models\Person;
Use Log;
class PersonController extends Controller
{
    // https://carbon.now.sh/
    public function getAll(){
      $data = Person::get();
      return response()->json($data, 200);
    }
    public function create(Request $request){
      $data['name'] = $request['name'];
      $data['email'] = $request['email'];
      $data['phone'] = $request['phone'];
      Person::create($data);
      return response()->json([
          'message' => "Successfully created",
          'success' => true
      ], 200);
    }
    public function delete($id){
      $res = Person::find($id)->delete();
      return response()->json([
          'message' => "Successfully deleted",
          'success' => true
      ], 200);
    }
    public function get($id){
      $data = Person::find($id);
      return response()->json($data, 200);
    }
    public function update(Request $request,$id){
      $data['name'] = $request['name'];
      $data['email'] = $request['email'];
      $data['phone'] = $request['phone'];
      Person::find($id)->update($data);
      return response()->json([
          'message' => "Successfully updated",
          'success' => true
      ], 200);
    }
}

6 – Create routes / Crear rutas

routes/api.php

use App\Http\Controllers\API\PersonController;
Route::prefix('person')->group(function () {
    Route::get('/',[ PersonController::class, 'getAll']);
    Route::post('/',[ PersonController::class, 'create']);
    Route::delete('/{id}',[ PersonController::class, 'delete']);
    Route::get('/{id}',[ PersonController::class, 'get']);
    Route::put('/{id}',[ PersonController::class, 'update']);
});

GitHub

https://github.com/lucenarenato/angular-10-laravel-8

Fonte:

- https://www.tutofox.com/angular/fullstack-crud-app-angular-10-laravel-8-mysql/

 


3

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 0 Comments

No comments yet! Be the first to comment

Blog Search


Categories

OUTROS (16) Variados (109) PHP (133) Laravel (171) Black Hat (3) front-end (29) linux (114) postgresql (39) Docker (28) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (56) devops (25) nodejs (5) npm (3) nvm (1) git (8) firefox (1) react (7) reactnative (5) collections (1) javascript (7) reactjs (8) yarn (0) adb (1) Solid (2) blade (3) models (1) controllers (0) log (1) html (2) hardware (3) aws (14) Transcribe (2) transcription (1) google (4) ibm (1) nuance (1) PHP Swoole (5) mysql (31) macox (4) flutter (1) symfony (1) cor (1) colors (2) homeOffice (2) jobs (3) imagick (2) ec2 (1) sw (1) websocket (2) markdown (1) ckeditor (1) tecnologia (14) faceapp (1) eloquent (14) query (4) sql (40) ddd (3) nginx (9) apache (4) certbot (1) lets-encrypt (3) debian (12) liquid (1) magento (2) ruby (1) LETSENCRYPT (1) Fibonacci (1) wine (1) transaction (1) pendrive (1) boot (1) usb (1) prf (1) policia (2) federal (1) lucena (1) mongodb (4) paypal (1) payment (1) zend (1) vim (4) ciencia (6) js (1) nosql (1) java (1) JasperReports (1) phpjasper (1) covid19 (1) saude (1) athena (1) cinnamon (1) phpunit (2) binaural (1) mysqli (3) database (42) windows (6) vala (1) json (2) oracle (1) mariadb (4) dev (12) webdev (24) s3 (4) storage (1) kitematic (1) gnome (2) web (2) intel (3) piada (1) cron (2) dba (18) lumen (1) ffmpeg (2) android (2) aplicativo (1) fedora (2) shell (4) bash (3) script (3) lider (1) htm (1) csv (1) dropbox (1) db (3) combustivel (2) haru (1) presenter (1) gasolina (1) MeioAmbiente (1) Grunt (1) biologia (1) programming (22) performance (3) brain (1) smartphones (1) telefonia (1) privacidade (1) opensource (3) microg (1) iode (1) ssh (3) zsh (2) terminal (3) dracula (1) spaceship (1) mac (2) idiomas (1) laptop (2) developer (37) api (5) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (3) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (43) Kubernetes (3) vscode (2) backup (1) angular (3) servers (2) pipelines (1) AppSec (1) DevSecOps (4) rust (1) RustLang (1) Mozilla (1) algoritimo (1) sqlite (1) Passport (2) jwt (5) security (2) translate (1) kube (2) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (3) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (3) Architecture (4) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (2) autorizacao (2) authentication (4) authorization (3) NoCookies (1) wsl (4) memcached (1) macos (2) unix (2) kali-linux (1) linux-tools (5) apple (1) noticias (2) composer (1) rancher (1) k8s (1) escopos (1) orm (1) jenkins (4) github (5) gitlab (3) queue (1) Passwordless (1) sonarqube (1) phpswoole (1) laraveloctane (1) Swoole (1) Swoole (1) octane (1) Structurizr (1) Diagramas (1) c4 (1) c4-models (1) compactar (1) compression (1) messaging (1) restfull (1) eventdrive (1) services (1) http (1) Monolith (1) microservice (1) historia (1) educacao (1) cavalotroia (1) OOD (0) odd (1) chatgpt (1) openai (3) vicuna (1) llama (1) gpt (1) transformers (1) pytorch (1) tensorflow (1) akitando (1) ia (1) nvidia (1) agi (1) guard (1) multiple_authen (2) rpi (1) auth (1) auth (1) livros (2) ElonMusk (2) Oh My Zsh (1) Manjaro (1) BigLinux (2) ArchLinux (1) Migration (1) Error (1) Monitor (1) Filament (1) LaravelFilament (1) replication (1) phpfpm (1) cache (1) vpn (1) l2tp (1) zorin-os (1) optimization (1) scheduling (1) monitoring (2) linkedin (1) community (1) inteligencia-artificial (2) wsl2 (1) maps (1) API_KEY_GOOGLE_MAPS (1) repmgr (1) altadisponibilidade (1) banco (1) modelagemdedados (1) inteligenciadedados (4) governancadedados (1) bancodedados (2) Observability (1) picpay (1) ecommerce (1) Curisidades (1) Samurai (1) KubeCon (1) GitOps (1) Axios (1) Fetch (1) Deepin (1) vue (4) nuxt (1) PKCE (1) Oauth2 (2) webhook (1) TypeScript (1) tailwind (1) gource (2)

New Articles



Get Latest Updates by Email