پروژه ساخت اپلیکیشن نمونه MEAN Stack با پشتیبانی از انگولار 9 (قسمت سوم)

01 اردیبهشت 1399
Angular-9-MEAN-Stack-Tutorial

با قسمت سوم از آموزش پروژه با انگولار یا اپلیکیشن نمونه MEAN Stack با شما هستیم. قسمت اول را اینجا و قسمت دوم را اینجا مشاهده کنید.

8. ایجاد سرویسی برای صرف RESTful API

برای صرف RESTful APIها در اپلیکیشن MEAN Stack خود، باید یک فایل سرویس (service file) ایجاد کنیم. این سرویس مسئولیت عملیات های Create و Read و Update و Delete محتوا را برعهده خواهد داشت.

قبل از این که سرویس را در اپلیکیشن ایجاد کنیم، باید دو کار زیر را انجام دهیم.

  • پیکربندی HttpClientModule 

باید سرویس HttpClientModule را در فایل app.module.ts ایمپورت کنیم.

import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [
    HttpClientModule
   ]
})

خب پس تا اینجا HttpClientModule را در اپلیکیشن خود جای دادید.

  • ایجاد فایلی برای مدل کارمندان (Employee Model File)

فایل employee.ts را در با استفاده از فرمان زیر مسیر src > model > employee.ts بسازید.

ng g cl model/Employee

کدهای زیر را درون آن بریزید:

export class Employee {
   name: string;
   email: string;
   designation: string;
   phoneNumber: number;
}

ساخت سرویس انگولار

از فرمان زیر برای ایجاد فایل سرویس انگولار (Angular Service file) استفاده کنید. این فایل نیز برای مدیریت عملیات های CRUD مورد استفاده قرار می گیرد.

ng g s service/api

حال به فایل api.service.ts در مسیر src > app > service > api.service.ts بروید و کدهای زیر را درون آن بریزید:

import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})

export class ApiService {
  
  baseUri:string = 'http://localhost:4000/api';
  headers = new HttpHeaders().set('Content-Type', 'application/json');

  constructor(private http: HttpClient) { }

  // Create
  createEmployee(data): Observable<any> {
    let url = `${this.baseUri}/create`;
    return this.http.post(url, data)
      .pipe(
        catchError(this.errorMgmt)
      )
  }

  // Get all employees
  getEmployees() {
    return this.http.get(`${this.baseUri}`);
  }

  // Get employee
  getEmployee(id): Observable<any> {
    let url = `${this.baseUri}/read/${id}`;
    return this.http.get(url, {headers: this.headers}).pipe(
      map((res: Response) => {
        return res || {}
      }),
      catchError(this.errorMgmt)
    )
  }

  // Update employee
  updateEmployee(id, data): Observable<any> {
    let url = `${this.baseUri}/update/${id}`;
    return this.http.put(url, data, { headers: this.headers }).pipe(
      catchError(this.errorMgmt)
    )
  }

  // Delete employee
  deleteEmployee(id): Observable<any> {
    let url = `${this.baseUri}/delete/${id}`;
    return this.http.delete(url, { headers: this.headers }).pipe(
      catchError(this.errorMgmt)
    )
  }

  // Error handling 
  errorMgmt(error: HttpErrorResponse) {
    let errorMessage = '';
    if (error.error instanceof ErrorEvent) {
      // Get client-side error
      errorMessage = error.error.message;
    } else {
      // Get server-side error
      errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
    }
    console.log(errorMessage);
    return throwError(errorMessage);
  }

}

خب Angular service file را هم برای به دوش کشیدن عملیات های CRUD ساختیم. حال به فایل app.module.ts بروید و سرویس زیر را در آن ایمپورت کرده و به ارایه ی providers اضافه کنید. مثل کد زیر:

import { ApiService } from './service/api.service';

@NgModule({
  providers: [ApiService]
})

9.ثبت نام یک کارمند با صرف RESTful API

برای ثبت نام یک کارمند در اپلیکیشن، از سرویس انگولار و RESTful API استفاده می کنیم. من از یک فرم واکنشی برای ثبت نام یک کارمند استفاده کرده ام.

به فایل employee-create.component.ts واقع در مسیر components > employee-create بروید و کدهای زیر را درون آن بریزید.

import { Router } from '@angular/router';
import { ApiService } from './../../service/api.service';
import { Component, OnInit, NgZone } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from "@angular/forms";

@Component({
  selector: 'app-employee-create',
  templateUrl: './employee-create.component.html',
  styleUrls: ['./employee-create.component.css']
})

export class EmployeeCreateComponent implements OnInit {  
  submitted = false;
  employeeForm: FormGroup;
  EmployeeProfile:any = ['Finance', 'BDM', 'HR', 'Sales', 'Admin']
  
  constructor(
    public fb: FormBuilder,
    private router: Router,
    private ngZone: NgZone,
    private apiService: ApiService
  ) { 
    this.mainForm();
  }

  ngOnInit() { }

  mainForm() {
    this.employeeForm = this.fb.group({
      name: ['', [Validators.required]],
      email: ['', [Validators.required, Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$')]],
      designation: ['', [Validators.required]],
      phoneNumber: ['', [Validators.required, Validators.pattern('^[0-9]+$')]]
    })
  }

  // Choose designation with select dropdown
  updateProfile(e){
    this.employeeForm.get('designation').setValue(e, {
      onlySelf: true
    })
  }

  // Getter to access form control
  get myForm(){
    return this.employeeForm.controls;
  }

  onSubmit() {
    this.submitted = true;
    if (!this.employeeForm.valid) {
      return false;
    } else {
      this.apiService.createEmployee(this.employeeForm.value).subscribe(
        (res) => {
          console.log('Employee successfully created!')
          this.ngZone.run(() => this.router.navigateByUrl('/employees-list'))
        }, (error) => {
          console.log(error);
        });
    }
  }

}

همچنین به فایل employee-create.component.html بروید و کدهای زیر را درون آن کپی کنید.

<div class="row justify-content-center">
  <div class="col-md-4 register-employee">
    <!-- form card register -->
    <div class="card-body">
      <form [formGroup]="employeeForm" (ngSubmit)="onSubmit()">
        <div class="form-group">
          <label for="inputName">Name</label>
          <input class="form-control" type="text" formControlName="name">
          <!-- error -->
          <div class="invalid-feedback" *ngIf="submitted && myForm.name.errors?.required">
            Name is required.
          </div>
        </div>

        <div class="form-group">
          <label for="inputEmail3">Email</label>
          <input class="form-control" type="text" formControlName="email">
          <!-- error -->
          <div class="invalid-feedback" *ngIf="submitted && myForm.email.errors?.required">
            Enter your email.
          </div>
          <div class="invalid-feedback" *ngIf="submitted && myForm.email.errors?.pattern">
            Enter valid email.
          </div>
        </div>

        <div class="form-group">
          <label for="inputPassword3">Designation</label>
          <select class="custom-select form-control" (change)="updateProfile($event.target.value)"
            formControlName="designation">
            <option value="">Choose...</option>
            <option *ngFor="let employeeProfile of EmployeeProfile" value="{{employeeProfile}}">{{employeeProfile}}
            </option>
          </select>
          <!-- error -->
          <div class="invalid-feedback" *ngIf="submitted && myForm.designation.errors?.required">
            Choose designation.
          </div>
        </div>

        <div class="form-group">
          <label for="inputVerify3">Mobile No</label>
          <input class="form-control" type="text" formControlName="phoneNumber">
          <!-- error -->
          <div class="invalid-feedback" *ngIf="submitted && myForm.phoneNumber.errors?.required">
            Enter your phone number.
          </div>
          <div class="invalid-feedback" *ngIf="submitted && myForm.phoneNumber.errors?.pattern">
            Enter Numbers Only
          </div>
        </div>

        <div class="form-group">
          <button class="btn btn-success btn-lg btn-block" type="submit">Register</button>
        </div>
      </form>

    </div>
  </div><!-- form card register -->
</div>

10. نمایش لیست کارمندان و ابجکت Delete با استفاده از  RESTful API

برای نمایش لیست کارمندان نیز از سرویس انگولار (Angular service) و RESTful API استفاده خواهیم کرد. به فایل employee-list.component.ts واقع در مسیر src/app/components/employee-list بروید و کدهای زیر را درون آن کپی کنید:

import { Component, OnInit } from '@angular/core';
import { ApiService } from './../../service/api.service';

@Component({
  selector: 'app-employee-list',
  templateUrl: './employee-list.component.html',
  styleUrls: ['./employee-list.component.css']
})

export class EmployeeListComponent implements OnInit {
  
  Employee:any = [];

  constructor(private apiService: ApiService) { 
    this.readEmployee();
  }

  ngOnInit() {}

  readEmployee(){
    this.apiService.getEmployees().subscribe((data) => {
     this.Employee = data;
    })    
  }

  removeEmployee(employee, index) {
    if(window.confirm('Are you sure?')) {
        this.apiService.deleteEmployee(employee._id).subscribe((data) => {
          this.Employee.splice(index, 1);
        }
      )    
    }
  }

}

برای نمایش لیست کارمندان نیز فایل employee-list.component.html را از مسیر src/app/components/employee-list باز کنید و کدهای زیر رادرون آن بریزید:

<div class="container">
  <!-- No data message -->
  <p *ngIf="Employee.length <= 0" class="no-data text-center">There is no employee added yet!</p>

  <!-- Employee list -->
  <table class="table table-bordered" *ngIf="Employee.length > 0">
    <thead class="table-success">
      <tr>
        <th scope="col">Employee ID</th>
        <th scope="col">Name</th>
        <th scope="col">Email</th>
        <th scope="col">Designation</th>
        <th scope="col">Phone No</th>
        <th scope="col center">Update</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let employee of Employee; let i = index">
        <th scope="row">{{employee._id}}</th>
        <td>{{employee.name}}</td>
        <td>{{employee.email}}</td>
        <td>{{employee.designation}}</td>
        <td>{{employee.phoneNumber}}</td>
        <td class="text-center edit-block">
          <span class="edit" [routerLink]="['/edit-employee/', employee._id]">
            <button type="button" class="btn btn-success btn-sm">Edit</button>
          </span>
          <span class="delete" (click)="removeEmployee(employee, i)">
            <button type="button" class="btn btn-danger btn-sm">Delete</button>
          </span>
        </td>
      </tr>
    </tbody>
  </table>
</div>

11. ویرایش اطلاعات کارمندان در اپلیکیشن

به منظور ایجاد قابلیت ویرایش اطلاعات کارمندان در اپلیکیشن، کدهای زیر را در فایل employee-edit.component.html واقع در مسیر src/app/components/employee-edit کپی نمایید:

<div class="row justify-content-center">
   <div class="col-md-4 register-employee">
     <!-- form card register -->
     <div class="card card-outline-secondary">
       <div class="card-header">
         <h3 class="mb-0">Edit Employee</h3>
       </div>
       <div class="card-body">
         <form [formGroup]="editForm" (ngSubmit)="onSubmit()">

           <div class="form-group">
             <label for="inputName">Name</label>
             <input class="form-control" type="text" formControlName="name">
             <div class="invalid-feedback" *ngIf="submitted && myForm.name.errors?.required">
               Name is required.
             </div>
           </div>
           <div class="form-group">
             <label for="inputEmail3">Email</label>
             <input class="form-control" type="text" formControlName="email">
             <!-- error -->
             <div class="invalid-feedback" *ngIf="submitted && myForm.email.errors?.required">
               Enter your email.
             </div>
             <div class="invalid-feedback" *ngIf="submitted && myForm.email.errors?.pattern">
               Enter valid email.
             </div>
           </div>

           <div class="form-group">
             <label for="inputPassword3">Designation</label>
             <select class="custom-select form-control" (change)="updateProfile($event.target.value)"
               formControlName="designation">
               <option value="">Choose...</option>
               <option *ngFor="let employeeProfile of EmployeeProfile" value="{{employeeProfile}}">{{employeeProfile}}
               </option>
             </select>
             <!-- error -->
             <div class="invalid-feedback" *ngIf="submitted && myForm.designation.errors?.required">
               Choose designation.
             </div>
           </div>

           <div class="form-group">
             <label for="inputVerify3">Mobile No</label>
             <input class="form-control" type="text" formControlName="phoneNumber">
             <!-- error -->
             <div class="invalid-feedback" *ngIf="submitted && myForm.phoneNumber.errors?.required">
               Enter your phone number.
             </div>
             <div class="invalid-feedback" *ngIf="submitted && myForm.phoneNumber.errors?.pattern">
               Enter Numbers Only
             </div>
           </div>

           <div class="form-group">
             <button class="btn btn-success btn-lg btn-block" type="submit">Update</button>
           </div>
         </form>
       </div>
     </div><!-- form  -->
   </div>
 </div>

همچنین کدهای زیر را نیز در فایل employee-edit.component.ts واقع در مسیر src/app/components/employee-edit بریزید:

import { Employee } from './../../model/Employee';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from "@angular/router";
import { ApiService } from './../../service/api.service';
import { FormGroup, FormBuilder, Validators } from "@angular/forms";


@Component({
  selector: 'app-employee-edit',
  templateUrl: './employee-edit.component.html',
  styleUrls: ['./employee-edit.component.css']
})

export class EmployeeEditComponent implements OnInit {
  submitted = false;
  editForm: FormGroup;
  employeeData: Employee[];
  EmployeeProfile: any = ['Finance', 'BDM', 'HR', 'Sales', 'Admin']

  constructor(
    public fb: FormBuilder,
    private actRoute: ActivatedRoute,
    private apiService: ApiService,
    private router: Router
  ) {}

  ngOnInit() {
    this.updateEmployee();
    let id = this.actRoute.snapshot.paramMap.get('id');
    this.getEmployee(id);
    this.editForm = this.fb.group({
      name: ['', [Validators.required]],
      email: ['', [Validators.required, Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$')]],
      designation: ['', [Validators.required]],
      phoneNumber: ['', [Validators.required, Validators.pattern('^[0-9]+$')]]
    })
  }

  // Choose options with select-dropdown
  updateProfile(e) {
    this.editForm.get('designation').setValue(e, {
      onlySelf: true
    })
  }

  // Getter to access form control
  get myForm() {
    return this.editForm.controls;
  }

  getEmployee(id) {
    this.apiService.getEmployee(id).subscribe(data => {
      this.editForm.setValue({
        name: data['name'],
        email: data['email'],
        designation: data['designation'],
        phoneNumber: data['phoneNumber'],
      });
    });
  }

  updateEmployee() {
    this.editForm = this.fb.group({
      name: ['', [Validators.required]],
      email: ['', [Validators.required, Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$')]],
      designation: ['', [Validators.required]],
      phoneNumber: ['', [Validators.required, Validators.pattern('^[0-9]+$')]]
    })
  }

  onSubmit() {
    this.submitted = true;
    if (!this.editForm.valid) {
      return false;
    } else {
      if (window.confirm('Are you sure?')) {
        let id = this.actRoute.snapshot.paramMap.get('id');
        this.apiService.updateEmployee(id, this.editForm.value)
          .subscribe(res => {
            this.router.navigateByUrl('/employees-list');
            console.log('Content updated successfully!')
          }, (error) => {
            console.log(error)
          })
      }
    }
  }

}

این هم از این! پروژه ی ما تکمیل است. حال همانطور که می دانید، می توانید با اجرای فرمان ng serve اپلیکیشن خود را مشاهده کنید. همچنین دموی اپلیکیشن در ویدیو زیر موجود است.

نتیجه گیری

ما یک پروژه را قدم به قدم با استفاده از تکنولوژی های MEAN ساختیم و نتیجه، یک اپلیکیشن مدیریت کارمندان شد. همانطور که قبلا گفتیم این پروژه یک آموزش مبتدی نبوده بلکه یک پروژه ی تخصصی برای افرادی است که به چهار تکنولوژی مذکور آشنایی داشته باشند و بتوانند کد بخوانند. کدهای این پروژه را می توانید از اینجا دانلود کنید. امید وارم که این پروژه برای شما مفید واقع شده باشد. سوالات و نظرات خود را در زیر همین مطلب درج نمایید. موفق و سربلند باشید.


منبع: سایت Positronx

نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.