1

I'm currently learning to developp with Angular2 and Ionic2 and I have some problems.

I have a main page, which display a map. On this page, I have a button which displays a Popover, with a list of items. When the user click on an item, it should trigger a function from the page component to display the item on the map, but I don't know how to do this.

I try using an event emitter in the Popover, but I must have made a mistake somewhere, cause the main page never receive the event.

Here are the relevent parts of my code :

import { Component, Output, EventEmitter  } from '@angular/core';
import { OnInit } from '@angular/core';

import { NavParams, ViewController } from 'ionic-angular';

import { ShareService } from '../../../app/service/share.service';
import { FavoriService } from '../../../app/service/favori.service';
import { Favori } from '../../../app/classes/favori';
import { Utilisateur } from '../../../app/classes/utilisateur';



@Component({
  templateUrl: 'popover-favori.html',
  providers: [FavoriService]
})

export class PopoverFavori implements OnInit{

  @Output() selectFav: EventEmitter<string> = new EventEmitter<string>();

  constructor(public navParams: NavParams, 
          public viewCtrl: ViewController,
          private favoriService: FavoriService,
          private shareService: ShareService) {}


  listeFavoris: Favori[] = this.shareService.userFavs;
  user: Utilisateur = this.shareService.currentUser;
  selectedFavori: Favori;

  ngOnInit() {
      if (this.navParams.data) {
        this.listeFavoris = this.navParams.data.listeFavori;

      }
  }

selectFavori(favori) {
  this.selectedFavori = favori;
  this.selectFav.emit(favori.nom_point);
;}

My Popover template :

<h2>Favoris</h2>
<ion-list>
  <ion-item-sliding *ngFor="let favori of listeFavoris" >
    <ion-item>
      <h3><ion-icon name="arrow-back"></ion-icon> {{ favori.nom_point }}</h3>
    </ion-item>
    <ion-item-options side="right">
      <button ion-button color="primary" (click)="selectFavori(favori)">
        <ion-icon name="eye"></ion-icon>
      </button>
    </ion-item-options>
  </ion-item-sliding>
</ion-list>

My page Component

import { Component, Input, AfterViewInit, ViewChild, OnInit  } from '@angular/core';

import { NavController, NavParams, Platform, ViewController, PopoverController } from 'ionic-angular';
import { FavoriService } from '../../app/service/favori.service';
import { AlertsFavoriService } from '../../app/service/alertsFavori.service';
import { ShareService } from '../../app/service/share.service';
import { UtilisateurService } from '../../app/service/utilisateur.service';
import { Utilisateur } from '../../app/classes/utilisateur';
import { Favori } from '../../app/classes/favori';
import { PopoverFavori } from './popover/popover-favori';


@Component({
  selector: 'page-carte',
  templateUrl: 'carte.html',
  providers: [
    FavoriService
    ]
})
export class CartePage implements OnInit {


  constructor(
    private navCtrl: NavController,
    private popoverCtrl: PopoverController, 
    pprivate navParams: NavParams, 
    private utilisateurService: UtilisateurService,
    private favoriService: FavoriService,
    private shareService: ShareService) { 

  }

   reponseFavoris: Favori[];
   reponseAlertsFavori: AlertsFavori[];
   user = this.shareService.currentUser;

  presentPopoverFavori(ev) {

    let popoverFavori = this.popoverCtrl.create(PopoverFavori, {
      listeFavori : this.reponseFavoris,

        });

    popoverFavori.present({
      ev: ev
    });
  }

 selectedFavoriName: string;

    onFavChange(event) {
      this.selectedFavoriName = event;
      this.getItineraireFavori(this.selectedFavoriName, this.shareService.currentUser.utilisateurId);
    }

Page template :

<sebm-google-map> //map stuff
</sebm-google-map>
<button ion-fab (click)="presentPopoverFavori($event)" (selectFav)="onFavChange($event)"><ion-icon name="star"></ion-icon></button>

If someone can help, it would be very appreciate.

3 Answers 3

1

You can handle this without using Events, instead pass in the callback as a parameter:

my-popover.ts

import { Component, Input } from '@angular/core';
import { NavParams } from 'ionic-angular';

@Component()
export class MyPopoverComponent {

  @Input()
  text:string = null;

  constructor(protected navParams:NavParams) {
    this.text = this.navParams.get("text");
  }

  onClicked(event:any) {
    this.navParams.get('clicked')(this.text);
  }
}

my-popover.html

<button ion-button (click)="onClicked($event)">{{text}}</button>

my-page.ts

let popover = this.popoverController.create(MyPopoverComponent, {
  text: "My Popover",
  clicked:(text:string) => {
    console.log(text);
  }
});
popover.present();
0

I didn't find a problem or the problem is too subtle, so lets cheat and use Events provider from ionic2 instead of EventEmitter. Because you can.

Adjust the popover component:

  constructor(public navParams: NavParams, 
          public viewCtrl: ViewController,
          private favoriService: FavoriService,
          private shareService: ShareService,
          private events:Events) {}

  selectFavori(favori) {
    this.selectedFavori = favori;
    this.events.publish('favori:selected',favori.nom_point);
  }

Then in constructor of the page

constructor(
    private navCtrl: NavController,
    private popoverCtrl: PopoverController, 
    pprivate navParams: NavParams, 
    private utilisateurService: UtilisateurService,
    private favoriService: FavoriService,
    private shareService: ShareService,
    private events:Events) { 
     this.events.subscribe('favori:selected', onFavChange);
  }
1
  • Thanks for your suggestion. It's not working yet, but I know if the problem is that the event is not emitted when the button is clicked or if the page doesn't receive it. Do you know where I can find working example with Ionic Events provider, please ?
    – Gaetane
    Commented Apr 12, 2017 at 8:36
0

I have implemented Events provider from ionic 2. This work fine.

 import { Events } from 'ionic-angular';

// first page (publish an event when a user is created)
constructor(public events: Events) {}
createUser(user) {
  console.log('User created!')
  this.events.publish('user:created', user, Date.now());
}


// second page (listen for the user created event after function is called)
constructor(public events: Events) {
  events.subscribe('user:created', (user, time) => {
    // user and time are the same arguments passed in `events.publish(user, time)`
    console.log('Welcome', user, 'at', time);
  });
}

Ionic Doc : https://ionicframework.com/docs/api/util/Events/

Source code : https://github.com/ionic-team/ionic/tree/master/demos/src/events

Not the answer you're looking for? Browse other questions tagged or ask your own question.