23

In Ionic 3 you could use the second argument of the navController to pass data to the next page and retrieve it with the navParams service.

This was a really convenient feature. Is there an equivalent api for routing in Ionic 4?

You can always JSON.stringify the object/array to the routerParams, which in my opinion is less convenient.

In Ionic 4 you can pass data with the modalController using ComponentProps and @Input() making it more suitable of a quick push/pop implementation.

EDIT

My intention with this question is to find out if there are any native APIs from Angular 6+ or Ionic 4+. I am well aware of ways to implement a custom service or resolver to accomplish this.

The goal is to use ionic's and angular's api to its fullest, since in larger projects each custom code requires documentation and increases complexity.

Han Che
  • 8,239
  • 19
  • 70
  • 116
  • 1
    This question talks about that https://stackoverflow.com/questions/41969571/how-can-i-programatically-pass-parameters-to-an-auxiliary-route-in-angular2 – hamilton.lima Sep 05 '18 at 14:22
  • 1
    Thanks for the suggestions, but as I've just edited, you could always pass a stringified object/array to the params. However the previous navController in ionic3 was more convenient – Han Che Sep 05 '18 at 14:24
  • Maybe another option is to create a mediator with rxjs/Subject to hold event values – hamilton.lima Sep 05 '18 at 15:28
  • 1
    If you want to pass data between component in you app the best option is to use rxjs/Subject and pass the info through a service, I can create an example of this as an answer if this is what you want. – Araldy Sep 05 '18 at 22:01
  • 1
    @Araldy thanks but that's not the answer I'm looking for. The Idea is to utilize default features to increase code transparency between our team. Each time you start a new service adds to unnecessary complexity – Han Che Sep 06 '18 at 07:24

6 Answers6

20

There is multiple ways to pass a parameters from a page to another in Ionic v4 / Angular 7.2+:

1. Using Extras State (new since Angular 7.2) - Recommanded

Simple and clean

// original page
let navigationExtras: NavigationExtras = { state: { foo: this.foo } };
this.router.navigate(['destination-path'], navigationExtras);
// destination page
constructor(private route: ActivatedRoute, private router: Router) {
    this.route.queryParams.subscribe(params => {
      if (this.router.getCurrentNavigation().extras.state) {
        this.foo= this.router.getCurrentNavigation().extras.state.foo;
      }
    });
  }

2. Use a service and a resolver

Does not fecth the data but a bit heavy.

Store the data into a service and pass a resolver using the router

3. Using object's id (not recommanded)

If your object is stored, you can pass the id in the url and fetch it again.

It will slows the application, implies that the object is stored somewhere and may increase networks issues (if not stored localy)

4. Using query params (not recommanded)

By stringyfing your object: See @Tahseen Quraishi's answer

Only few informations can be passed and the URL is hideous

Some examples here

NayoR
  • 702
  • 6
  • 13
14

I have solved this by wrapping the Ionic NavController in a provider which has functions to set a value to a variable and a function to get it again. Similar to this.navParams.get('myItem').

Take a look at the following;

import { Injectable } from '@angular/core';
import { NavController } from '@ionic/angular';

@Injectable()
export class Nav {
    data: any;

    constructor(public navCtrl: NavController) {
        // ...
    }

    push(url: string, data: any = '') {
        this.data = data;

        this.navCtrl.navigateForward('/' + url);
    }

    pop(url) {
        this.navCtrl.navigateBack('/' + url);
    }

    get(key: string) {
        return this.data[key];
    }
}

Hope this helps!

Adam Thoor
  • 141
  • 1
  • 4
  • Thanks for the suggestion, this would've been my fallback approach too. But as I've mentioned in the a comment above, it's importat to utilize default apis when working in a larger projekt and team. Each custom service you write creates complexity and documentation efforts – Han Che Sep 07 '18 at 12:49
  • Sure, I get that, but as of now it seems like this is the best way, unless you want to use angulars router.navigate which doesn't support ionics animations very well. – Adam Thoor Sep 07 '18 at 13:23
  • 1
    `NavParams` is not available in ionic 4. – shah Feb 06 '19 at 00:20
7

You can simply pass the object with route using queryParams.

import { Router } from '@angular/router';

      object = {
            name: 'subham',
            age: '34',
            address: '34 street, Delhi, India'
            }

      constructor(public router : Router) {}

            onGoToNextPage(){
            this.router.navigate(['/pageName'],{
            queryParams: this.object,
            });
          }

To receive this object you need to use ActivatedRoute which is to be imported from '@angular/router'

import { ActivatedRoute } from '@angular/router';


 constructor(public activatedRoute : ActivatedRoute,) { 

                this.activatedRoute.queryParams.subscribe((res)=>{
                  console.log(res);
              });
              }

In case you have little complex structure of object.

let suppose you have below object to send.

object = {
                name: 'subham',
                age: '34',
                address: '34 street, Delhi, India'
                favourite_movie: ['dhoom','race 2','krishh'],
                detail : {
                  height: '6ft',
                  weight: '70kg'
                 }
                }

To send the above object you need to first stringify the object with the help of JSON.stringfy().

   import { Router } from '@angular/router';

          object = {
                    name: 'subham',
                    age: '34',
                    address: '34 street, Delhi, India'
                    favourite_movie: ['dhoom','race 2','krishh'],
                    detail : {
                      height: '6ft',
                      weight: '70kg',
                     }
                    }

          constructor(public router : Router) {}

                onGoToNextPage(){
                this.router.navigate(['/pageName'],{
                queryParams: {
                   value : JSON.stringify(this.object)
                  },
                });
              }

To recieve this object you need to parse this object using JSON.parse() method.

import { ActivatedRoute } from '@angular/router';


 constructor(public activatedRoute : ActivatedRoute,) { 

                this.activatedRoute.queryParams.subscribe((res)=>{
                  console.log(JSON.parse(res.value));
              });
              }
Tahseen Quraishi
  • 1,353
  • 1
  • 14
  • 16
5

Actually there is many way to pass data between pages. I tried over Route and navCtrl but, it didn't works for me. I am sharing a way to pass data using SERVICE.

  1. Create a service on your ionic project or you can follow the same steps for Angular project also (only the command will change):
  $ ionic generate provider <any name>
  1. Put this codes on your service TS file.
  import { Injectable } from "@angular/core";
  import { map } from "rxjs/operators";
  import { BehaviorSubject } from "rxjs";  

  @Injectable({ providedIn: "root" })

  export class <your_class_name_here> {
    constructor() {}

    private dataSource = new BehaviorSubject("default message");
    serviceData = this.dataSource.asObservable();

    changeData(data: any) {
      this.dataSource.next(data);
    }
  }
  1. Import the service on both pages, from where you take the data and where to want to get the data. like this.
  import { UserService } from "./../services/user.service";

  constructor(
    private userServ: UserService,
  ) {}
  1. Set your data like this :
  this.userServ.changeData(responceData.data);
  1. get your data like this :
  sentData: any;

  ngOnInit() {
    this.userServ.serviceData
      .subscribe(data => (this.sentData = data));
    console.log("sent data from login page : ", this.sentData);
  }

this works for me.

Al Dass
  • 831
  • 15
  • 23
Sushil
  • 2,324
  • 1
  • 27
  • 26
  • 1
    Can we use Events to share to share data between one page to another? – Mohan Jan 31 '19 at 13:52
  • If you're passing data that isn't going to change, it might be simpler to make `get` and `set` methods that you can use instead of `changeData` and `subscribe`. – br1ckd Apr 05 '19 at 18:13
  • yes, than can be possible. but I preferred this way. – Sushil Apr 21 '19 at 10:47
2

I have solved this

You can simply pass the object data with route using JSON.stringify.

this.router.navigate(['namepage',JSON.stringify(data)]);

To recieve this object you need to parse this object using JSON.parse() method.

items: any;

this.items = JSON.parse(this.activatedRoute.snapshot.paramMap.get('id'));

to visualize the data we attach the name of the field where it is saved

this.idxxx = this.items.namefield;

you must first define the parameter in app.routing.module.ts

const routes: Routes = [
  { path: '', redirectTo: 'login', pathMatch: 'full' },
  { path: 'namepage/:id', loadChildren: './pages/page/page.module#pagePageModule' },
];

I hope it helps you, it really is the easiest way to do it

0

I've been working with Ionic 4 since the first beta and I haven't found what you are looking for. I believe the Ionic team wants to leave the task of component interaction to the component framework (Angular, React, Vue...).

If you want to reduce complexity, you could use Angular services, redux or ngrx for state management of the application. This way you could navigate to a view, update the global state through an action, then go back to the previous view and show the updated state.

David Villamizar
  • 802
  • 9
  • 16