Skip to content

Commit

Permalink
feat(component): add error as value to LetDirective's context (#3380)
Browse files Browse the repository at this point in the history
Closes #3343 

BREAKING CHANGES:

The `$error` property from `LetDirective`'s view context is
a thrown error or `undefined` instead of `true`/`false`.

BEFORE:

```ts
<p *ngrxLet="obs$; $error as e">{{ e }}</p>
```

- `e` will be `true` when `obs$` emits error event.
- `e` will be `false` when `obs$` emits next/complete event.

AFTER:

```ts
<p *ngrxLet="obs$; $error as e">{{ e }}</p>
```

- `e` will be thrown error when `obs$` emits error event.
- `e` will be `undefined` when `obs$` emits next/complete event.
  • Loading branch information
markostanimirovic authored May 20, 2022
1 parent 0ffed02 commit 6452e24
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
26 changes: 16 additions & 10 deletions modules/component/spec/let/let.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ class LetDirectiveTestComponent {

@Component({
template: `
<ng-container *ngrxLet="value$; $error as error">{{ error }}</ng-container>
<ng-container *ngrxLet="value$; $error as error">{{
error === undefined ? 'undefined' : error
}}</ng-container>
`,
})
class LetDirectiveTestErrorComponent {
Expand Down Expand Up @@ -376,21 +378,25 @@ describe('LetDirective', () => {
describe('when error', () => {
beforeEach(waitForAsync(setupLetDirectiveTestComponentError));

it('should render the error to false if next or complete', () => {
letDirectiveTestComponent.value$ = of(1);
it('should render undefined when next event is emitted', () => {
letDirectiveTestComponent.value$ = new BehaviorSubject(1);
fixtureLetDirectiveTestComponent.detectChanges();
expect(componentNativeElement.textContent).toBe('false');
expect(componentNativeElement.textContent).toBe('undefined');
});

it('should render the error to true if one occurs', () => {
letDirectiveTestComponent.value$ = throwError(
() => new Error('error message')
);
it('should render undefined when complete event is emitted', () => {
letDirectiveTestComponent.value$ = EMPTY;
fixtureLetDirectiveTestComponent.detectChanges();
expect(componentNativeElement.textContent).toBe('true');
expect(componentNativeElement.textContent).toBe('undefined');
});

it('should render error when error event is emitted', () => {
letDirectiveTestComponent.value$ = throwError(() => 'error message');
fixtureLetDirectiveTestComponent.detectChanges();
expect(componentNativeElement.textContent).toBe('error message');
});

it('should call error handler', () => {
it('should call error handler when error event is emitted', () => {
const errorHandler = TestBed.inject(ErrorHandler);
const error = new Error('ERROR');
letDirectiveTestComponent.value$ = throwError(() => error);
Expand Down
14 changes: 7 additions & 7 deletions modules/component/src/let/let.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface LetViewContext<T> {
/**
* `*ngrxLet="obs$; let e = $error"` or `*ngrxLet="obs$; $error as e"`
*/
$error: boolean;
$error: any;
/**
* `*ngrxLet="obs$; let c = $complete"` or `*ngrxLet="obs$; $complete as c"`
*/
Expand Down Expand Up @@ -66,7 +66,7 @@ export interface LetViewContext<T> {
* <app-number [number]="n" *ngIf="!e && !c">
* </app-number>
*
* <p *ngIf="e">There is an error.</p>
* <p *ngIf="e">There is an error: {{ e }}</p>
* <p *ngIf="c">Observable is completed.</p>
* </ng-container>
* ```
Expand Down Expand Up @@ -94,7 +94,7 @@ export class LetDirective<U> implements OnInit, OnDestroy {
private readonly viewContext: LetViewContext<U | null | undefined> = {
$implicit: undefined,
ngrxLet: undefined,
$error: false,
$error: undefined,
$complete: false,
$suspense: true,
};
Expand All @@ -106,7 +106,7 @@ export class LetDirective<U> implements OnInit, OnDestroy {
reset: () => {
this.viewContext.$implicit = undefined;
this.viewContext.ngrxLet = undefined;
this.viewContext.$error = false;
this.viewContext.$error = undefined;
this.viewContext.$complete = false;
this.viewContext.$suspense = true;

Expand All @@ -118,14 +118,14 @@ export class LetDirective<U> implements OnInit, OnDestroy {
this.viewContext.$suspense = false;

if (event.reset) {
this.viewContext.$error = false;
this.viewContext.$error = undefined;
this.viewContext.$complete = false;
}

this.renderMainView();
},
error: (event) => {
this.viewContext.$error = true;
this.viewContext.$error = event.error;
this.viewContext.$suspense = false;

if (event.reset) {
Expand All @@ -144,7 +144,7 @@ export class LetDirective<U> implements OnInit, OnDestroy {
if (event.reset) {
this.viewContext.$implicit = undefined;
this.viewContext.ngrxLet = undefined;
this.viewContext.$error = false;
this.viewContext.$error = undefined;
}

this.renderMainView();
Expand Down
2 changes: 1 addition & 1 deletion projects/ngrx.io/content/guide/component/let.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ We can track next, error, and complete events:
<app-number [number]="n" *ngIf="!e && !c">
</app-number>

<p *ngIf="e">There is an error.</p>
<p *ngIf="e">There is an error: {{ e }}</p>
<p *ngIf="c">Observable is completed.</p>
</ng-container>
```
Expand Down

0 comments on commit 6452e24

Please sign in to comment.