3

I'm stuck with Angular2, I would like to pass parameters from a Products page (eg: product ids) to a Payment page, here is what I tried so far:

enter image description here

payment.html :

  Message: {{message}}
  <page-products></page-products>

payment.ts :

import { Component, ViewChild, AfterViewInit} from '@angular/core';
import { ProductsPage } from "../../products/products";

@IonicPage()
@Component({
    selector: 'page-payment',
    templateUrl: 'payment.html'
})
export class PaymentPage implements AfterViewInit {

     @ViewChild(ProductsPage) child;

     constructor(public navCtrl: NavController) {}

     message:string;

     ngAfterViewInit() {
             this.message = this.child.message
     }
    }

products.ts :

import { Component} from '@angular/core';
import { IonicPage, NavController } from 'ionic-angular';

@IonicPage()
@Component({
    selector: 'page-products',
    templateUrl: 'products.html',
})
 export class ProductsPage {

     message: string = "Hola Mundo!"

     constructor(public navCtrl: NavController) {}

     goToPayment() {
         this.navCtrl.setRoot('PaymentPage');
     }
 }

product.html :

<button ion-button (click)="goToPayment()">pay</button>

but I always get this error message:

enter image description here

Any idea of what I'm doing wrong?


here is my payment.module.ts:

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { ComponentsModule } from '../../../components/components.module';
import { PaymentPage } from './payment';
import { ProductsPage } from '../../products/products';

@NgModule({
   declarations: [
       PaymentPage, ProductsPage  <-- if I add here ProductsPage, then new error (see under)
   ],
   imports: [
        IonicPageModule.forChild(PaymentPage),
        ComponentsModule
   ]
})
export class PaymentPageModule {}

and products.module.ts :

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { ProductsPage } from './products';
import { ComponentsModule } from '../../components/components.module';

@NgModule({
   declarations: [
      ProductsPage
   ],
   imports: [
      IonicPageModule.forChild(ProductsPage),
      ComponentsModule
  ]
})
export class ProductsPageModule {}

and if I declare ProductsPage like above then I get this error message:

enter image description here

3
  • have you added pageProducts under app.module.ts Commented Feb 13, 2018 at 9:20
  • You need to add the ProductsPage component to the same module the PaymentPage component is associated with. Or if they are in separate modules, you have to export the ProductsPage component from the associated module, and import this particular module to the module the PaymentPage component is bound to. Commented Feb 13, 2018 at 9:22
  • I tried to add ProductsPage in the module PaymentPage but I get a new error message (I edited the question), any idea? Commented Feb 13, 2018 at 9:32

3 Answers 3

2

To pass parameters between components that dont have a hierarchical relationship you should use a service. To achieve this, first create the service:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class MyService {

  private messageSource = new BehaviorSubject<type_of_the_message>(message);
  currentMessage = this.messageSource.asObservable();

  constructor() { }

  sendMessage(message: type_of_the_message) {
    this.messageSource.next(message);
  }

}

Then in the sender component:

    import { Component, OnInit } from '@angular/core';
    import { MyService } from 'pathToService/MyService.service';

    @Component({
      selector: 'sender',
      templateUrl: 'senderTemplate',
      styleUrls: ['senderStyles']
    })
    export class SenderComponent implements OnInit {

      private message: type_of_the_message;

      constructor(private myService: MyService) {}

      ngOnInit() {
        this.myService.currentMessage.subscribe(message => this.message = message);
      }

      sendMessage() {
        this.myService.sendMessage(!this.message);
      }
    }

And finally in the receiver component:

import { Component, OnInit } from '@angular/core';
import { MyService } from 'pathToService/MyService.service';

@Component({
  selector: 'receiver',
  templateUrl: 'receiverTemplate',
  styleUrls: ['receiverStyles']
})
export class ReceiverComponent implements OnInit {

  private message: boolean;

  constructor(private myService: MyService) {}

  ngOnInit() {
    this.myService.currentMessage.subscribe(message => this.message = message);
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

as for the error you're getting, it's because you haven't declared your ProductsPage component inside a module. it seems the appropriate place to do that, is inside products.module.ts (inside it's declarations array in metadata object). but regarding the problem of passing data from a child component, there are better ways to do that. one is using an Output property for the child component and assigning a method to it inside parent's template, and emitting the value when needed...

2 Comments

I tried also with the emit method (using Ouput property etc) but I got the same error message, I added the content of both modules in the question, with ProductsPage added in PaymentPage but I get a new error message, any idea?
actually you have to see where you're using the component. if it's under both PaymentPageModule and ProductPageModule, then you have to declare it under a higher level module like AppModule
0

///payments.ts

import { Component, ViewChild, AfterViewInit} from '@angular/core';
import { ProductsPage } from "../../products/products";
import { OnInit } from "@angular/core/src/metadata/lifecycle_hooks";

@IonicPage()
@Component({
    selector: 'page-payment',
    templateUrl: 'payment.html'
})
export class PaymentPage implements AfterViewInit, OnInit {

     @ViewChild(ProductsPage) child;

     constructor(public navCtrl: NavController, public commonService : CommonService) {}

     message:string;
	  ngOnInit() {
			this.commonService.payment.subscribe(data => {
				this.message = data;
			});
		}

     ngAfterViewInit() {
             this.message = this.child.message
     }
    }
	
	
	
///	products.ts
	
	
	import { Component} from '@angular/core';
import { IonicPage, NavController } from 'ionic-angular';

@IonicPage()
@Component({
    selector: 'page-products',
    templateUrl: 'products.html',
})
 export class ProductsPage {

     message: string = "Hola Mundo!"

     constructor(public navCtrl: NavController, public commonService : CommonService) {}

     goToPayment() {
       commonService.goToPayment(message);
     }
 }
 ///commonService
 
 @Injectable()
export class CommonService {

  @Output() payment: EventEmitter<String> = new EventEmitter();

  goToPayment(message) {
	  this.payment.emit(message);
      this.navCtrl.setRoot('PaymentPage');
  }

}

share the data between components in 3 different ways. Using service is the best. Referral Url

2 Comments

I tried sharing data using a service, evthg works fine but when I refresh the page then the data I get from the service are empty, any idea?
When ever event occurred on a service function we are emit the event with data from the service. That event we can subscribe any where of other components. After subscribing the data in component. Can you pls unsubscribe eventemitter in onDestroy function of component where you are subscribing data.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.