Skip to content

Commit

Permalink
Merge pull request #21 from joanllenas/v6
Browse files Browse the repository at this point in the history
V6
  • Loading branch information
joanllenas authored Mar 14, 2021
2 parents 406f827 + 3aa9cb0 commit 0b7a631
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 265 deletions.
97 changes: 69 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ Our html template will have to use complex `*ngIf` statements to make sure we ar
Instead of using a complex data structures we use a single data type to express all possible request states:

```ts
type RemoteData<T, E> = NotAsked | InProgress<T> | Failure<E, T> | Success<T>;
type RemoteData<T, E>
= NotAsked
| InProgress<T>
| Failure<E, T>
| Success<T>;
```

This approach **makes it impossible to create invalid states**.
Expand Down Expand Up @@ -165,7 +169,7 @@ export class AppComponent {

<a name="examples-demo" />

#### Demo
#### Demo 👀

- [Stackblitz Ngrx demo](https://stackblitz.com/edit/ngx-remotedata-demo?file=src%2Fapp%2Fmeow%2Freducer.ts)

Expand All @@ -181,13 +185,13 @@ export class AppComponent {

<a name="examples-ngrx" />

- [Ngrx (includes store rehydration with de/serialization)](src/app/examples/ngrx)
- [Ngrx](src/app/examples/ngrx) _(includes store rehydration from `localStorage`)_

<a name="api" />

## Api

### RemoteData
### RemoteData 📚

`RemoteData<T, E>`

Expand All @@ -198,7 +202,7 @@ export class AppComponent {

- Type guard function: `isRemoteData = <T, E>(value: unknown): value is RemoteData<T, E>`.

### NotAsked
### NotAsked 📚

- Constructor function: `notAsked<T, E>(): RemoteData<T, E>`.
- Type guard function: `isNotAsked<T, E>(value: unknown): value is NotAsked`.
Expand All @@ -216,7 +220,7 @@ if (isNotAsked(myRemoteData)) {
}
```

### InProgress
### InProgress 📚

- Constructor function: `inProgress<T, E>(value?: T): RemoteData<T, E>`.
- Type guard function: `isInProgress<T, E>(value: unknown): value is InProgress<T>`.
Expand All @@ -233,11 +237,11 @@ const myRemoteData: RemoteData<User> = inProgress({ email: '[email protected]' });

if (isInProgress(myRemoteData)) {
// Here myRemoteData is narrowed to InProgress
console.log(`I have some data: ${myRemoteData.value().email}`);
console.log(`I have some data: ${myRemoteData.value.email}`);
}
```

### Success
### Success 📚

- Constructor function: `success<T, E>(value: T): RemoteData<T, E>`.
- Type guard function: `isSuccess<T, E>(value: unknown): value is Success<T>`.
Expand All @@ -252,11 +256,11 @@ const myRemoteData: RemoteData<User> = success({ email: '[email protected]' });

if (isSuccess(myRemoteData)) {
// Here myRemoteData is narrowed to Success
console.log(`I have some data: ${myRemoteData.value().email}`);
console.log(`I have some data: ${myRemoteData.value.email}`);
}
```

### Failure
### Failure 📚

- Constructor function: `failure<T, E>(err: E, val?: T): RemoteData<T, E>`.
- Type guard function: `isFailure<T, E>(value: unknown): value is Failure<E, T>`.
Expand All @@ -275,8 +279,8 @@ const myRemoteData: RemoteData<User> = failure('Something went wrong.', {

if (isFailure(myRemoteData)) {
// Here myRemoteData is narrowed to Failure
console.log(`This is the failure: ${myRemoteData.error()}`);
console.log(`I have some data: ${myRemoteData.value().email}`);
console.log(`This is the failure: ${myRemoteData.error}`);
console.log(`I have some data: ${myRemoteData.value.email}`);
}
```

Expand All @@ -291,7 +295,7 @@ const myRemoteData: RemoteData<User, Error> = failure(

## Unwrapping RemoteData values

### getOrElse
### getOrElse 📚

```ts
getOrElse<T, E>(rd: RemoteData<T, E>, defaultValue: T): T;
Expand All @@ -300,14 +304,15 @@ getOrElse<T, E>(rd: RemoteData<T, E>, defaultValue: T): T;
`getOrElse` _unwraps_ and returns the value of `Success` instances or the `defaultValue` when it's any other `RemoteData` variant.

```ts
// Example
let myRemoteData = success('ok!');
console.log(getOrElse(myRemoteData, 'The default value')); // ok!

myRemoteData = failure('There has been an error');
console.log(getOrElse(myRemoteData, 'The default value')); // The default value
```

### fold
### fold 📚

```ts
fold<T, E>(
Expand All @@ -321,9 +326,22 @@ fold<T, E>(

With `fold` you _unwrap_ the `RemoteData` value by providing a function for each of the type variants.

```ts
// Example
const rd = success('this is fine!');
const result = fold(
() => 'not asked',
val => 'in progress: ' + val,
(error, value) => `failure: ${error} ${value}`,
value => 'success: ' + value,
rd
);
console.log(result); // success: this is fine!
```

## Transforming RemoteData values

### map
### map 📚

```ts
map<A, B, E>(
Expand All @@ -335,13 +353,14 @@ map<A, B, E>(
With `map` you provide a transformation function that is applied to a `RemoteData` only when it's a `Success` instance.

```ts
// Example
const scream = (s: string) => s.toUpperCase();
const hello = success('hello!');
const helloScreaming = map(scream, hello);
console.log(helloScreaming); // success('HELLO!')
```

### mapFailure
### mapFailure 📚

```ts
mapFailure<A, E, F>(
Expand All @@ -353,23 +372,45 @@ mapFailure<A, E, F>(
With `mapFailure` you provide a transformation function that is applied to a `RemoteData` only when it's a `Failure` instance.

```ts
// Example
const scream = (s: string) => s.toUpperCase();
const error = failure('wrong!');
const wrongScreaming = mapFailure(scream, error);
console.log(wrongScreaming); // failure('WRONG!')
```

### chain 📚

```ts
chain<A, B, E>(
fn: (a: A) => RemoteData<B, E>,
rd: RemoteData<A, E>
): RemoteData<B, E>;
```

With `chain` you can provide a transormation function that can change the returned `RemoteData` variant.

```ts
// Example
const checkAge = (n: number) =>
n >= 0 ? success(n) : failure(`${n} is an invalid age`);
let ageResult = chain(checkAge, success(25));
expect(ageResult).toEqual(success(25));
ageResult = chain(checkAge, success(-3));
expect(ageResult).toEqual(failure('-3 is an invalid age'));
```

<a name="pipes" />

## Pipes

### isNotAsked
### isNotAsked 📚

`transform<T, E>(rd: RemoteData<T, E>): boolean;`

Returns `true` when `RemoteData` is a `NotAsked` instance.

### anyIsNotAsked
### anyIsNotAsked 📚

```ts
transform<T, E>(
Expand All @@ -379,13 +420,13 @@ transform<T, E>(

Returns `true` when any `RemoteData<T, E>[]` items is a `NotAsked` instance.

### isInProgress
### isInProgress 📚

`transform<T, E>(rd: RemoteData<T, E>): boolean;`

Returns `true` when `RemoteData` is an `InProgress` instance.

### anyIsInProgress
### anyIsInProgress 📚

```ts
transform<T, E>(
Expand All @@ -395,25 +436,25 @@ transform<T, E>(

Returns `true` when any `RemoteData<T, E>[]` item is an `InProgress` instance.

### isFailure
### isFailure 📚

`transform<T, E>(rd: RemoteData<T, E>): boolean;`

Returns `true` when `RemoteData` is a `Failure` instance.

### isSuccess
### isSuccess 📚

`transform<T, E>(rd: RemoteData<T, E>): boolean;`

Returns `true` when `RemoteData` is a `Success` instance.

### hasValue
### hasValue 📚

`transform<T, E>(rd: RemoteData<T, E>): boolean;`

Returns `true` when `RemoteData` is a `Success` instance or is an `InProgress` or `Failure` instance with a value that is not `null` or `undefined`.

### successValue
### successValue 📚

```ts
transform<T, E>(
Expand All @@ -424,7 +465,7 @@ transform<T, E>(

Returns the `Success` payload (of type `T`) when the `RemoteData` is a `Success` instance, otherwise it returns the `defaultValue` when provided or `undefined` when not.

### inProgressValue
### inProgressValue 📚

```ts
transform<T, E>(
Expand All @@ -435,19 +476,19 @@ transform<T, E>(

Returns the `InProgress` payload (of type `T`) when `RemoteData` is an `InProgress` instance, otherwise it returns the provided `defaultValue` or `undefined` when not.

### remoteDataValue
### remoteDataValue 📚

`transform<T, E>(rd: RemoteData<T, E>): T | E | undefined;`

Returns the `InProgress`, `Failure` or `Success` payload (of type `T`) when `RemoteData` is an `InProgress`, `Failure` or `Success` instance. Returns `undefined` otherwise.

### failureError
### failureError 📚

`transform<T, E>(rd: RemoteData<T, E>): E | undefined`

Returns the `Failure` error payload (of type `E`) when `RemoteData` is a `Failure` instance or `undefined` otherwise.

### failureValue
### failureValue 📚

`transform<T, E>(rd: RemoteData<T, E>): T | undefined`

Expand Down
36 changes: 26 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-remotedata",
"version": "5.1.0",
"version": "6.0.0",
"description": "RemoteData: Slaying a UI Antipattern with Angular",
"repository": {
"type": "git",
Expand Down Expand Up @@ -48,9 +48,10 @@
"@angular/platform-browser": "~11.1.0",
"@angular/platform-browser-dynamic": "~11.1.0",
"@angular/router": "~11.1.0",
"@ngrx/effects": "^10.1.2",
"@ngrx/store": "^10.1.2",
"@ngrx/store-devtools": "^10.1.2",
"@ngrx/effects": "^11.0.1",
"@ngrx/store": "^11.0.1",
"@ngrx/store-devtools": "^11.0.1",
"ngrx-store-localstorage": "^11.0.0",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
Expand Down
Loading

0 comments on commit 0b7a631

Please sign in to comment.