Drop
Drop

Reputation: 1572

How take router data from sub-child route to parent route angular 6+?

I wanna take router data from sub-child route to root page , page scheme was be that site.com/admin/dashbord/sub-page, so I need take data in root page from last router sub-page. When I check in console sub-child data, path for data was like that ActivatedRoute > snapshot.children[""0""].children[""0""].data

How I can easy take that data from child route?

Upvotes: 0

Views: 667

Answers (1)

Mauricio Gracia Gutierrez
Mauricio Gracia Gutierrez

Reputation: 10844

Since there are many navigation events (router events) that have the following name and sequence

NavigationStart,
RouteConfigLoadStart,
RouteConfigLoadEnd,
RoutesRecognized,
GuardsCheckStart,
ChildActivationStart,
ActivationStart,
GuardsCheckEnd,
ResolveStart,
ResolveEnd,
ActivationEnd
ChildActivationEnd
NavigationEnd,
NavigationCancel,
NavigationError
Scroll

If you need access to the currently called route you can do this

this.router.events.subscribe(value => {
    console.log('current route: ', router.url.toString());
    // here you should call the emit on the event ...se below
    // this.notify.emit('router.url.toString()')
});

That part was taken from this answer - Angular Router Events: NavigationEnd -- How to filter only the last event

Then using EventEmitter or other methods for Passing data to and from a nested component in Angular 2 you can pass the router.url.toString() from the child to the parent. (as mentioned in the comments)

If it is unclear to you how to connect to to main aspects that I have just mentioned let me know using the comments.

Here are the details for Passing data from a Nested Component

In the previous example I showed how the container can pass data to the nested component by binding to a nested component's property, that is declared with the @Input decorator.

If the nested component wants to send information back to its container, it can raise an event. The nested component exposes an event it can use to pass output to its container using the @Output decorator.

Like with the @Input decorator, we can use the @Output decorator to decorate any property of the nested components class. However, the property type must be an event. The only way a nested component can pass data back to its container, is with an event. The data to pass is called the event payload. In Angular, an event is defined with an EventEmitter object. So let's start by creating a new instance of an Event Emitter and decorate the property with the @Output decorator.

@output() notify: EventEmitter<string> = new EventEmitter<string>();

If you're not familiar with generics, this syntax may look a bit odd to you. Generics allow us to identify a specific type that the object instance will work with.

The generic argument, string, identifies of the event payload. So now we can only pass string values to the container. If we would want to pass a integer for example, we'd write something like this:

@output() notify: EventEmitter<number> = new EventEmitter<number>();

Although not recommended, you can let it accept any type. You can use TypeScript's any type. We'll stick with a string for now. Please note that JavaScript does not support generics by itself; it's a TypeScript feature. I've personally only played with generics in C# a bit, and I think the concept is fairly new to the Javascript community in general.

Now we've got an event emitter in place, let's use the notify event property and call its emit method to raise the notify event and pass in our payload as an argument.

this.notify.emit('payload');

We'll need a user interaction that will raise the event, so I'll add a link that will do so.

/* child.component.html */
<h2>Hi, I'm a nested component</h2>
<span (click)='onClick()'>Click me please!</span>

Now we'll add the click event handler to the component, and raise the notify event:

@Component({
  selector: 'child-selector',
  template: 'child.component.html'
})
export class ChildComponent {
  @output() notify: EventEmitter<string> = new EventEmitter<string>();

  onClick() {
    this.notify.emit('Click from nested component');
  }
}

So every time a user clicks on the 'Click me please' link, the nested component will dispatch an event to its parent component.

The parent component receives that event and its payload. We use event binding to bind to this notify event and call a method.

/* parent.conponent.html */
<div>
  <h1>I'm a container component</h1>
  <child-selector (notify)='onNotify($event)></child-selector>
</div>

We have to pass the $event to the handler because that variable holds the event payload.

The only time we can can specify a nested component's property as an event binding target is when that property is decorated with the @Output decorator.

Our final step is to provide the onNotify method to execute when the notify event occurs. Since the event payload is a string, the onNotify function takes in a string. We can perform any desired action in our handler, but for now let's just alert the payload.

@Component({
  selector: 'parent-selector',
  template: 'parent.component.html',
  directives: [ChildComponent]
})
export class ParentComponent {
  onNotify(message:string):void {
    alert(message);
  }
}

So now we should see an alert with the text from the nested component

Upvotes: 1

Related Questions