简体   繁体   中英

How to pass data from a form into another component in angular

I have a form within my cart-item component. It is supposed to be used as a checkout page. When the user fills out the form with their information and selects the button, I need to send them to a confirmation page, that displays all of the data they just entered into the form. I am having trouble passing the data from my cart-item component to my confirmation component. I feel like I should be using a service, but I am new to angular and unsure how to do this.

Cart-item HTML:

       <form #userForm="ngForm"(ngSubmit)="onClickSubmit(userForm.value)" >
            <div class="row">
              <div class="col-md-6 mb-3">
                <label for="firstName">First name</label>
                <input type="text" ngModel name="firstName" #firstName="ngModel"class="form-control" id="firstName" placeholder="" value="" required>
                <div class="alert alert-danger"*ngIf=" firstName.touched && !firstName.valid" >
                   First Name is required.
                </div>
              </div>
              <div class="col-md-6 mb-3">
                <label for="lastName">Last name</label>
                <input type="text" ngModel name="lastName" #lastName="ngModel"class="form-control" id="lastName" placeholder="" value="" required>
                <div class="alert alert-danger"*ngIf=" lastName.touched && !lastName.valid" >
                   Last Name is required.
                </div>
              </div>
            </div>
    
      
            <div class="mb-3">
              <label for="email">Email <span class="text-muted">(Optional)</span></label>
              <input type="email" class="form-control" id="email" placeholder="you@example.com">
              <div class="invalid-feedback">
                Please enter a valid email address for shipping updates.
              </div>
            </div>
    
            <div class="mb-3">
              <label for="address">Address</label>
              <input type="text" ngModel name="address" #address="ngModel"class="form-control" id="address" placeholder="" value="" required>
              <div class="alert alert-danger"*ngIf="address.touched && !address.valid" >
                 Address is required.
              </div>
              
            </div>
    
        
            <div class="row">
              <div class="col-md-5 mb-3">
                <label for="country">Country</label>
                <select class="custom-select d-block w-100" id="country" required>
                  <option>United States</option>
                </select>
                <div class="invalid-feedback">
                  Please select a valid country.
                </div>
              </div>
              <div class="col-md-4 mb-3">
                <label for="state">State</label>
                <select class="custom-select d-block w-100" id="state" required>
                  <option value="">Choose...</option>
                  <option>California</option>
                  <option>Pennsylvania</option>
                </select>
                <div class="invalid-feedback">
                  Please provide a valid state.
                </div>
              </div>
              <div class="col-md-3 mb-3">
                <label for="zip">Zip</label>
                <input type="text" class="form-control" ngModel name="zip" #zip="ngModel" id="zip" placeholder="" required>
                <div class="alert alert-danger"*ngIf="zip.touched && !zip.valid">
                  Zip code required.
                </div>
              </div>
            </div>
      
        
      
    
            <h4 class="mb-3">Payment</h4>
    
            <div class="d-block my-3">
              <div class="custom-control custom-radio">
                <input id="credit" name="paymentMethod" type="radio" class="custom-control-input" checked required>
                <label class="custom-control-label" for="credit">Credit card</label>
              </div>
              <div class="custom-control custom-radio">
                <input id="debit" name="paymentMethod" type="radio" class="custom-control-input" required>
                <label class="custom-control-label" for="debit">Debit card</label>
              </div>
              <div class="custom-control custom-radio">
                <input id="paypal" name="paymentMethod" type="radio" class="custom-control-input" required>
                <label class="custom-control-label" for="paypal">PayPal</label>
              </div>
            </div>
            <div class="row">
              <div class="col-md-6 mb-3">
                <label for="cc-name">Name on card</label>
                <input type="text" class="form-control" ngModel name="name" #name="ngModel" id="cc-name" placeholder="" required>
                <small class="text-muted">Full name as displayed on card</small>
                <div class="alert alert-danger"*ngIf="name.touched && !name.valid">
                  Name on card is required
                </div>
              </div>
              <div class="col-md-6 mb-3">
                <label for="cc-number">Credit card number</label>
                <input type="text" ngModel name="card" #card="ngModel" class="form-control" id="cc-number" placeholder="" required>
                <div class="alert alert-danger"*ngIf="card.touched && !card.valid">
                  Credit card number is required
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col-md-3 mb-3">
                <label for="cc-expiration">Expiration</label>
                <input type="text" class="form-control" ngModel name="expiration" #expiration="ngModel" id="cc-expiration" placeholder="" required>
                <div class="alert alert-danger"*ngIf="expiration.touched && !expiration.valid">
                  Expiration date required
                </div>
              </div>
              <div class="col-md-3 mb-3">
                <label for="cc-cvv">CVV</label>
                <input type="text" class="form-control" ngModel name="cvv" #cvv="ngModel" id="cc-cvv" placeholder="" required>
                <div class="alert alert-danger"*ngIf="cvv.touched && !cvv.valid">
                  Security code required
                </div>
              </div>
            </div>
            <hr class="mb-4">
            <button class="btn btn-primary btn-lg btn-block" type="submit" [disabled]="userForm.invalid">Purchase Product(s)</button>
          </form>

cart-item.ts:

import { Component, OnInit,Input } from '@angular/core';
import { Product } from '../product';
import { CardComponent } from '../card/card.component'
import { Router } from '@angular/router'

@Component({
  selector: 'app-cart-item',
  templateUrl: './cart-item.component.html',
  styleUrls: ['./cart-item.component.css']
})
export class CartItemComponent implements OnInit {

  @Input() product!: Product;
  namesOfDestinations:any=[];
  descriptions:any=[]
  prices:any=[];
  totalPrice:number=0;

  items:any=[];
  confirmPurchase:any=[];

constructor(public router: Router) { }

  ngOnInit(): void {
   
    // console.log(this.cart)
    // this.cartItems()
    this.getNames()
    this.getDescription()
    this.getPrice()
    this.getLocalStorageLength()
    this.getTotalPrice()
  }
onClickSubmit(data:any){
  this.router.navigate(['/confirmation'])
  this.confirmPurchase.push(data)
  console.log(this.confirmPurchase)
 }
}

confirmation-page html:

<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td align="center" style="background-color: #eeeeee;" bgcolor="#eeeeee">
            <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:600px;">
                <tr>
                    <td align="center" valign="top" style="font-size:0; padding: 35px;" bgcolor="#F44336">
                        
                        <div style="display:inline-block; max-width:50%; min-width:100px; vertical-align:top; width:100%;" class="mobile-hide">
                            <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:300px;">
                                <tr>
                                    <td align="right" valign="top" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 48px; font-weight: 400; line-height: 48px;">
                                        <table cellspacing="0" cellpadding="0" border="0" align="right">
                                          
                                        </table>
                                    </td>
                                </tr>
                            </table>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td align="center" style="padding: 35px 35px 20px 35px; background-color: #ffffff;" bgcolor="#ffffff">
                        <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:600px;">
                            <tr>
                                <td align="center" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding-top: 25px;"> <img src="https://img.icons8.com/carbon-copy/100/000000/checked-checkbox.png" width="125" height="120" style="display: block; border: 0px;" /><br>
                                    <h2 style="font-size: 30px; font-weight: 800; line-height: 36px; color: #333333; margin: 0;"> Thank You For Your Order! </h2>
                                </td>
                            </tr>
                            <tr>
                                
                            </tr>
                            <tr>
                                <td align="left" style="padding-top: 20px;">
                                    <table cellspacing="0" cellpadding="0" border="0" width="100%">
                                        <tr>
                                            <td width="75%" align="left" bgcolor="#eeeeee" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 800; line-height: 24px; padding: 10px;"> Order Confirmation # </td>
                                            <td width="25%" align="left" bgcolor="#eeeeee" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 800; line-height: 24px; padding: 10px;"> 2345678 </td>
                                        </tr>
                                        <tr>
                                            <td width="75%" align="left" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding: 15px 10px 5px 10px;"> Name: </td>
                                            <td width="25%" align="left" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding: 15px 10px 5px 10px;">{{data.firstName}}<br>{{data.lastName}} </td>
                                        </tr>
                                        <tr>
                                            <td width="75%" align="left" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding: 5px 10px;"> Email </td>
                                            <td width="25%" align="left" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px; padding: 5px 10px;"> {{data.email}} </td>
                                        </tr>
                                      
                                    </table>
                                </td>
                            </tr>
                            <tr>
                                <td align="left" style="padding-top: 20px;">
                                    <table cellspacing="0" cellpadding="0" border="0" width="100%">
                                        <tr>

                                            
                                        </tr>
                                    </table>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
                <tr>
                    <td align="center" height="100%" valign="top" width="100%" style="padding: 0 35px 35px 35px; background-color: #ffffff;" bgcolor="#ffffff">
                        <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:660px;">
                            <tr>
                                <td align="center" valign="top" style="font-size:0;">
                                    <div style="display:inline-block; max-width:50%; min-width:240px; vertical-align:top; width:100%;">
                                        <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:300px;">
                                            <tr>
                                                <td align="left" valign="top" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px;">
                                                    <p style="font-weight: 800;">Delivery Address</p>
                                                    <p>{{data.address}}<br>{{data.country}}<br>{{data.state}}<br>{{data.zip}}</p>
                                                </td>
                                            </tr>
                                        </table>
                                    </div>
                                    <div style="display:inline-block; max-width:50%; min-width:240px; vertical-align:top; width:100%;">
                                        <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width:300px;">
                                            <tr>
                                                <td align="left" valign="top" style="font-family: Open Sans, Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 24px;">
                                                    <p style="font-weight: 800;">Credit Card Information</p>
                                                    <p>{{data.card}}<br>{{data.expiration}},{{data.cvv}}</p>
                                                    
                                                </td>
                                            </tr>
                                        </table>
                                    </div>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
               
            </table>
        </td>
    </tr>
</table>
onClickSubmit(data:any){
  this.router.navigate(['/confirmation'])
  this.confirmPurchase.push(data)
  console.log(this.confirmPurchase)
 }

Currently your confirmPurchase.push(data) line shouldn't be executed. You are doing that after you navigate to '/confirmation' path.

If you need to make any changes, you need to that before navigating to another path.

In sending component, you can use a service like in the constructor

  constructor(private dataService: DataService) { }

  private newData = new BehaviorSubject<any>({
    name: 'K',
    mail: 'kathy@go.com',
  });

  setNewData(data: any) {
    this.newData.next(data);
  }

  getNewDataInfo() {
    return this.newData.asObservable();
  }

And in the receiving component, you can use getNewDataInfo of the service to receive passed data.

The returned data will be an observable, you can subscribe to it to receive the data you need.

You can try like below,

modify onClickSubmit method in Cart-item.component

onClickSubmit(data: any) {
  this.confirmPurchase.push(data)
  console.log(this.confirmPurchase)
  this.sharedService.setCartItemData(this.confirmPurchase);
  this.router.navigate(['/confirmation'])
 }

Create a service class with BehaviorSubject variable to pass the data between two components.

@Injectable()
export class SharedService {

    public cartItemData = new BehaviorSubject<any>([]);

    constructor() { }
    
    setCartItemData(data: any) {
       this.cartItemData.next(data);
    }

    getCartItemData() {
       return this.cartItemData.asObservable();
    }
}

confirmation-page.component.ts

ngOnInit() {
   this.sharedService.getCartItemData().subscribe(data => {
       console.log('form data ', data);
   });
}

StackBlitz with sample code for your reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM