Input Field showing fetched data but not allowed to input anything - javascript

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

Related

Update Specific Component rather than whole page

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

Pass input text value to function per click

I want to insert the value inserted into an input in the database using Angular as the frontend and php as the backend but I'm not able to insert the input value into the method along with the user.id.
The input is for the reason of moderation when clicking on disapprove it is necessary to pass the reason but it is not entering.
import { Component, OnInit, TemplateRef } from '#angular/core';
import { FormGroup } from '#angular/forms';
import { observerMixin } from '#rodrigowba/observer-component';
import { ResponseData, DefaultResponse } from '#rodrigowba/http-common';
import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
import { ToastrService } from 'ngx-toastr';
import { Observable } from 'rxjs';
import { ActionPayload } from '~/ngrx';
import {
HotsiteUser,
HotsiteUsersFacade,
HotsiteUsersFormService,
RegistrationStatusTypes,
UpdateHotsiteUserRequest,
HotsitePointsPrebase,
} from '~/admin/users';
import {
updateHotsiteUser,
hotsiteUserUpdated,
hotsiteUserUpdateFailed,
hotsiteUserRegistrationModerated,
hotsiteUserModerateRegistrationFailed
} from '~/admin/users/state';
import { distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';
#Component({
templateUrl: './view.component.html',
})
export class ViewComponent extends observerMixin() implements OnInit {
user$: Observable<HotsiteUser>;
pointsPrebase$: Observable<HotsitePointsPrebase[]>;
customFields$: Observable<{
field: string,
value: string
}[]>;
registrationStatusTypes = RegistrationStatusTypes;
form: FormGroup;
modalRef: BsModalRef;
submiting = false;
constructor(
private hotsiteUsersFacade: HotsiteUsersFacade,
private hotsiteUsersFormService: HotsiteUsersFormService,
private modalService: BsModalService,
private toastr: ToastrService
) {
super();
this.form = this.hotsiteUsersFormService.updateForm();
}
ngOnInit() {
this.user$ = this.hotsiteUsersFacade.selectCurrentHotsiteUser();
this.customFields$ = this.user$.pipe(
map(user => Object.values(user.custom_fields)),
map(customFields => customFields.map(customField => {
let value = customField.value;
if (Array.isArray(value)) {
value = value.join(', ');
}
return {
field: customField.field,
value
};
}))
);
this.pointsPrebase$ = this.user$.pipe(
map(user => user.id),
distinctUntilChanged(),
tap(id => {
this.hotsiteUsersFacade.fetchHotsitePointsPrebase(id);
}),
switchMap(id => this.hotsiteUsersFacade.selectHotsitePointsPrebaseByHotsiteUser(id))
);
this.observe(this.user$).subscribe(user => {
this.form.patchValue(user);
});
this.observe(
this.hotsiteUsersFacade.ofType(updateHotsiteUser)
).subscribe(() => {
this.submiting = true;
});
this.observe(
this.hotsiteUsersFacade.ofType<ActionPayload<ResponseData<HotsiteUser>>>(
hotsiteUserUpdated,
hotsiteUserRegistrationModerated
)
).subscribe(action => {
const { message, data } = action.payload;
this.submiting = false;
this.toastr.success(message);
});
this.observe(
this.hotsiteUsersFacade.ofType<ActionPayload<DefaultResponse>>(
hotsiteUserUpdateFailed,
hotsiteUserModerateRegistrationFailed
)
).subscribe(action => {
const { message } = action.payload;
this.submiting = false;
this.toastr.error(message);
});
}
onSubmit(id: string, data: UpdateHotsiteUserRequest) {
this.hotsiteUsersFacade.updateHotsiteUser(id, data);
}
openModal(template: TemplateRef<any>, size = 'modal-md') {
this.modalRef = this.modalService.show(template, { class: size });
}
approveRegistration(id: string,reason: string) {
this.hotsiteUsersFacade.moderateRegistrationHotsiteUser(id, { approved: true,reason });
}
rejectRegistration(id: string,reason: string) {
this.hotsiteUsersFacade.moderateRegistrationHotsiteUser(id, { approved: false,reason });
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<form [formGroup]="form" (ngSubmit)="onSubmit(user.id, form.value)" >
<form [formGroup]="form" (ngSubmit)="onSubmit(user.id, form.value)" >
<div class="row mb-3">
<div class="col-12">
<div class="form-group">
<label>Name</label>
<input type="text" [value]="user.name" class="form-control" readonly />
</div>
</div>
<div class="col-12 col-lg-6">
<div class="form-group">
<label>E-mail</label>
<input type="text" [value]="user.email" class="form-control" readonly />
</div>
</div>
<div class="col-12 col-lg-6">
<div class="form-group">
<label>Document</label>
<input type="text" [value]="user.document" class="form-control" readonly />
</div>
</div>
<div class="col-12" *ngFor="let customField of customFields$ | async">
<div class="form-group">
<label>{{ customField.field }}</label>
<input type="text" [value]="customField.value" class="form-control" readonly />
</div>
</div>
<div class="col-auto">
<div class="form-group">
<mat-slide-toggle formControlName="admin" color="primary" ></mat-slide-toggle>
<label class="ml-2">Admin</label>
</div>
</div>
<div class="col-auto">
<div class="form-group">
<mat-slide-toggle formControlName="active" color="primary" ></mat-slide-toggle>
<label class="ml-2">Active</label>
</div>
</div>
</div>
<ng-container *ngIf="pointsPrebase$ | async as pointsPrebase">
<div class="row mb-3" *ngIf="pointsPrebase.length > 0">
<div class="col-12">
<h4 class="font-16 font-weight-bold">Points</h4>
</div>
<div class="col-12 col-lg-6">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>Chave</th>
<th class="text-center">Points</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let points of pointsPrebase">
<td>{{ points.value }}</td>
<td class="text-center">{{ points.points }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</ng-container>
<div class="form-row">
<ng-container *ngIf="user.registration_status === registrationStatusTypes.AwaitingModeration">
<div class="col-auto">
<label>Reason</label>
<input type="text" name="reason" placeholder="Reason of moderation..." class="form-control"/>
</div>
<div class="col-auto">
<button
type="button"
class="btn btn-success"
(click)="approveRegistration(user.id,form.reason)"
>
<app-loading-label [loading]="submiting">Approved </app-loading-label>
</button>
</div>
<div class="col-auto">
<button
type="button"
class="btn btn-danger"
(click)="rejectRegistration(user.id,form.reason)"
>
<app-loading-label [loading]="submiting">Repproved </app-loading-label>
</button>
</div>
</ng-container>
<div class="col text-right">
<button
type="submit"
class="btn btn-orange"
[disabled]="form.invalid || submiting"
>
<app-loading-label [loading]="submiting">Salvar</app-loading-label>
</button>
</div>
</div>
</form>
Error:
Property 'reason' does not exist on type 'formGroup'
As user776686 suggested, there is a formControlName missing linked to "reason" field.
To get the field value in HTML you should access to the FormGroup controls:
(click)="approveRegistration(user.id, form.controls.reason.value)"
Also you can create a "get" property in TS code and then access to it in HTML:
get reason() {
return this.form.controls.reason.value;
}
(click)="approveRegistration(user.id, reason)"
BTW, a field can be accessed too through the "get" method of a FormGroup:
get reason() {
return this.form.get('reason').value;
}
It expects a control with the attribute formControlName="reason" which is not present here:
<input type="text" name="reason" placeholder="Reason of moderation..." class="form-control"/>
This might be a reason.
If that doesn't help, you my also want to look into the *ngIf condition here:
<ng-container *ngIf="user.registration_status === registrationStatusTypes.AwaitingModeration">

How can I add a date to an object in Angular?

am sending an put request based on these files.
Venue.ts file
export class Venue {
id: number;
venueName: string;
cityName: string;
emailContact: string;
fighter1: string;
fighter2: string;
dateOfFight: Date;
active: boolean;
}
My Angular Component files:
create-venue.component.html
<h3>Create Event</h3>
<div [hidden]="submitted" style="width: 400px;">
<form (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="name">Venue Name</label>
<input type="text" class="form-control" id="venueName" required [(ngModel)]="venue.venueName" name="venueName">
</div>
<div class="form-group">
<label for="name">City Name</label>
<input type="text" class="form-control" id="cityName" required [(ngModel)]="venue.cityName" name="cityName">
</div>
<div class="form-group">
<label for="name">Email Contact</label>
<input type="text" class="form-control" id="emailContact" required [(ngModel)]="venue.emailContact" name="emailContact">
</div>
<div class="form-group">
<label for="name">Fighter 1 Contact</label>
<input type="text" class="form-control" id="fighter1" required [(ngModel)]="venue.fighter1" name="fighter1">
</div>
<div class="form-group">
<label for="name">Fighter 2 Contact</label>
<input type="text" class="form-control" id="fighter2" required [(ngModel)]="venue.fighter2" name="fighter2">
</div>
<div class="form-group">
<label for="name">Choose a time for your Event:</label>
<input type="datetime-local" class="form-control" id="dateOfFight" min="2021-01-01T00:00" max="2023-06-14T00:00" required [(ngModel)]="venue.dateOfFight" name="dateOfFight">
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>
<div [hidden]="!submitted">
<h4>You submitted successfully!</h4>
<!-- <button class="btn btn-success" (click)="newVenue()">Add</button> -->
</div>
create-venue.component.ts
import { VenueService } from '../venue.service';
import { Venue} from '../venue';
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-create-venue',
templateUrl: './create-venue.component.html',
styleUrls: ['./create-venue.component.css']
})
export class CreateVenueComponent implements OnInit {
venue: Venue = new Venue();
submitted = false;
constructor(private venueService: VenueService,
private router: Router) {}
ngOnInit() {
}
newVenue(): void {
this.submitted = false;
this.venue = new Venue();
}
save() {
this.venueService.createVenue(this.venue)
.subscribe(data => console.log(data), error => console.log(error));
this.venue = new Venue();
this.gotoList();
}
onSubmit() {
this.submitted = true;
this.save();
}
gotoList() {
this.router.navigate(['/venues']);
}
}
My current sent data in chrome:
I am quite new to javascript and angular, maybe this was answered before but I have no idea how to get the input data into the Venue object...
Edit:
This is my header tab:
I
using a string instead of Date type for the dateOfFight property will let you post to the backend without issue.
You can then generate the date with new Date(datestring) on your server if needed. On the front end you can look into date pipes which will help you format the string accordingly.
You also seem to not be capturing any values in your date input. Notice venue.dateOfFight is not even there. Perhaps try logging out your data before posting
You can use a string instead of date type dateOfFight: string;, and before saving, trasform it into a date format with Moment js.
moment(Date.now()).format('YYYY-MM-DD').toString()

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>

Passing Data from FORM to another component in Angular 2

1.After the data being entered , onClick of the submit button in nav.template.html.
2.FORM data should be passed into product.component.ts, Also the same data should be inserted inside the table in product.template.html.
3.In interface data types are being defined and passed through a service called product.data.js.
nav.component.ts
import { Component } from '#angular/core';
import { Router } from '#angular/router';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
#Component({
moduleId: module.id,
selector: 'ng-nav',
inputs: ['products'],
templateUrl: 'nav.template.html'
})
export class NavbarComponent {
productForm: boolean=false;
isNewForm: boolean;
rForm : FormGroup;
post : any;
fname : string = '';
lname : string = '';
email : string = '';
phnum : number;
address : string = '';
ZipCode : number;
state : string = '';
country : string = '';
fnameAlert : string = 'Maximum 10 characters';
lnameAlert : string = 'Maximum 10 characters';
emailAlert : string = 'Maximum 50 characters in e-mail format';
phnumAlert : string = 'Maximum 10 digits';
addressAlert : string = 'Maximum 100 characters';
ZipCodeAlert : string = 'Maximum 10 characters';
constructor(private fb:FormBuilder){
this.rForm = fb.group({
'fname':[null,Validators.compose([Validators.required,Validators.maxLength(10),Validators.minLength(3)])],
'lname':[null,Validators.compose([Validators.required,Validators.maxLength(10),Validators.minLength(3)])],
'email':[null,Validators.compose([Validators.required,Validators.maxLength(50)])],
'phnum':[null,Validators.compose([Validators.required,Validators.maxLength(10)])],
'address':[null,Validators.compose([Validators.required,Validators.maxLength(10)])],
'ZipCode':[null,Validators.compose([Validators.required,Validators.maxLength(6)])],
'state':[null,Validators.required],
'country':[null,Validators.required],
'validate' : ''
});
}
addpost(post){
this.fname = post.fname;
this.lname = post.lname;
this.email = post.email;
this.phnum = post.phnum;
this.address = post.address;
this.ZipCode = post.ZipCode;
}
// saveProduct(product: Product){
// }
}
nav.template.html
<button (click)="showAddProductForm()"><i class="fa fa-plus add-plus-button"></i></button>
<div class="container">
<form [formGroup]="rForm" (ngSubmit)="addPost(rForm.value)" *ngIf="productForm">
<div class="form-container">
<div class="form-style-1">
<h2>Customer Details</h2>
<label>First Name<span class="required">*</span><input class="fname-holder" [(ngModel)]="newProduct.fname" type="text" formControlName="fname"/></label>
<div class="alert" *ngIf="!rForm.controls['fname'].valid && rForm.controls['fname'].touched">{{fnameAlert}}</div>
<label>Last Name<span class="required">*</span><input class="lname-holder" [(ngModel)]="newProduct.lname" type="text" formControlName="lname"/></label>
<div class="alert" *ngIf="!rForm.controls['lname'].valid && rForm.controls['lname'].touched">{{lnameAlert}}</div>
<label>Email <span class="required">*</span><input type="email" [(ngModel)]="newProduct.email" formControlName="email"/></label>
<div class="alert" *ngIf="!rForm.controls['email'].valid && rForm.controls['email'].touched">{{emailAlert}}</div>
<label>Phone <span class="required">*</span><input type="text" [(ngModel)]="newProduct.phnum" formControlName="phnum"/></label>
<div class="alert" *ngIf="!rForm.controls['phnum'].valid && rForm.controls['phnum'].touched">{{phnumAlert}}</div>
<label>Address <span class="required">*</span><textarea style="width: 319px;"type="address" [(ngModel)]="newProduct.id" formControlName="address"></textarea></label>
<div class="alert" *ngIf="!rForm.controls['address'].valid && rForm.controls['address'].touched">{{addressAlert}}</div>
<label>Zip Code <span class="required">*</span><input type="text" [(ngModel)]="newProduct.ZipCode" formControlName="ZipCode"/></label>
<div class="alert" *ngIf="!rForm.controls['ZipCode'].valid && rForm.controls['ZipCode'].touched">{{ZipCodeAlert}}</div>
<label>State <span class="required">*</span><input type="text" [(ngModel)]="newProduct.state" formControlName="state"/></label>
<label>Country <span class="required">*</span><input type="text" [(ngModel)]="newProduct.country" formControlName="country"/></label>
<input type="submit" style="width: 95px;" class="button button2" value="Submit" (click)="saveProduct(newProduct)" [disabled]="!rForm.valid"/>
</div>
</div>
</form>
</div>
product.component.ts
import { Component, OnInit } from '#angular/core';
import { Product} from './product';
import { ProductService } from './product.service';
#Component({
moduleId: module.id,
selector: 'ng-product',
templateUrl: 'product.template.html'
})
export class ProductComponent implements OnInit{
products:Product[];
productForm:boolean = false;
isNewForm:boolean;
constructor (private _productService:ProductService){}
ngOnInit(){
this.getProducts();
}
getProducts(){
this.products = this._productService.getProductsFromData();
}
removeProductForm(product: Product){
this._productService.deleteProduct(product);
}
}
product.template.html
<div>
<div>
<div style="float: right;"><input class="filter-search" placeholder="Search..." type="text" [(ngModel)]="term">
<i class="fa fa-search search-bar-icon"></i>
</div>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Phone</th>
<th>Address</th>
<th>Zipcode</th>
<th>State</th>
<th>Country</th>
<th></th>
<th></th>
</tr>
<tr *ngFor="let product of products|filter:term">
<td>{{product.fname}}</td>
<td>{{product.lname}}</td>
<td>{{product.email}}</td>
<td>{{product.phnum}}</td>
<td>{{product.address}}</td>
<td>{{product.ZipCode}}</td>
<td>{{product.state}}</td>
<td>{{product.country}}</td>
<td><i class="fa fa-edit" style="font-size:24px;color: #3eb0f7;" (click)="showEditProductForm(product)"></i></td>
<td><i class="fa fa-trash" style="font-size:24px;color: #ff3232;" (click)="removeProductForm(product)"></i></td>
</tr>
</table>
</div>
</div>
<ng-nav [products]="products"></ng-nav>
product.service.ts
import{Injectable} from '#angular/core';
import{Product} from './product';
import{PRODUCT_ITEMS} from './product.data';
#Injectable()
export class ProductService {
private pItems = PRODUCT_ITEMS;
getProductsFromData():Product[]{
console.log(this.pItems);
return this.pItems
}
deleteProduct(product: Product){
this.pItems.splice(this.pItems.indexOf(product),1)
}
}
You can use Subject or BehaviourSubject from rxjs. Pass the submitted data to next method of Observable and subscribe it to another component and you will get the data there.
Your newProduct should exists in product.component.ts. By the magic of two way data binding you have the data in the component.
To send it to the service..
export class ProductComponent implements OnInit{
products:Product[];
newProduct: Product;
constructor (private _productService:ProductService){}
ngOnInit(){
this.getProducts();
}
onSubmit(){
this._productService.addProduct(this.newProduct);
}

Categories