-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fetch pokemon with validation example
- Loading branch information
1 parent
1565436
commit f39ee8b
Showing
6 changed files
with
128 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
abstract interface class Constants { | ||
static const int minimumPokemonId = 1; | ||
static const int maximumPokemonId = 898; | ||
|
||
static String requestAPIUrl(int pokemonId) => | ||
'https://pokeapi.co/api/v2/pokemon/$pokemonId'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import 'dart:convert'; | ||
|
||
import 'package:fpdart/fpdart.dart'; | ||
import 'package:poke_api/constants.dart'; | ||
import 'package:poke_api/pokemon.dart'; | ||
import 'package:poke_api/pokemon_error.dart'; | ||
|
||
abstract interface class HttpClient { | ||
String get(Uri uri); | ||
} | ||
|
||
Effect<(HttpClient, JsonCodec), PokemonError, Pokemon> program( | ||
String pokemonId, | ||
) => | ||
Effect.gen(($) async { | ||
final (client, json) = await $(Effect.env()); | ||
|
||
final id = await $( | ||
Either.fromNullable( | ||
int.tryParse(pokemonId), | ||
PokemonIdNotInt.new, | ||
), | ||
); | ||
|
||
if (id < Constants.minimumPokemonId && id > Constants.maximumPokemonId) { | ||
return await $(Effect.fail(const InvalidPokemonIdRange())); | ||
} | ||
|
||
final uri = Uri.parse(Constants.requestAPIUrl(id)); | ||
final body = await $(Effect.tryCatch( | ||
execute: () => client.get(uri), | ||
onError: (_, __) => const GetPokemonRequestError(), | ||
)); | ||
|
||
final bodyJson = await $(Either.tryCatch( | ||
execute: () => json.decode(body), | ||
onError: (_, __) => const PokemonJsonDecodeError(), | ||
)); | ||
|
||
final bodyJsonMap = await $<Map<String, dynamic>>( | ||
Either.safeCastStrict( | ||
bodyJson, | ||
(value) => const PokemonJsonInvalidMap(), | ||
), | ||
); | ||
|
||
return $(Effect.tryCatch( | ||
execute: () => Pokemon.fromJson(bodyJsonMap), | ||
onError: (_, __) => const PokemonInvalidJsonModel(), | ||
)); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
class Pokemon { | ||
final int id; | ||
final String name; | ||
final int height; | ||
final int weight; | ||
|
||
const Pokemon({ | ||
required this.id, | ||
required this.name, | ||
required this.height, | ||
required this.weight, | ||
}); | ||
|
||
factory Pokemon.fromJson(Map<String, Object?> json) => Pokemon( | ||
id: json['id'] as int, | ||
name: json['name'] as String, | ||
height: json['height'] as int, | ||
weight: json['weight'] as int, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
sealed class PokemonError { | ||
const PokemonError(); | ||
} | ||
|
||
class PokemonIdNotInt extends PokemonError { | ||
const PokemonIdNotInt(); | ||
} | ||
|
||
class InvalidPokemonIdRange extends PokemonError { | ||
const InvalidPokemonIdRange(); | ||
} | ||
|
||
class GetPokemonRequestError extends PokemonError { | ||
const GetPokemonRequestError(); | ||
} | ||
|
||
class PokemonJsonDecodeError extends PokemonError { | ||
const PokemonJsonDecodeError(); | ||
} | ||
|
||
class PokemonJsonInvalidMap extends PokemonError { | ||
const PokemonJsonInvalidMap(); | ||
} | ||
|
||
class PokemonInvalidJsonModel extends PokemonError { | ||
const PokemonInvalidJsonModel(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: poke_api | ||
description: > | ||
Example of using fpdart to fetch pokemon from pokeapi with validation. | ||
version: 2.0.0 | ||
homepage: https://www.sandromaglione.com/ | ||
repository: https://github.com/SandroMaglione/fpdart | ||
publish_to: "none" | ||
|
||
environment: | ||
sdk: ">=3.3.0 <4.0.0" | ||
|
||
dependencies: | ||
fpdart: | ||
path: ../../packages/fpdart | ||
|
||
dev_dependencies: | ||
lints: ^2.0.1 | ||
test: ^1.23.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters