Why does Ionic 4 provide NavParams either it does not work?

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

@Component({...})
export class MyPage {
  constructor(
    navParams: NavParams
  ) {
    console.log(navParams.get('foo'));
  }
}

Result: No provider for NavParams!

My current solution is to use router.getCurrentNavigation().extras.state and pass the data by extras state. But maybe there is a better solution? I want to pass data as body. Not as query params in the url.

My current thinking on this topic is that it isn’t worth trying to jam application state into the router, so I just let the router route and manage application state completely separately, in one (or several) services specifically dedicated to that task. Since anything done in the router must be super-generic, it’s not going to be as feature-rich or easy to read as a dedicated service with domain-specific interfaces and descriptive method names. See this post for an example of what I’m talking about.

For Angular

to pass data between components

i prefer use Observable objects or better SubjectBehavior

like this

private _data = new SubjectBehavior<string>();

get data() {
  return this._data.asObservable();
}

then subscribe to that object

and or when I want to pass data to the component that used with its selector

like this

<my-custom-element [dataNeeded]="someThing"></my-custom-element>

i prefer use

@Input() dataNeeded;

If I want to pass data using navParams for example when i need to create the modal with that component

I will use this code

this.modal.create({
  component: 'SomeComponent',
  componentProps: {
       data: 'someThing',
    }
});

A couple of minor things here

  • it’s BehaviorSubject, not SubjectBehavior
  • I don’t bother with asObservable - you can just return _data directly, assuming you type the return value as Observable<Foo>
  • which means getData() should be an ordinary method, and not one of those magical getters (that should be avoided as much as possible anyway)

yea , Always have this mistake

but didn’t get what you mean exactly

why it should be avoid

I think getter and setter functions like that violate the principle of least surprise, although perhaps that is less true for people with extensive JavaScript experience. When I do something like this.fruit = "apple" or let fruit = this.fruits.fruit I’m not expecting anything to happen aside from a mere assignment; I’m not wanting either the potential overhead or unexpected side effects of a function call.

So I would just do this (with the caveat that data is a terrible name in a real application; it’s worth taking the time to use something descriptive):

private data = new BehaviorSubject<Data>({});
getData(): Observable<Data> { return data; }
1 Like