I'm looking for similar solution to ui-router abstract state in Angular2 Router.
To have "virtual" parent state to resolve some common things for child states.
A route doesn't need to be associated with a component. It can just have children with an empty path. You can use this "empty" route for things like guards or resolves.
One thing I didn't know until testing right now, is that Resolves (it's data) will trickle down to child routes. So if you want to "resolve some common things for child states", this might be the place to do it.
{
path: '',
resolve: {
data: DummyResolve
},
children: [
{ path: 'one', component: Child1Component },
{ path: 'two', component: Child2Component }
]
}
Here is the complete test I used to test with
import { Component, Injectable, OnInit } from '@angular/core';
import { Router, Resolve, ActivatedRoute } from '@angular/router';
import { By } from '@angular/platform-browser';
import { Location, CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing';
import { TestBed, inject, fakeAsync, tick, ComponentFixture } from '@angular/core/testing';
@Injectable()
class DummyResolve implements Resolve<string> {
resolve() {
return 'Hello Routing';
}
}
@Component({
template: `
<router-outlet></router-outlet>
`
})
class RoutingComponent {
}
@Component({
template: `
<h1>Child One</h1>
<span>{{ data }}</span>
`
})
class Child1Component implements OnInit {
data: string;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.data.forEach((data: { data: string }) => {
this.data = data.data;
console.log(`data from child 1: ${this.data}`);
});
}
}
@Component({
template: `
<h1>Child Two</h1>
<span>{{ data }}</span>
`
})
class Child2Component implements OnInit {
data: string;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.data.forEach((data: { data: string }) => {
this.data = data.data;
console.log(`data from child 2: ${this.data}`);
});
}
}
describe('component: RoutingComponent', function () {
let fixture: ComponentFixture<RoutingComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
CommonModule,
RouterTestingModule.withRoutes([
{
path: '',
resolve: {
data: DummyResolve
},
children: [
{ path: 'one', component: Child1Component },
{ path: 'two', component: Child2Component }
]
}
])
],
providers: [ DummyResolve ],
declarations: [ RoutingComponent, Child1Component, Child2Component ]
});
fixture = TestBed.createComponent(RoutingComponent);
fixture.detectChanges();
});
it('should go to child one',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
router.navigate(['/one']);
tick();
fixture.detectChanges();
let debugEl = fixture.debugElement;
expect(debugEl.query(By.css('h1')).nativeElement.innerHTML).toEqual('Child One');
expect(debugEl.query(By.css('span')).nativeElement.innerHTML).toEqual('Hello Routing');
})));
it('should go to child two',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
router.navigate(['/two']);
tick();
fixture.detectChanges();
let debugEl = fixture.debugElement;
expect(debugEl.query(By.css('h1')).nativeElement.innerHTML).toEqual('Child Two');
expect(debugEl.query(By.css('span')).nativeElement.innerHTML).toEqual('Hello Routing');
})));
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With