Step .1
app.module.ts
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { HttpClientModule } from "@angular/common/http";
import { ReactiveFormsModule } from "@angular/forms";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { BlogPostsComponent } from "./Components/blog-posts/blog-posts.component";
import { BlogPostComponent } from "./Components/blog-post/blog-post.component";
import { BlogPostAddEditComponent } from "./Components/blog-post-add-edit/blog-post-add-edit.component";
import { BlogPostService } from "./services/blog-post.service";
@NgModule({
declarations: [
AppComponent,
BlogPostsComponent,
BlogPostComponent,
BlogPostAddEditComponent,
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
ReactiveFormsModule,
],
providers: [BlogPostService],
bootstrap: [AppComponent],
})
export class AppModule {}
app.component.html
<div class="container">
<a [routerLink]="['/']" class="btn btn-danger">Home</a>
<router-outlet></router-outlet>
</div>
blog-posts.component.html
blog-posts.component.ts<h1>Blog posts</h1> <p *ngIf="!(blogPosts$ | async)"><em>Loading...</em></p> <p> <a [routerLink]="['/add']" class="btn btn-primary float-right mb-3">New post</a> </p> <table class="table table-sm table-hover" *ngIf="(blogPosts$ | async)?.length>0"> <thead> <tr> <th>#</th> <th>Title</th> <th>Creator</th> <th>Date</th> <th></th> <th></th> </tr> </thead> <tbody> <tr *ngFor="let blogPost of (blogPosts$ | async)"> <td>{{ blogPost.employeeId }}</td> <td><a [routerLink]="['/blogpost/', blogPost.employeeId]">{{ blogPost.employeeName }}</a></td> <td>{{ blogPost.phoneNumber }}</td> <td>{{ blogPost.skillId }}</td> <td><a [routerLink]="['/blogpost/edit/', blogPost.employeeId]" class="btn btn-primary btn-sm float-right">Edit</a></td> <td><a [routerLink]="" (click)="delete(blogPost.employeeId)" class="btn btn-danger btn-sm float-right">Delete</a></td> </tr> </tbody> </table>
blog-post-add-edit.component.htmlimport { Component, OnInit } from '@angular/core'; import { BlogPost } from 'src/app/services/models/BlogPos'; import { Observable } from 'rxjs'; import { BlogPostService } from 'src/app/services/blog-post.service'; @Component({ selector: 'app-blog-posts', templateUrl: './blog-posts.component.html', styleUrls: ['./blog-posts.component.css'] }) export class BlogPostsComponent implements OnInit { blogPosts$: Observable<BlogPost[]>; constructor(private blogPostService: BlogPostService) { } ngOnInit() { this.loadBlogPosts(); } loadBlogPosts() { this.blogPosts$ = this.blogPostService.getBlogPosts(); } delete(postId) { const ans = confirm('Do you want to delete blog post with id: ' + postId); if (ans) { this.blogPostService.deleteBlogPost(postId).subscribe((data) => { this.loadBlogPosts(); }); } } }
blog-post-add-edit.component.ts<h1>{{actionType}} blog post</h1> <form [formGroup]="form" (ngSubmit)="save()" #formDir="ngForm" novalidate> <div class="form-group row"> <label class=" control-label col-md-12">employee Name</label> <div class="col-md-12"> <input class="form-control" type="text" formControlName="employeeName"> </div> <span class="text-danger ml-3" *ngIf="employeeName.invalid && formDir.submitted"> employee Name is required. </span> </div> <div class="form-group row"> <label class="control-label col-md-12" for="phoneNumber">phone Number</label> <div class="col-md-12"> <textarea class="form-control" rows="15" formControlName="phoneNumber"></textarea> </div> <span class="text-danger ml-3" *ngIf="phoneNumber.invalid && formDir.submitted"> phone Number is required. </span> </div> <div class="form-group row"> <label class=" control-label col-md-12">skillId</label> <div class="col-md-12"> <input class="form-control" type="text" formControlName="skillId"> </div> <span class="text-danger ml-3" *ngIf="skillId.invalid && formDir.submitted"> skillId is required. </span> </div> <div class="form-group row"> <label class=" control-label col-md-12">yearsExperience</label> <div class="col-md-12"> <input class="form-control" type="text" formControlName="yearsExperience"> </div> <span class="text-danger ml-3" *ngIf="yearsExperience.invalid && formDir.submitted"> yearsExperience is required. </span> </div> <div class="form-group"> <button type="submit" class="btn btn-success float-right">Save</button> <button class="btn btn-secondary float-left" (click)="cancel()">Cancel</button> </div> </form>
BlogPos.tsimport { Component, OnInit } from '@angular/core'; import { BlogPost } from 'src/app/services/models/BlogPos'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Router, ActivatedRoute } from '@angular/router'; import { BlogPostService } from 'src/app/services/blog-post.service'; @Component({ selector: 'app-blog-post-add-edit', templateUrl: './blog-post-add-edit.component.html', styleUrls: ['./blog-post-add-edit.component.css'] }) export class BlogPostAddEditComponent implements OnInit { form: FormGroup; actionType: string; formemployeeName: string; formphoneNumber: string; formskillId: string; formyearsExperience: string; employeeId: number; errorMessage: any; existingBlogPost: BlogPost; // tslint:disable-next-line: max-line-length constructor(private blogPostService: BlogPostService, private formBuilder: FormBuilder, private avRoute: ActivatedRoute, private router: Router) { const idParam = 'id'; this.actionType = 'Add'; this.formemployeeName = 'employeeName'; this.formphoneNumber = 'phoneNumber'; this.formskillId = 'skillId'; this.formyearsExperience = 'yearsExperience'; if (this.avRoute.snapshot.params[idParam]) { this.employeeId = this.avRoute.snapshot.params[idParam]; } this.form = this.formBuilder.group( { employeeIdemployeeId: 0, employeeName: ['', [Validators.required]], phoneNumber: ['', [Validators.required]], skillId: ['', [Validators.required]], yearsExperience: ['', [Validators.required]] } ); } ngOnInit() { if (this.employeeId > 0) { this.actionType = 'Edit'; this.blogPostService.getBlogPost(this.employeeId) .subscribe(data => ( this.existingBlogPost = data, this.form.controls[this.formemployeeName].setValue(data.employeeName), this.form.controls[this.formphoneNumber].setValue(data.phoneNumber), this.form.controls[this.formskillId].setValue(data.skillId), this.form.controls[this.formyearsExperience].setValue(data.yearsExperience) )); } } save() { if (!this.form.valid) { return; } if (this.actionType === 'Add') { const blogPost: BlogPost = { employeeName: this.form.get(this.formemployeeName).value, phoneNumber: this.form.get(this.formphoneNumber).value, skillId: this.form.get(this.formskillId).value, yearsExperience: this.form.get(this.formyearsExperience).value }; this.blogPostService.saveBlogPost(blogPost) .subscribe((data) => { this.router.navigate(['/blogpost', data.employeeId]); }); } if (this.actionType === 'Edit') { const blogPost: BlogPost = { employeeId: this.existingBlogPost.employeeId, employeeName: this.form.get(this.formemployeeName).value, phoneNumber: this.form.get(this.formphoneNumber).value, skillId: this.form.get(this.formskillId).value, yearsExperience: this.form.get(this.formyearsExperience).value }; this.blogPostService.updateBlogPost(blogPost.employeeId, blogPost) .subscribe((data) => { this.router.navigate([this.router.url]); }); } } cancel() { this.router.navigate(['/']); } get employeeName() { return this.form.get(this.formemployeeName); } get phoneNumber() { return this.form.get(this.formphoneNumber); } get skillId() { return this.form.get(this.formskillId); } get yearsExperience() { return this.form.get(this.formyearsExperience); } }
blog-post.service.tsexport class BlogPost { employeeId?: number; employeeName: string; phoneNumber: string; skillId: number; yearsExperience: number; }
app-routing.module.tsimport { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { retry, catchError } from 'rxjs/operators'; import { environment } from 'src/environments/environment'; import { BlogPost } from './models/BlogPos'; @Injectable({ providedIn: 'root' }) export class BlogPostService { myAppUrl: string; myApiUrl: string; httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json; charset=utf-8' }) }; constructor(private http: HttpClient) { this.myAppUrl = environment.appUrl; this.myApiUrl = 'api/TblEmployees/'; } getBlogPosts(): Observable<BlogPost[]> { return this.http.get<BlogPost[]>(this.myAppUrl + this.myApiUrl) .pipe( retry(1), catchError(this.errorHandler) ); } getBlogPost(postId: number): Observable<BlogPost> { return this.http.get<BlogPost>(this.myAppUrl + this.myApiUrl + postId) .pipe( retry(1), catchError(this.errorHandler) ); } saveBlogPost(blogPost): Observable<BlogPost> { return this.http.post<BlogPost>(this.myAppUrl + this.myApiUrl, JSON.stringify(blogPost), this.httpOptions) .pipe( retry(1), catchError(this.errorHandler) ); } updateBlogPost(postId: number, blogPost): Observable<BlogPost> { return this.http.put<BlogPost>(this.myAppUrl + this.myApiUrl + postId, JSON.stringify(blogPost), this.httpOptions) .pipe( retry(1), catchError(this.errorHandler) ); } deleteBlogPost(postId: number): Observable<BlogPost> { return this.http.delete<BlogPost>(this.myAppUrl + this.myApiUrl + postId) .pipe( retry(1), catchError(this.errorHandler) ); } errorHandler(error) { 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); } }
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { BlogPostsComponent } from './Components/blog-posts/blog-posts.component';
import { BlogPostComponent } from './Components/blog-post/blog-post.component';
import { BlogPostAddEditComponent } from './Components/blog-post-add-edit/blog-post-add-edit.component';
const routes: Routes = [
{ path: '', component: BlogPostsComponent, pathMatch: 'full' },
{ path: 'blogpost/:id', component: BlogPostComponent },
{ path: 'add', component: BlogPostAddEditComponent },
{ path: 'blogpost/edit/:id', component: BlogPostAddEditComponent },
{ path: '**', redirectTo: '/' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
API
Install-Package Microsoft.EntityFrameworkCore.SqlServer
1. Scaffold-DbContext "Server=.;Database=MbkTest;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
2. Scaffold-DbContext "Server=.;Database=MbkTest;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables tblSkills -Force
Scaffold-DbContext [-Connection] [-Provider] [-OutputDir] [-Context] [-Schemas>] [-Tables>]
[-DataAnnotations] [-Force] [-Project] [-StartupProject] [<CommonParameters>]
Startup.cs
appsettings.jsonusing System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CurdAPP2.Models; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace CurdAPP2 { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddDbContext<MbkTestContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MbkTestCon"))); services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } //app.UseMvc(); app.UseCors("CorsPolicy"); app.UseHttpsRedirection(); app.UseStaticFiles(); //app.UseSpaStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller}/{action=Index}/{id?}"); }); } } }
TblEmployeesController.cs{ "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "MbkTestCon": "Server=.;Database=MbkTest;Trusted_Connection=True;MultipleActiveResultSets=true" } }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using CurdAPP2.Models;
namespace CurdAPP2.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TblEmployeesController : ControllerBase
{
private readonly MbkTestContext _context;
public TblEmployeesController(MbkTestContext context)
{
_context = context;
}
// GET: api/TblEmployees
[HttpGet]
public async Task<ActionResult<IEnumerable<TblEmployees>>> GetTblEmployees()
{
return await _context.TblEmployees.ToListAsync();
}
// GET: api/TblEmployees/5
[HttpGet("{id}")]
public async Task<ActionResult<TblEmployees>> GetTblEmployees(int id)
{
var tblEmployees = await _context.TblEmployees.FindAsync(id);
if (tblEmployees == null)
{
return NotFound();
}
return tblEmployees;
}
// PUT: api/TblEmployees/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTblEmployees(int id, TblEmployees tblEmployees)
{
if (id != tblEmployees.EmployeeId)
{
return BadRequest();
}
_context.Entry(tblEmployees).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TblEmployeesExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/TblEmployees
[HttpPost]
public async Task<ActionResult<TblEmployees>> PostTblEmployees(TblEmployees tblEmployees)
{
_context.TblEmployees.Add(tblEmployees);
await _context.SaveChangesAsync();
return CreatedAtAction("GetTblEmployees", new { id = tblEmployees.EmployeeId }, tblEmployees);
}
// DELETE: api/TblEmployees/5
[HttpDelete("{id}")]
public async Task<ActionResult<TblEmployees>> DeleteTblEmployees(int id)
{
var tblEmployees = await _context.TblEmployees.FindAsync(id);
if (tblEmployees == null)
{
return NotFound();
}
_context.TblEmployees.Remove(tblEmployees);
await _context.SaveChangesAsync();
return tblEmployees;
}
private bool TblEmployeesExists(int id)
{
return _context.TblEmployees.Any(e => e.EmployeeId == id);
}
}
}
CREATE TABLE [dbo].[tblEmployees](
[EmployeeID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[EmployeeName] [varchar](50) NULL,
[PhoneNumber] [varchar](50) NULL,
[SkillID] [int] NULL,
[YearsExperience] [int] NULL,
PRIMARY KEY CLUSTERED
(
[EmployeeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[tblEmployees] ON
INSERT [dbo].[tblEmployees] ([EmployeeID], [EmployeeName], [PhoneNumber], [SkillID], [YearsExperience]) VALUES (1, N'Suhana Kalla', N'9869569634', 2, 11111)
INSERT [dbo].[tblEmployees] ([EmployeeID], [EmployeeName], [PhoneNumber], [SkillID], [YearsExperience]) VALUES (2, N'Ashish Kalla', N'9869166077', 8, 14)
INSERT [dbo].[tblEmployees] ([EmployeeID], [EmployeeName], [PhoneNumber], [SkillID], [YearsExperience]) VALUES (3, N'Manoj Kalla', N'9869569634', 1, 24)
INSERT [dbo].[tblEmployees] ([EmployeeID], [EmployeeName], [PhoneNumber], [SkillID], [YearsExperience]) VALUES (6, N'Murli Vyas', N'9261166012', 5, 18)
INSERT [dbo].[tblEmployees] ([EmployeeID], [EmployeeName], [PhoneNumber], [SkillID], [YearsExperience]) VALUES (8, N'wer', N'1', 1, 1)
SET IDENTITY_INSERT [dbo].[tblEmployees] OFF
No comments :
Post a Comment