I have two components, payment-info and confirmation. I'm trying to pass the input from payment-info into confirmation using a service (not parent/child relation). Right now the confirmation.component.html page will display the 'NA' text from the service model, but that value isn't being updated for some reason. Any help would be greatly appreciated!
Here is my payment-info.component.ts file code:
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormGroup, FormControl } from '@angular/forms';
import { PaymentInfoService } from '../services/payment-info.service';
@Component({
selector: 'app-payment-info',
templateUrl: './payment-info.component.html',
styleUrls: ['./payment-info.component.css']
})
export class PaymentInfoComponent implements OnInit {
constructor(
private formBuilder: FormBuilder,
private paymentInfoService: PaymentInfoService
) { }
paymentInfo = this.paymentInfoService.getPaymentInfo();
checkoutForm = this.formBuilder.nonNullable.group({
cardNumber: ''
})
ngOnInit(): void {
}
onSubmit(): void {
this.setData(this.checkoutForm.value.cardNumber!);
}
setData(cardNumber: string) {
this.paymentInfoService.setPaymentInfo(cardNumber);
}
}
Here is my payment-info.component.html code:
<mat-card>
<mat-card-title>Payment Details</mat-card-title>
<mat-card-content>
<form [formGroup]="checkoutForm" (ngSubmit)="onSubmit()">
<table>
<tr>
<td>
<mat-form-field >
<input matInput id="cardNumber" formControlName="cardNumber" placeholder="Card Number">
</mat-form-field>
</td>
</tr>
</table>
<button mat-raised-button color="accent" routerLink="/confirmation" type="submit" >Confirm Purchase</button>
</form>
</mat-card-content>
</mat-card>
Here is the code for confirmation.component.ts:
import { Component, OnInit } from '@angular/core';
import { PaymentInfoService } from '../services/payment-info.service';
import { Payment } from '../shared/models/Payment';
@Component({
selector: 'app-confirmation',
templateUrl: './confirmation.component.html',
styleUrls: ['./confirmation.component.css']
})
export class ConfirmationComponent {
payment! : Payment;
constructor(private paymentInfoService: PaymentInfoService) {
this.updatePaymentInfo();
}
ngOnInit(): void {
}
updatePaymentInfo(){
this.payment = this.paymentInfoService.getPaymentInfo();
}
}
Here is my code for confirmation.component.html:
<mat-card>
<mat-card-title>CONFIRMATION</mat-card-title>
<mat-card-content>
<form>
<table>
<tr>
<td>
<mat-form-field >
<p>{{payment.cardNumber}}</p>
</mat-form-field>
</td>
</tr>
</table>
<button mat-raised-button color="accent" routerLink="/" type="submit" >Return to catalog</button>
</form>
</mat-card-content>
</mat-card>
Here is my payment-info.service.ts code:
import { Injectable } from '@angular/core';
import { Payment } from '../shared/models/Payment';
@Injectable({
providedIn: 'root'
})
export class PaymentInfoService {
paymentInfo: Payment = new Payment();
setPaymentInfo(cardHolder:String, cardNumber: String, cvv: String, expirationDate: String){
this.paymentInfo.cardNumber = cardNumber;
}
getPaymentInfo() {
return this.paymentInfo;
}
}
Lastly, here is the model I'm using for storing the input (Payment.ts):
export class Payment{
cardNumber?: String = 'NA';
}
CodePudding user response:
Problem(s) & Concern(s)
Problem: The button didn't trigger the onSubmit
function.
<button mat-raised-button color="accent" routerLink="/confirmation" type="submit" >Confirm Purchase</button>
You may place a debugger that the onSubmit
function is not triggered and instead, it redirects to the confirmation page.
Concern 1: Incorrect calling setPaymentInfo
method
From the PaymentService
's setPaymentInfo
method:
setPaymentInfo(
cardHolder: String,
cardNumber: String,
cvv: String,
expirationDate: String
) {
this.paymentInfo.cardNumber = cardNumber;
}
While in PaymentInfoComponent
:
setData(cardNumber: string) {
this.paymentInfoService.setPaymentInfo(cardNumber);
}
You are incorrectly calling the method by providing parameters' values that do not match the method definition. You will get the compilation error.
You have to call the setPaymentInfo
method by matching the method definition correctly as below:
setData(cardNumber: string) {
this.paymentInfoService.setPaymentInfo('', cardNumber, '', '');
}
Concern 2: MatFormField
error
In the confirmation page, the below HTML will get an error as MatFormField
requires containing the MatFormFieldControl
<mat-form-field >
<p>{{payment.cardNumber}}</p>
</mat-form-field>
Hence, you need to perform either of these actions:
Remove the
<mat-form-field>
element as not required.Provide
MatFormFieldControl
to<mat-form-field>
element.
<mat-form-field >
<input matInput [value]="payment.cardNumber" readonly />
</mat-form-field>
Solution
- Modify the Payment Info page's submit button to remove the
routerLink
attribute.
<button
mat-raised-button
color="accent"
type="submit"
>
Confirm Purchase
</button>
- Inject
Router
service.
constructor(
private formBuilder: FormBuilder,
private paymentInfoService: PaymentInfoService,
private router: Router
) {}
- Navigate to the confirmation page through the
onSubmit
function.
onSubmit(): void {
this.setData(this.checkoutForm.value.cardNumber!);
this.router.navigate(['/confirmation']);
}