21

I have a component where I select a set of image objects. I want to pass these selected images to my new route, CreateAlbum. The data it nested and wouldn't be suitable to pass as URL parameters.

Is there any easy way to achieve this?

Here's my code to navigate to the route

  public gotoCreateAlbum(): void {
    this.router.navigate([('/create-album')])
  }

My selected data sits in this variable

@Input() selectedPhotos: IPhoto[];

and this is my routing module

const routes: Routes = [
  { path: 'photos',  component: PhotosComponent},
  { path: 'photos/:filter', component: PhotosComponent},
  { path: 'create-album', component: CreateAlbumComponent}
];

Basically I want to perform the same operations as if the CreateAlbum component was a child to my current component in which case I would have used @Input()

4

7 Answers 7

26

I hope this will work. Try using Query Parameters.

 <nav>
      <a [routerLink]="['/component1']">No param</a>
      <a [routerLink]="['/component2']" [queryParams]="{ page: 99 }">Go to Page 99</a>
 </nav>

or

opencomponent2(pageNum) {
    this.router.navigate(['/component2'], { queryParams: { page: pageNum } });
  }

In child component :

constructor(
    private route: ActivatedRoute,
    private router: Router) {}

  ngOnInit() {
    this.sub = this.route
      .queryParams
      .subscribe(params => {
        // Defaults to 0 if no query param provided.
        this.page = +params['page'] || 0;
      });
  }

I have studied this on rangle.io website. Try this if it works for you. otherwise https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service is only option.

Sign up to request clarification or add additional context in comments.

3 Comments

What if you want to pass object? pageNum:{"name":"John"}
@dev same for me, have you find any solution ?
Maybe you can avoid object. For multiple params you can do this.router.navigate(['/Component2'], { queryParams: { page: 3, otherpage:4 } });
10

See https://angular.io/guide/router for an in-depth example. Scroll down to this code snippet:

gotoHeroes(hero: Hero) {
  let heroId = hero ? hero.id : null;
  // Pass along the hero id if available
  // so that the HeroList component can select that hero.
  // Include a junk 'foo' property for fun.
  this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);
}

To get the value of 'id' in the target component:

ngOnInit() {
  this.heroes$ = this.route.paramMap.pipe(
    switchMap((params: ParamMap) => {
      // (+) before `params.get()` turns the string into a number
      this.selectedId = +params.get('id');
      return this.service.getHeroes();
    })
  );
}

3 Comments

how do you receive the data?
@Philip Beber Why you have used switchMap here
Because this.service.getHeroes() executes asynchronously and returns an observable. If it executed synchronously and returned a plain value then you would use map(). switchmap is cool because it cancels any operations you no longer care about. For example, say this.route.paramMap.pipe() emits a value, then this.service.getHeroes() will be called and an observable created. When this.route.paramMap.pipe() emits another value that observable will be canceled and its resources releases. this.service.getHeroes() is called again and a new observable created.
2

Unless you want users to manipulate the query string in the addressbar, do a "atob" and "btoa" before sending and after receiving the data. Just a little security

Also, if you don't want to have a subscription, you can use the Route snapshot param as follows (just that it doesn't keep on updating like an observable, so unless the component gets re-init, it won't be getting updated value if any. Hence a good place to get the value is in the ngOnInit event handler

// before
this._router.navigate(["/welcome/" + atob(userName)]);

// after
ngOnInit() {
    this.userName = btoa(this.route.snapshot.params['userName']);
}

Comments

2

You can pass data using router, for example

{ path: 'form', component: FormComponent ,data :{data :'Test Data'} },

and your component

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

export class FormComponent {
    sub: any;
    constructor(private route: ActivatedRoute) { }
    ngOnInit() {
        this.sub = this.route
            .data
            .subscribe(value => console.log(value));
    }
}

More info

But this may not be the preferred way, you can use parent child communication or make a service common and share data between them. Check below references for doing that.

Parent child communication

Share data using service

1 Comment

how do you dynamically pass the data? i.e using this.route.navigate()
1
sender html

<a [routerLink]="['../../../print/attendance/',{data:userDetails | json}]">link</a>

receiver ts
ngOnInit() {
   this.route.params.subscribe(params=>
    {
      this.data=JSON.parse(params['data'])
    }
    );

  }

Comments

1

Angular >= 7.2.0 introduced a new way of passing the data when navigating between routed components. In NavigationExtras interface within the router module was added a new attribute: state: any and you can set the data which will be present in the new state.

In component

export class ComponentA {
    constructor(private router: Router) {}

    goToComponentB(): void {
        // programmatically        
        this.router.navigate(['/b'], {state: {data: {...}}});
    }
}

In HTML

<a routerLink="/b" [state]="{ data: {...}}">Go to B</a>

Get data in Component B using history.state.data

export class ComponentB {
    constructor() {
       console.log(history.state.data); // GET DATA
    }
}

Thanks to Ľudovít Hajzer Read the whole blog here https://medium.com/ableneo/how-to-pass-data-between-routed-components-in-angular-2306308d8255

Comments

-1
this.router.navigate(['path', { flag: "1"}]);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.