7

I have a simple project with 3 tabs. When the user hits a button on an item on the first tab I need that item to move to the second tab and vise versa. (I also need to notify a server when this happens). Is there any way for me to pass a item object to a array in the About-Page tab and vise versa?

home.html

<ion-header>
  <ion-toolbar>
    <ion-title>Home</ion-title>
    <ion-buttons end>
      <button ion-button icon-only color="royal" (click)="updateData()">
        <ion-icon name="refresh"></ion-icon>
      </button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-list>
    <ion-item-sliding *ngFor="let item of items">
      <ion-item>
        <ion-icon name="alert" *ngIf="!item.taken" item-left></ion-icon>
        <ion-icon name="checkmark-circle-outline" *ngIf="item.taken" item-left></ion-icon>
        <h2><b>{{item.title}}</b></h2>
        <h3>{{item.name}} | {{item.number}}</h3>
        <h3 style="white-space: normal;"><b>Details:</b> {{item.text}}</h3>
      </ion-item>
      <ion-item-options side="left">
        <button ion-button color="primary" (click)="smsPressed(item)">
          <ion-icon name="text"></ion-icon>
          Text
        </button>
        <button ion-button color="secondary" (click)="phonePressed(item)">
          <ion-icon name="call"></ion-icon>
          Call
        </button>
      </ion-item-options>
      <ion-item-options side="right">
        <button ion-button color="primary" *ngIf="item.taken" (click)="responderPressed(item)">
          <ion-icon name="person"></ion-icon>
          Responder
        </button>
        <button ion-button color="primary" *ngIf="!item.taken" (click)="takecallPressed(item)">
          <ion-icon name="navigate"></ion-icon>
          Take Call
        </button>
      </ion-item-options>
    </ion-item-sliding>
  </ion-list>

  <ion-fab right bottom>
    <button ion-fab color="light" (click)="addItem()"><ion-icon name="add"></ion-icon></button>
  </ion-fab>
</ion-content>

home.ts

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

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  items: any[];

  constructor(public navCtrl: NavController, public alertCtrl: AlertController) {
    this.items = []
      this.items.push({
        title: "Title",
        text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pretium quam at est porta fringilla.",
        name: "Sam",
        number: "(555) 555-5555",
        taken: true,
        responder: {
          name: "Bob",
          phone: "(666) 666-6666"
        }
      })
      this.items.push({
        title: "Stuff",
        text: "Take Now",
        name: "Sam",
        number: "(555) 555-5555",
        taken: false,
        responder: {}
      })

  }

  buttonPressed(item){
    alert(item.title)
  }

  smsPressed(item){alert(item.number)}

  phonePressed(item){alert(item.number)}

  responderPressed(item){alert(item.responder.name)}

  takecallPressed(item){alert(item.taken)}

  updateData(){
    this.items.unshift({
      title: "Added",
      text: "Take Now",
      name: "Sam",
      number: "(555) 555-5555",
      taken: false,
      responder: {}
    })
  }

  addItem(){
    let prompt = this.alertCtrl.create({
      title: 'Add Call',
      message: "Enter the details for the call you want to add",
      inputs: [
        { name: 'title',  placeholder: 'Title'},
        { name: 'text',  placeholder: 'Details'},
        { name: 'name',  placeholder: 'Name'},
        { name: 'number',  placeholder: 'Number'},
      ],
      buttons: [
        { text: 'Cancel',handler: data => {}},
        { text: 'Save',handler: data => {
            this.items.unshift({
              title: data.title,text: data.text,
              name: data.name,number: data.number,
              taken: false,responder: {}
            })
          }
        }
      ]
    });
    prompt.present();
  }
}

tabs.html

<ion-tabs>
      <ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
      <ion-tab [root]="tab2Root" tabTitle="Current" tabIcon="alarm"></ion-tab>
      <ion-tab [root]="tab3Root" tabTitle="Account" tabIcon="contacts"></ion-tab>
</ion-tabs>

tabs.ts

import { Component } from '@angular/core';
import { HomePage } from '../home/home';
import { AboutPage } from '../about/about';
import { ContactPage } from '../contact/contact';

@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {
  // this tells the tabs component which Pages
  // should be each tab's root Page
  tab1Root: any = HomePage;
  tab2Root: any = AboutPage;
  tab3Root: any = ContactPage;

  constructor() {

  }
}
Menachem Hornbacher
  • 2,080
  • 2
  • 24
  • 36
  • One way I did was at tab 1 page, store the data into SQL storage and at tab 2 page, retrieve from SQL storage. There may be better solutions but if you are looking for a quick fix, this may help – Huiting Mar 10 '17 at 02:51
  • http://stackoverflow.com/questions/31026886/how-do-i-share-data-between-components-in-angular2 – Marko Mar 10 '17 at 03:38
  • http://www.gajotres.net/ionic-2-sharing-data-between-pagescomponents/2/ take a look – varun aaruru Mar 10 '17 at 03:52
  • what is the data you wanted to share and from what page to what page you need it – Mohan Gopi Mar 10 '17 at 04:17
  • I am not sure if you have a tab related requirement. But, using [segments](http://ionicframework.com/docs/v2/components/#segment) it is much easier to solve. Of course if your requirement is to use tabs there would be a different solution. Will answer your question in any case. – Sagar Kulkarni Mar 10 '17 at 06:18

3 Answers3

11

There are several way you could achieve this.

  1. Events would be the right choice when it comes to passing data between different pages.

    Events is a publish-subscribe style event system for sending and responding to application-level events across your app.

    create an event with

    constructor(public events: Events) {}
    function sendData(data) {
      events.publish('data:created', data);
    }
    

    subscribe to it using

    events.subscribe('data:created', (data) => { console.log( data); });


  1. Use a shared service

    constructor(public shared: Share) {} pushData(data){ this.shared.items.push(data); }

    You can access items in other components using this.shared.items when you inject the service globally in app.module.ts


  1. Another option would be to use segments instead of tabs. This depends on the use case. For simple applications, this would be the better solution. You can learn more from the documentation.

Edit

I have avoided storing the data in database as its not an efficient way to do this. But there may be use cases for such an approach.

raj
  • 5,989
  • 7
  • 30
  • 62
  • 2
    How can i achieve this if there is no button click event.I want to pass data when user move to secound tab. – shyni May 30 '19 at 08:59
  • Events has been removed in Ionic 5 and need to use Observables. Found a solution here: https://stackoverflow.com/questions/60197785/how-to-fix-member-event-from-ionic-angular-error-in-ionic-5 – Aman Mohammed Mar 12 '20 at 00:20
1

LocalStorage - This could be one of the ways you can solve it.

You can store the necessary data in your localStorage after a specific action from 1 tab using -

let data = {"demo": "demo"};
localStorage.setItem('myData',JSON.stringify(data));

Now, in another tab you can use ionic's lifecycle even ionViewWillEnter() which gets executed whenever a view is entered so the data will be refreshed. Here you can access your data stored in localStorage like this:

ionViewWillEnter(){
    let data = JSON.parse(localStorage.getItem('myData'));
    console.log("Did data load? : ",data);
}

NOTE : You need to use JSON.stringify() and JSON.parse() while storing and retrieving from localStorage as you can only store strings in it.

Sagar Kulkarni
  • 2,072
  • 2
  • 16
  • 25
0

I know, old thread, and Observables/Events is a good way to do it,

but in Ionic, tabs are yet another ion-router-outlet for each tab. So you already have ActivatedRoute. You might think the ActivatedRoute inside your tab component is just for that specific ion-router-outlet, and that it will not contain the same data your tabs.ts has, but you can access the parent ActivatedRoute.

This is where resolvers are storing their resolved data.

in your tabs.ts just populate this value (either using resolvers or ion-refresher or otherwise)

this.activatedRoute.snapshot.data['yourData'];

And in each of your tabs components you can access it by:

this.activatedRoute.snapshot.parent.data['yourData'];

Don't forget to inject the ActivatedRoute object in your constructor.

Also, be aware this is a solution for ionic 4/5, I don't know if it works for 3 and earlier.

SomeOne_1
  • 808
  • 10
  • 10