Skip to content

Commit

Permalink
feat(navigation-end): add navigationEnd util function
Browse files Browse the repository at this point in the history
  • Loading branch information
va-stefanek committed Sep 16, 2023
1 parent ca9606b commit ca159ed
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ nx generate ngxtension:init
- [connect](https://ngxtension.netlify.app/utilities/connect)
- [create-effect](https://ngxtension.netlify.app/utilities/create-effect)
- [if-validator](https://ngxtension.netlify.app/utilities/if-validator)
- [navigation-end](https://ngxtension.netlify.app/utilities/navigation-end)

<!-- UTILITIES:END -->

Expand Down
1 change: 1 addition & 0 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default defineConfig({
{ label: 'createEffect', link: '/utilities/create-effect' },
{ label: 'ifValidator', link: '/utilities/if-validator' },
{ label: 'call apply Pipes', link: '/utilities/call-apply' },
{ label: 'navigationEnd', link: '/utilities/navigation-end' },
],
},
],
Expand Down
35 changes: 35 additions & 0 deletions docs/src/content/docs/utilities/navigation-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: injectNavigationEnd
description: ngxtension/navigation-end
---

The `injectNavigationEnd` function is a utility for creating an `Observable` that emits when a navigation ends. It might perform tasks after a route navigation has been completed.

```ts
import { injectNavigationEnd } from 'ngxtension/navigation-end';
```

## Usage

`injectNavigationEnd` accepts optionally `Injector`.

```ts
import { Component } from '@angular/core';
import { injectNavigationEnd } from 'ngxtension/navigation-end';
import { NavigationEnd } from '@angular/router';

@Component({
standalone: true,
selector: 'app-example',
template: '<p>Example Component</p>',
})
export class ExampleComponent {
navigationEnd$ = injectNavigationEnd();
constructor() {
navigationEnd$.subscribe((event: NavigationEnd) => {
// This code will run when a navigation ends.
console.log('Navigation ended:', event);
});
}
}
```
3 changes: 3 additions & 0 deletions libs/ngxtension/navigation-end/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# ngxtension/navigation-end

Secondary entry point of `ngxtension`. It can be used by importing from `ngxtension/navigation-end`.
5 changes: 5 additions & 0 deletions libs/ngxtension/navigation-end/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"lib": {
"entryFile": "src/index.ts"
}
}
33 changes: 33 additions & 0 deletions libs/ngxtension/navigation-end/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "ngxtension/navigation-end",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"sourceRoot": "libs/ngxtension/navigation-end/src",
"targets": {
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/ngxtension/jest.config.ts",
"testPathPattern": ["navigation-end"],
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": [
"libs/ngxtension/navigation-end/**/*.ts",
"libs/ngxtension/navigation-end/**/*.html"
]
}
}
}
}
1 change: 1 addition & 0 deletions libs/ngxtension/navigation-end/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './navigation-end';
52 changes: 52 additions & 0 deletions libs/ngxtension/navigation-end/src/navigation-end.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Component } from '@angular/core';
import {
ComponentFixture,
TestBed,
fakeAsync,
tick,
} from '@angular/core/testing';
import { NavigationEnd, Router } from '@angular/router';
import { delay, of } from 'rxjs';
import { injectNavigationEnd } from './navigation-end';

describe(injectNavigationEnd.name, () => {
@Component({
standalone: true,
template: '',
})
class Foo {
count = 0;
navigationEnd$ = injectNavigationEnd();

ngOnInit() {
this.navigationEnd$.pipe(delay(0)).subscribe(() => {
this.count = 1;
});
}
}

let component: Foo;
let fixture: ComponentFixture<Foo>;
beforeEach(() => {
TestBed.overrideProvider(Router, {
useValue: {
events: of(new NavigationEnd(0, '', '')),
},
});
fixture = TestBed.createComponent(Foo);
fixture.autoDetectChanges();
component = fixture.componentInstance;
});

it('should modify "count" when router NavigationEnd event occur', fakeAsync(() => {
component.ngOnInit();
expect(component.count).toBe(0);
tick(100);
expect(component.count).toBe(1);

fixture.destroy(); // destroy the component here

tick(500);
expect(component.count).toBe(1);
}));
});
21 changes: 21 additions & 0 deletions libs/ngxtension/navigation-end/src/navigation-end.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Injector, inject, runInInjectionContext } from '@angular/core';
import { Event, NavigationEnd, Router } from '@angular/router';
import { assertInjector } from 'ngxtension/assert-injector';
import { filter, type Observable } from 'rxjs';

/**
* Creates an Observable that emits when a navigation ends.
* @returns An Observable of NavigationEnd events.
*/
export function injectNavigationEnd(
injector?: Injector
): Observable<NavigationEnd> {
injector = assertInjector(injectNavigationEnd, injector);
return runInInjectionContext(injector, () => {
return inject(Router).events.pipe(
filter(
(event: Event): event is NavigationEnd => event instanceof NavigationEnd
)
);
});
}
3 changes: 3 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
"ngxtension/inject-destroy": [
"libs/ngxtension/inject-destroy/src/index.ts"
],
"ngxtension/navigation-end": [
"libs/ngxtension/navigation-end/src/index.ts"
],
"ngxtension/repeat": ["libs/ngxtension/repeat/src/index.ts"],
"ngxtension/resize": ["libs/ngxtension/resize/src/index.ts"],
"plugin": ["libs/plugin/src/index.ts"]
Expand Down

0 comments on commit ca159ed

Please sign in to comment.