Update Specific Component rather than whole page - javascript

I am currently making a small application where users can add contacts to a list. i am able to add the contacts to a list and it shows up in a separate div. at the moment when i click save, i have some code which basically has await and the whole app refreshes. the problem i am currently having is when i insert data for a user and click save it refreshes the whole screen but instead when i click save i want it to only refresh the contact component.
I currently have a piece of code which essentially refreshes all the components which is okay but now i want to try and just refresh the component i have added data too.
i have included the code below:
`
<div class="container">
<div class="main-contact-list">
<h2>Contacts</h2>
<li *ngFor="let contact of contacts;">
<button type="button" (click)="getContact(contact.id)">
<span class="name"> {{contact.firstName}} {{contact.lastName}}</span>
</button>
</li>
</div>
<div class="form">
<form [formGroup]="fg">
<div class="actionBtns">
<button class="btn btn-primary" (click)="saveContact()">Edit/Save</button>
<div class="divider"></div>
<button class="btn btn-primary" (click)="deleteContact(contact.id)">Delete</button>
</div>
<div class="row" class="row-object">
<input type="text" class="form-control" [(ngModel)]="contact.firstName" name="firstName"
formControlName="firstName" placeholder="First Name" />
<div class="divider"></div>
<input type="text" class="form-control" [(ngModel)]="contact.lastName" name="lastName"
formControlName="lastName" placeholder="Last Name" />
<div class="col">
<input type="text" class="form-control" [(ngModel)]="contact.emailAddress" name="emailAddress"
formControlName="emailAddress" placeholder="Email Address" />
<div class="divider"></div>
<input type="text" class="form-control" [(ngModel)]="contact.address1" name="address1"
formControlName="address1" placeholder="Address1" />
<div class="divider"></div>
<input type="text" class="form-control" [(ngModel)]="contact.address2" name="address2"
formControlName="address2" placeholder="Address2" />
<div class="divider"></div>
<input type="text" class="form-control" [(ngModel)]="contact.city" name="city"
formControlName="city" placeholder="City" />
<div class="divider"></div>
<input type="text" class="form-control" [(ngModel)]="contact.postCode" name="postCode"
formControlName="postCode" placeholder="Post Code" />
<div class="divider"></div>
</div>
</div>
</form>
<div class="activityForm" *ngIf="contact.id">
<app-activities [childItem]="contact"></app-activities>
</div>
</div>
`
`
import { Component, OnInit } from '#angular/core';
import {
FormBuilder,
FormControl,
FormGroup,
Validators,
FormsModule
} from '#angular/forms';
import { AppService } from '../app.service';
//interface for Contact
interface Contact {
id?: number;
firstName: string;
lastName: string;
emailAddress: string;
address1: string;
address2: string;
city: string;
postCode: string;
}
#Component({
selector: 'app-contact-details',
templateUrl: './contact-details.component.html',
styleUrls: ['./contact-details.component.css'],
})
export class ContactDetailsComponent implements OnInit {
constructor(private appService: AppService, private fb: FormBuilder) { }
fg!: FormGroup;
contacts: Contact[] = [];
contact: any = {};
//get the form field as a form control. it will useful for validation and etc
get firstNameField(): FormControl {
return this.fg.get('firstName') as FormControl;
}
get lastNameField(): FormControl {
return this.fg.get('lastName') as FormControl;
}
get emailAddressField(): FormControl {
return this.fg.get('emailAddress') as FormControl;
}
get address1Field(): FormControl {
return this.fg.get('address1') as FormControl;
}
get address2Field(): FormControl {
return this.fg.get('address2') as FormControl;
}
get postCodeField(): FormControl {
return this.fg.get('postCode') as FormControl;
}
async ngOnInit() {
this.initForm();
this.getContacts();
}
//form init. here we create the reactive form. https://angular.io/guide/reactive-forms
initForm(): void {
let id = Date.now() * Math.random();
this.fg = this.fb.group({
id: [id],
firstName: ['', [Validators.required]],
lastName: ['', [Validators.required]],
emailAddress: ['', [Validators.required, Validators.email]],
address1: ['', [Validators.required]],
address2: ['', [Validators.required]],
city: ['', [Validators.required]],
postCode: ['', [Validators.required]],
});
}
//save function
async saveContact() {
console.log(this.fg);
console.log(this.contact);
//if form doesn't have any validation error this if condition will executed
if (this.fg.valid) {
const newContact: Contact = {
firstName: this.fg.value.firstName,
lastName: this.fg.value.lastName,
emailAddress: this.fg.value.emailAddress,
address1: this.fg.value.address1,
address2: this.fg.value.address2,
city: this.fg.value.city,
postCode: this.fg.value.postCode,
};
if (this.contact?.id) {
this.appService
.editContacts(this.contact.id, newContact).subscribe();
} else {
this.appService
.addContacts(newContact).subscribe();
}
this.fg.reset(); //resetting the form array
await this.refresh();
} else {
console.log('this is invalid ');
}
}
refresh(): void {
window.location.reload();
}
async getContacts(): Promise<void> {
await this.appService
.getContacts()
.subscribe((contacts: any) => (this.contacts = contacts));
}
edit(id: number): void {
const data = this.contacts[id];
this.fg.patchValue(data);
this.refresh();
}
getContact(id: number | undefined) {
this.appService
.get(id)
.subscribe((contact: any) => (this.contact = contact));
}
selectContact(contact: Contact) {
this.contact = contact;
}
deleteContact(id: number | undefined) {
this.appService.deleteContact(id).subscribe();
this.refresh();
}
}
`

I did manage to figure this problem out. Most tutorials were stating that you basically use the router route so when something happens to refresh the route and it should show the new page.
Instead I just added #Input in front of my array and object, so when in my main HTML page I am using the *ngFor statement to iterate through the array, every time it is updated it automatically shows the new list

Related

Problems with custom form validator in angular

I create custom form validator for checking equality of password, I mean it checks if the passwords are matching. I can't get a real true or false in my html(variable=signupForm.valid ). Maybe I need to pass on different way controlValuesAreEqual in my form, or there is problem with imports all these forms and validators?
Ts file:
import { HttpClient } from '#angular/common/http';
import { Component, OnInit } from '#angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ValidatorFn, AbstractControl, ValidationErrors, FormGroup } from '#angular/forms';
import { Router } from '#angular/router';
#Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.scss'],
})
export class SignupComponent implements OnInit {
public signupForm!: UntypedFormGroup;
constructor(
private formBuilder: UntypedFormBuilder,
private http: HttpClient,
private router: Router
) {}
ngOnInit(): void {
this.signupForm = this.formBuilder.group({
email: ['', Validators.required],
name: ['', Validators.required],
password: ['', Validators.required],
confirmPassword: ['',Validators.required],
validators: this.controlValuesAreEqual('password', 'confirmPassword')
});
}
private controlValuesAreEqual(controlNameA: string, controlNameB: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const formGroup = control as FormGroup
const valueOfControlA = formGroup.get(controlNameA)?.value
const valueOfControlB = formGroup.get(controlNameB)?.value
if (valueOfControlA === valueOfControlB) {
return null
} else {
return { valuesDoNotMatch: true }
}
}
}
signUp() {
this.http
.post<any>('http://localhost:3000/signupUsers', this.signupForm.value)
.subscribe({
next: (res) => {
this.signupForm.reset(), this.router.navigate(['login']);
},
error: (e) => alert('Something went wrong'),
});
}
}
And HTML is here
<div class="container mt-5">
<div class="card" style="padding: 20px">
<h2 class="text-center">Please Sign Up!</h2>
<form [formGroup]="signupForm" (ngSubmit)="signUp()">
<mat-form-field appearance="outline" class="w-100">
<mat-label>Email</mat-label>
<input formControlName="email" matInput placeholder="E-Mail" />
<mat-hint>Hint</mat-hint>
</mat-form-field>
<mat-form-field appearance="outline" class="w-100">
<mat-label>Name</mat-label>
<input formControlName="name" matInput placeholder="name" />
<mat-hint>Hint</mat-hint>
</mat-form-field>
<mat-form-field appearance="outline" class="w-100">
<mat-label>Password</mat-label>
<input
type="password"
formControlName="password"
matInput
placeholder="password"
/>
<mat-hint>Hint</mat-hint>
</mat-form-field>
<mat-form-field appearance="outline" class="w-100">
<mat-label>Confirm Password</mat-label>
<input
type="password"
formControlName="confirmPassword"
matInput
placeholder="password"
/>
<mat-hint align="start">
<strong>{{ signupForm.valid }}</strong>
</mat-hint>
</mat-form-field>
<button type="submit" mat-raised-button color="primary" class="w-100">
Sign Up
</button>
</form>
<a style="text-decoration: none; margin-top: 10px" routerLink="/login"
>Already registered? Click to Login</a
>
</div>
</div>
Include this method in your component so that password and confirmed password mismatch error can be emitted to your template.
get passwordMatchError() {
return (
this.signupForm.getError('valuesDoNotMatch') &&
this.signupForm.get('confirmPassword')?.touched
);
}
Place the following code under confirm password mat-form-field section so that the mismatch error can be shown.
<mat-error *ngIf="passwordMatchError">Password and confirmed password do not match.</mat-error>

Input Field showing fetched data but not allowed to input anything

I am trying for 3 day and looking for a solution in to fix this problem but I am not success. I have read a problem with the same title but it did not help me in solving because it is different from my problem.
I hope that someone can help me .
Problem Description :
I have a Modal which send from one component to another component , this Modal should allow the user to Update the Student Information after calling the Method onUpdate() .
so I have Component A and Child A and the exchange some Data by using service file .
Component A has the Method onUpdate (userData) --> send to service --> Child A
javaScriptCode for Component A
onUpdate(userId: number, index: number) {
this.isOnDeleteORUpdate = true;
**// here the data will be fetched from DB and send to the Service,
// so that can be shown in Modal Form**
if (this.isOnDeleteORUpdate) {
this.requestService.getUserWithId(userId).subscribe((userData) => {
this.theModalServiceUpdate.setUser(userData);
this.theModalServiceUpdate.setUser(userData);
if (userData.courses.length <= 0 || userData.courses == null) {
this.loadedCourses = [];
this.theModalService.setCourses([]);
} else {
this.loadedCourses = userData.courses;
this.theModalService.setCourses(userData.courses);
}
});
this.modalService
.open(this.theModalServiceUpdate.modalTemplate, { centered: true })
.result.then(
(res) => {
this.closeModal = `Closed with: ${res}`;
},
(res) => {
this.closeModal = `Dismissed ${this.getDismissReason(res)}`;
}
);
}
}
Modal HTML Code:
<ng-template #modalData let-modal>
<div class="modal-dialog-scrollable modal-dialog-centered" id="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-basic-title">Modal title</h5>
<button
type="button"
class="btn-close"
data-dismiss="modal"
aria-label="Close"
(click)="modal.dismiss('Cross click')"
></button>
</div>
<div class="modal-body">
<form [formGroup]="userForm">
<label for="firstName">First Name</label>
<input
type="text"
class="form-control"
name="firstName"
formControlName="firstName"
/>
<label for="lastName">Last Name</label>
<input
type="text"
class="form-control"
name="lastName"
formControlName="lastName"
/>
<label for="email">Email</label>
<input
type="email"
class="form-control"
name="email"
formControlName="email"
/>
<label for="address">Address</label>
<input
type="text"
class="form-control"
name="address"
formControlName="address"
/>
<label for="telNumber">Telfone no.</label>
<input
type="text"
class="form-control"
name="telNumber"
formControlName="telNumber"
/>
<label for="gebDatum">gebDatum</label>
<input
type="text"
class="form-control"
name="gebDatum"
formControlName="gebDatum"
/>
</form>
<div class="card-body">
<div
style="
border-radius: 6px;
overflow: hidden;
border: 0.05em solid rgb(218, 231, 198);
"
>
<table class="table table-hover table-responsive">
<thead style="background-color: gray; text-align: center">
<tr>
<th scope="col">Id</th>
<th scope="col">Course Name</th>
<th scope="col">Serial Number</th>
</tr>
</thead>
<tbody>
<tr
*ngFor="let course of loadedCourses"
style="text-align: center"
>
<td>{{ course.id }}</td>
<td>
<input type="text" [value]="course.name" />
</td>
<td>
<input type="text" [value]="course.serialNumber" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal-footer">
<button (click)="saveData()" type="button" class="btn btn-danger">
Close
</button>
</div>
</div>
</div>
</ng-template>
its work for me fine and the Student Data are fetched from DataBase in the Input fields .
but I can't inter Any Information , the Input Field is frozen only I can inter the Courses Information because I user the [value] data binding in HTML instead of ngForm.
see photo: as you can see the Modal divided in tow section , in the upper one I get the data from DB but I can't modify it. in the Table Section because I am using the data binding and not the ngForm so I can enter information .
The code in JavaScript look like the following :
import { Component, OnInit, TemplateRef, ViewChild } from '#angular/core';
import { FormControl, FormGroup, Validators } from '#angular/forms';
import { courses } from 'src/app/userInfo/courses.module';
import { userInfo } from 'src/app/userInfo/user.module';
import { modalServiceUpdate } from '../../modal.updateUser.service';
#Component({
selector: 'app-modal-update-student',
templateUrl: './modal-update-student.component.html',
styleUrls: ['./modal-update-student.component.css'],
})
export class ModalUpdateStudentComponent implements OnInit {
#ViewChild('modalData') templateRef: TemplateRef<any>;
userForm: FormGroup;
loadedUser: userInfo;
lodedUserId: number = 0;
loadedCourses: courses[] = [
{
id: 0,
name: 'undefine',
serialNumber: 0,
},
];
user: userInfo = {
id: 0,
firstName: 'undefined',
lastName: 'undefined',
email: '',
gebDatum: 0,
telNumber: 0,
address: '',
courses: [],
};
constructor(private modalServiceUpdate: modalServiceUpdate) {}
loadedUserFromService: userInfo;
ngOnInit(): void {}
ngDoCheck(): void {
this.initForm();
}
private initForm() {
this.modalServiceUpdate.modalTemplate = this.templateRef;
let firstName = '';
let lastName = '';
let email = '';
let address = '';
let telNumber = 0;
let gebDatum = '0';
const user = this.modalServiceUpdate.getUser();
this.loadedCourses = this.modalServiceUpdate.getUser().courses;
firstName = user.firstName;
lastName = user.lastName;
email = user.email;
address = user.address;
telNumber = user.telNumber;
gebDatum = '0';
this.userForm = new FormGroup({
firstName: new FormControl(firstName, Validators.required),
lastName: new FormControl(lastName, Validators.required),
email: new FormControl(email, Validators.required),
address: new FormControl(address, Validators.required),
telNumber: new FormControl(telNumber, Validators.required),
gebDatum: new FormControl(gebDatum, Validators.required),
});
}
saveData() {}
}
the second issue , if I don't use the ngDoCheck() , the data that comes from other Component(Component A) will not be fired before the onUpdate() is called. so with ngOnInit() I will get undefined or empty userData .
is there alternative that can I use , to inform Angular about any changes happen on the userData that saved in Service.ts ?
I hope that some one can help me .
Thank you

Angular json value not displayed in textbox

Im new to Angular and I can't figure out whats going on here.
I have a MVC Controller which gives me the correct value such as {PostalContactPerson : jeff}
however my Angualar view does not recognise the value on page load in the input box.
How can i get the value into the textbox please? Im perplexed why it's 'blank' when the other values are displayed from the same Form Group.
Form.component.ts
export class FormComponent implements OnInit {
data: any = null;
this.arService.get(id, true)
.subscribe(data => {
this.loading = false;
this.ar = data;
this.attachments = this.ar.attachments.filter(e => e.type == Enums.AttachmentType.Normal);
**this.data = this.ensureData(data.formData);
this.ar.formData = this.data;**
this.stationInformationForm = formBuilder.group({
"businessNumbersGroup": formBuilder.group({
"acn": [this.data.acn],
"icn": [this.data.icn],
"postalcontactperson": [this.data.postaladdress],
}, ),
});
}
ensureData(data: any): any {
if (data == null) {
data = {};
}
if (!data["postalcontactperson"]) {
data["postalcontactperson"] = { state: "" };
}
form.component.html
<div [formGroup]="stationInformationForm.controls['businessNumbersGroup']">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label>ACN</label>
<div class="form-description">Specify if applicable</div>
<input type="text" [ngClass]="{'has-error': !stationInformationForm.controls['businessNumbersGroup'].valid && (stationInformationForm.controls['businessNumbersGroup'].controls['acn'].touched || workflowSections[0].submitted)}" formControlName="acn" [(ngModel)]="data.acn"
class="form-control" />
<hr/>
</div>
<div class="form-group">
<label>postalcontactperson</label>
<div class="form-description">Specify if applicable</div>
<input type="text" [ngClass]="{'has-error': !stationInformationForm.controls['businessNumbersGroup'].valid && (stationInformationForm.controls['businessNumbersGroup'].controls['PostalContactPerson'].touched || workflowSections[0].submitted)}" formControlName="PostalContactPerson"
[(ngModel)]="data.postalcontactperson" class="form-control" />
</div>
<hr/>
</div>
</div>
</div>
MVC Model
public static AnnualReturnModel Create(AnnualReturn annualReturn)
{
return new AnnualReturnModel
{
Id = annualReturn.Id,
FormData = annualReturn.FormData,
PostalContactPerson = annualReturn.FormData.PostalContactPerson,
}
}
MVC Form Data
public class AnnualReturnFormData
{
public int? ActiveSectionIndex { get; set; }
#region Station Information
public string LesseeNames { get; set; }
//Postal Address
public string PostalContactPerson { get; set; }
}
json result of above:
{"ActiveSectionIndex":0,"LesseeNames":"aaa","PostalContactPerson":"aa","PostalPosition":"aa","PostalEmail":"aa","PostalPhone":"aa","StationContactPerson":"aaa"}
debugging description here
On page load, my ACN is shown in the textbox but the PostalContactPerson is not. why?
When I put an alert on the site, the contact person does not show my value.
alert(this.data.acn); //shows me a value of 22222
alert("contact person=" + this.data.postalcontactperson); //shows undefined
Any suggestions please? what am I missing, the JSON value is shown correctly when i check the database.
Any suggestions are Much appreciated. what am i missing with the ngModel?
Ive updated the code to the below:
form.component.html
<div [formGroup]="stationInformationForm.controls['postalAddressGroup']">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label>Contact Person</label>
<input type="text" formControlName="postalcontactperson"class="form-control" value={{annualReturn.postalcontactperson}} /> <!--value={{annualReturn.postalcontactperson}}-->
</div>
<div class="form-group">
<label>Position</label>
<input type="text" formControlName="postalposition" class="form-control" />
<div class="validation-error" *ngIf="!stationInformationForm.controls['postalAddressGroup'].valid && (stationInformationForm.controls['postalAddressGroup'].get('postalposition').touched || workflowSections[0].submitted)">You must specify Position</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label>Email</label>
<input type="text" formControlName="postalemail" class="form-control" />
<div class="validation-error" *ngIf="!stationInformationForm.controls['postalAddressGroup'].valid && (stationInformationForm.controls['postalAddressGroup'].get('postalemail').touched || workflowSections[0].submitted)">You must specify email</div>
</div>
<div class="form-group">
<label>Phone</label>
<input type="text" formControlName="postalphone" class="form-control" />
<div class="validation-error" *ngIf="!stationInformationForm.controls['postalAddressGroup'].valid && (stationInformationForm.controls['postalAddressGroup'].get('postalphone').touched || workflowSections[0].submitted)">You must specify phone</div>
</div>
</div>
</div>
</div>
</div>
form.component.ts
var id = this.route.snapshot.params['param'];
if (id != null) {
this.arService.get(param, true)
.subscribe(data => {
this.loading = false;
this.annualReturn = data;
this.attachments = this.annualReturn.attachments.filter(e => e.type == Enums.AttachmentType.Normal);
this.data = this.ensureData(data.formData);
this.annualReturn.formData = this.data;
this.dateConfig.disableUntil = { year: this.annualReturn.year - 1, month: 6, day: 30 };
this.dateConfig.disableSince = { year: this.annualReturn.year, month: 7, day: 1 };
// this.testprop = this.data.postalcontactperson;
this.stationInformationForm = formBuilder.group({
"survey.region": [this.data.survey.region],
"lesseeNames": [this.data.stationName, Validators.required],
// "somethingfancy": [this.data.postalcontactperson],
"postalcontactperson": [this.data.postalcontactperson],
"postalAddressGroup": formBuilder.group({
"postalcontactperson": [this.data.postalcontactperson, Validators.required],
"postalposition": [this.data.postalposition, Validators.required],
"postalemail": [this.data.postalemail, Validators.required],
"postalphone": [this.data.postalphone, Validators.required],
}, ),
You are referring to the incorrect formControlName in the template file. It's postalcontactperson not PostalContactPerson . Observe the Capitals P...C...P.... And better not to use [(ngModel)] as you already using Reactive Forms. FYI, refer below changes
Working stackblitz
Typescript file
export class AppComponent implements OnInit {
addressForm: FormGroup;
stationInformationForm: FormGroup;
data: any = {
acn: 1,
icn: 2,
postaladdress: {
contactperson: "Michael",
address: "Some Address"
}
};
constructor(private formBuilder: FormBuilder) {}
public ngOnInit() {
this.stationInformationForm = this.formBuilder.group({
businessNumbersGroup: this.formBuilder.group({
acn: [this.data.acn, Validators.required],
icn: [this.data.icn, Validators.required],
postalcontactperson: [this.data.postaladdress.contactperson, Validators.required]
})
});
// Getting inner form group
this.addressForm = this.stationInformationForm.get(
"businessNumbersGroup"
) as FormGroup;
// Getting Form Changes instead of using `[(ngModel)]`
this.addressForm.valueChanges.subscribe(data => console.log(data));
}
}
Template file
<div [formGroup]="addressForm">
<label>ACN</label>
<div class="form-description">Specify if applicable</div>
<input type="text" [ngClass]="{'has-error': !addressForm.valid && addressForm.get('acn').touched }" formControlName="acn" class="form-control" />
<hr />
<label>postalcontactperson</label>
<div class="form-description">Specify if applicable</div>
<input type="text" [ngClass]="{'has-error': !addressForm.valid && addressForm.get('postalcontactperson').touched }" formControlName="postalcontactperson" class="form-control" />
</div>

I'm not able to make a post request using FormGroup Angular 6

I'm new to angular, I am not able to make a post request using formGroup. The body is being sent for all the fields that I have however, there is an error 400 (bad request) due to the following error: {"status":"error","errors":{"message":"A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext, however instance members are not guaranteed to be thread safe. This could also be caused by a nested query being evaluated on the client, if this is the case rewrite the query avoiding nested invocations."}}, I kind of understand what the error is about but I don't understand what's wrong with my code. thanks in advance
register.model.ts
export class User{
FirstName: string;
LastName: string;
UserName: string;
Email: string;
Password: string;
}
register.service.ts
RegisterUser(user: User){
return this.http.post('url', user);
}
register.component.html
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div class="form-group row">
<label class="col-sm-3 col-form-label">First Name:</label>
<div class="col-sm-3">
<input type="text" formControlName="FirstName" class="form-control"
placeholder="First Name" ngModel>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Last Name:</label>
<div class="col-sm-3">
<input type="text" formControlName="LastName" class="form-control"
id="LastName" placeholder="LastName" ngModel>
</div>
</div>
<div class="form-group row">
<label for="UserName" class="col-sm-3 col-form-label">Username:</label>
<div class="col-sm-3">
<input type="text" formControlName="UserName" class="form-control"
placeholder="User Name" ngModel>
</div>
</div>
<div class="form-group row">
<label for="Email" class="col-sm-3 col-form-label">Email:</label>
<div class="col-sm-3">
<input type="email" formControlName="Email" class="form-control"
placeholder="example#example.com" ngModel>
</div>
</div>
<div class="form-group row">
<label for="password" class="col-sm-3 col-form-label">Password:</label>
<div class="col-sm-3">
<input type="password" formControlName="Password" class="form-control"
placeholder="*********" ngModel>
</div>
</div>
<br>
<p class="text-center">Already have an account? <span>
<button (click)="goToSignIn();" class="unstyled-button">Sign In.</button>
</span></p>
<button type="submit" class="button button4">Sign Up</button>
</form>
register.component.ts
export class RegisterComponent implements OnInit {
user: User;
registerForm: FormGroup;
constructor(private router: Router, private userService: RegisterService, private toastr:
ToastrService, private fb: FormBuilder) { }
ngOnInit() {
this.registerForm = this.fb.group({
FirstName: ['', Validators.required],
LastName: ['', Validators.required],
UserName: ['', Validators.required],
Email: ['', Validators.required],
Password: ['', Validators.required],
})
}
onSubmit(){
return this.userService.RegisterUser(this.registerForm.value).subscribe((data:any) => {
this.toastr.success('User Registered Successfully');
}, error => {
this.toastr.error('Registeration Failed');
})
}
}
This is not a javascript error that you are having the problem with. This is an error comming from Entity Framework.
Your DBContext is being used by two threads at the same time. It could be that it is used by two threads in the same request.
Check that your DBContext is not declared static for some reason.
You need to share your api code in order for us to debug your problem.
Try like this:
registerUser(user) : Observable<any> {
return this.http.post<any>('url', JSON.stringify(user), this.httpOptions).pipe(
tap((user) => console.log(`user sent : ${JSON.stringify(user)}`)),
catchError(this.handleError)
);
};
the httpOptions are like this:
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
for catch error:
handleError(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}`;
}
window.alert(errorMessage);
return throwError(errorMessage);
}

angular2 using input to dynamically add to form model

This is to some extent a dupe of this question but hopefully less convoluted.
Is it possible to to add a completely new FormGroup via a form input where the new FormGroupName can be defined via input? If so which directives or functions would I use to achieve this?
User Case:
The user can define a new FormGroupName via input field and click to extend the form with the new FormGroup, then fill out values for that FormGroup’s FormControls.
1 User fills out an existing 'name' field as normal.
2 Types ‘foo’ into an input field
3 Clicks ‘add data group’ to create the new FormGroup 'foo'
4 The form reveals input fields for 'height' and 'weight' for the new FormGroup foo.
5 User fills out 'height' and 'weight' values for 'foo'
6 Repeats step 2-5 for 'bar'
7 Submits:
{
"name":"Data Form",
"foo":{
"height":"6.00",
"weight":"300"
},
"bar":{
"height":"5.11",
"weight":"260"
}
}
The FormControls in the added FormGroups will always be consistent.
So as in the above example always ‘weight’ and ‘height’.
The intention is to use the form as a basic UI to help generate some JSON data.
Thanks.
The solution I came up with was to use a dynamic [formGroupName] which references an array which is updated each time a new group is added
[formGroupName]="myGroupName[i]"
app.component.ts :
import { Component, OnInit } from '#angular/core';
import { Customer } from './customer.interface';
import { FormControl, FormBuilder, FormGroup, FormArray, Validators } from '#angular/forms';
#Component({
moduleId: module.id,
selector: 'my-app',
templateUrl: 'app.component.html',
})
export class AppComponent implements OnInit {
public myForm: FormGroup;
myGroupName = ['test'];
constructor(private _fb: FormBuilder) {
}
ngOnInit() {
this.myForm = this._fb.group({
myArray: this._fb.array([
this._fb.group({
test: this._fb.group({
name: ['test'],
title: [''],
link: [''],
cta: [''],
})
}),
])
});
}
initArray(nameObj:any) {
return this._fb.group({
[nameObj]: this._fb.group({
name: [nameObj],
title: [''],
link: [''],
cta: [''],
})
})
}
addArray(newName:string) {
const control = <FormArray>this.myForm.controls['myArray'];
this.myGroupName.push(newName);
control.push(this.initArray(newName));
document.getElementById('newName').value='';
}
removeDataKey(i: number) {
const control = <FormArray>this.myForm.controls['myArray'];
control.removeAt(i);
this.myGroupName.splice(i,1);
}
}
app.component.html:
<form [formGroup]="myForm" novalidate (ngSubmit)="save(myForm)">
<div formArrayName="myArray">
<div *ngFor="let myGroup of myForm.controls.myArray.controls; let i=index" class="panel panel-default">
<div [formGroupName]="i" class="panel-body">
<span *ngIf="myForm.controls.myArray.controls.length > 1"
(click)="removeDataKey(i)" class="glyphicon glyphicon-remove pull-right">
</span>
<h5 >Group {{i + 1 }}</h5>
<h3> {{myGroupName[i] }}</h3>
<!--[formGroupName]="myGroupName[i]"-->
<div [formGroupName]="myGroupName[i]" class="panel-body">
<div class="form-group">
<label>Title</label>
<input type="text" class="form-control" formControlName="title" >
</div>
<div class="form-group">
<label>Link</label>
<input type="text" class="form-control" formControlName="link" >
</div>
<div class="form-group">
<label>Cta</label>
<input type="text" class="form-control" formControlName="cta" >
</div>
</div>
<!--[formGroupName]="myGroupName[i]"-->
</div>
<!--[formGroupName]="i" -->
</div>
</div>
<!-- myArray array-->
<div class="margin-20">
<input #newName
(keyup.enter)="addName(newName.value)"
type="text" style="width:30%" id="newName">
<a (click)="addArray(newName.value)" style="cursor: default" class="btn">Add Group +</a>
</div>
</form>
The dupe of this question is also answered here with related plunks

Categories