Home > Software engineering >  Cant submit more then one form in database from Angular because of duplicate primary key
Cant submit more then one form in database from Angular because of duplicate primary key

Time:03-14

So im building and application with Angular and WebAPI (Swagger) and i can only submit once (so when i try to submit it first time everything goes okay) my form into database otherwise i need to change my Id key in model class(class TimelyTable) by hand or it shows error 500 (that Primary Key is duplicate) so im guessing the problem should be in my WebApi Controller. Im gussing I should have some function that increments my Id or something like that?

This is my model class in Angular:

    export class TimelyTable {
    id:number = 1;
    projectName:string = '';
    startTime:Date = new Date();
    stopTime:Date = new Date();
    duration:number = 0;
}

This is my form in html:

 <form  style="text-align: center;" #form="ngForm" (submit)="onButtonClick(form)">
        <input type="hidden" ngModel name="id" [value]="service.formData.id">
        <div  style="margin-top: 70px;">
            <label style="margin: 10px;">Project Name</label>
            <input  placeholder="Project Name"
            ngModel name="projectName" #projectName="ngModel" [(ngModel)]="service.formData.projectName">
            <div>
                <label style="margin: 22px;">Start Time</label>
                <input  placeholder="Start Time"
                ngModel name="startTime" #startTime="ngModel" [(ngModel)]="service.formData.startTime">
            </div>
    <div>
        <label style="margin: 22px;">Stop Time</label>
        <input  placeholder="Stop time"
        ngModel name="stopTime" #stopTime="ngModel" [(ngModel)]="service.formData.stopTime">
    </div>
    <div>
        <label style="margin: 28px;">Duration</label>
        <input  placeholder="duration"
        ngModel name="duration" #stopTime="ngModel" [(ngModel)]="service.formData.duration">
    </div>
        </div>
        <div >
            <button   type="submit" style="margin-top: 40px; margin-right: 120px;">Start Time</button>
            <button   style="margin-top: 40px;">Stop Time</button>
        </div>
    </form>

This is my component file:

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { distinctUntilChanged } from 'rxjs';
import { TimelyTable } from 'src/app/shared/timely-table.model';
import { TimelyTableService } from 'src/app/shared/timely-table.service';

@Component({
  selector: 'app-table-form',
  templateUrl: './table-form.component.html'
})
export class TableFormComponent implements OnInit {

  constructor(public service:TimelyTableService){
  }
  formData = new TimelyTable();

  ngOnInit(): void {
  };


  onButtonClick(form:NgForm){
      this.service.postForm().subscribe(
        (result) => {
          console.log(result);
          this.resetform(form);
        }
        
      );
    }
  resetform(form:NgForm){
      form.form.reset();
      this.service.formData = new TimelyTable();
  }

}

And this is my service file:

import { Injectable } from '@angular/core';
import { TimelyTable } from './timely-table.model';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/internal/Observable';
import { catchError } from 'rxjs/internal/operators/catchError';
import { environment } from 'src/environments/environment';


@Injectable({
  providedIn: 'root'
})
export class TimelyTableService {
  httpOptions = {
    headers : ({'Content-Type': 'application/json'})
    }

  readonly APIUrl = environment.apiHost
  constructor(private http:HttpClient) { }

  formData:TimelyTable = new TimelyTable();

  postForm(){
   return this.http.post(`${this.APIUrl}`,this.formData);
  }
}

And my WebApi Controller:

public async Task<ActionResult<Time>> PostTime(Time time)
{
  _context.Times.Add(time);
  _context.Database.OpenConnection();
  try
  {
    _context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Times ON;");
    await _context.SaveChangesAsync();
    _context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Times OFF;");
  }
  finally
  {
    _context.Database.CloseConnection();
  }
  return CreatedAtAction("GetTime", new { id = time.Id }, time);
}

CodePudding user response:

If you are allowing the database to set the primary key, you should pass NULL for this value on all inserts (SET IDENTITY_INSERT).

Change the id value:

id:number | unknown;

You can also remove the hidden field:

<input type="hidden" ngModel name="id" [value]="service.formData.id">

This will need to be modified if you want your form to support edits (UPDATE/PUTs) but that is the idea for INSERT (POST). You are defaulting the value to 1, hence a duplicate primary key.

CodePudding user response:

I made such a careless mistake. My GetTime() method was commented out in my WebApi Controller and that was the problem.

  • Related