Depois de muito tempo, estou de volta na publicação de artigos, neste artigo vamos vou mostrar prar vocês como simplicar aquela tarefa chata que ninguém quer fazer, a redução de boilerplate quando estamos trabalhando com conversão de de uma classe Dart para json e vice-versa.
Todo desenvolvedor Flutter já se deparou com o problema de escrever as funções fromJson
e toJson
quanto estamos trabalhando com base de dados ou mesmo consumindo recursos de algum servidor. É um trabalho simples para projetos bem pequenos, mas quando vamos trabalhar com projetos grande chega a ser uma tarefa difícil de gerir a longo prazo.
Por este motivo websites como o Quicktype (um conversor de Json para classes de diferentes linguagens, incluindo Dart) se tornaram famosos e são ferramentas que estão sendo cada vez mais usadas no dia-a-dia dos desenvolvedores.
Eu vou mostrar para você um jeito mais simples de fazer isso usando um pacote Dart que gera as funções fromJson
e toJson
para você.
json_serializable
É um pacote da linguagem Dart que simplifica a conversão de uma classe Dart para json e vice-versa através da geração de código, continue lendo para ver o funcionamento dela.
Do contrário ao Quicktype este pacote evita ter classes conversoras de de objectos, já que todo trabalho sujo é transparente para o desenvolvedor em um arquivo separado.
Vamos dizer que temos a seguinte classe User
em nosso projeto, e precisamos fazer com ele suporte conversão automática para json, tudo o que precisamos fazer é:
- [x] Adicionar
part 'user.g.dart';
(user, é o nome do ficheiro onde se encontra a classe) - [x] Anotar a classe com a anotação
@JsonSerializable()
- [x] Configurar a classe para usar as funcões gerada pelo pacote.
Com todos os passos feitos, teremos uma classe parecida com:
part of 'user.dart';
@JsonSerializable()
class User {
final String firstName;
final String lastName;
final DateTime dateOfBirth;
User({this.firstName, this.lastName, this.dateOfBirth});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
De momento a IDE poderá mostrar erros nas últimas linhas da classe, isso porque não geramos o codigo necessário para o funcionamento da classe. Após a execução de flutter pub run build_runner build
teremos o problema resolvido e vai aparecer um novo ficheiro user.g.dart
com o seguinte:
part of 'user.dart';
User_$UserFromJson(Map<String, dynamic> json) {
return User(
firstName: json['firstName'] as String,
lastName: json['lastName'] as String,
dateOfBirth: DateTime.parse(json['dateOfBirth'] as String),
);
}
Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
'firstName': instance.firstName,
'lastName': instance.lastName,
'dateOfBirth': instance.dateOfBirth.toIso8601String(),
};
Este é o arquivo que contém o código gerado, o codigo necessário para a conversão automática da sua classe para json. Não se preocupe, você não precisa saber da existência deste arquivo, e nem precisa usar ele.
Conversão de Classes usando outras classes como propiedades.
Por padrão este pacote não suporta conversão de propriedades de tipos desconhecidos, o que pode causar problema se você tiver uma classe do tipo:
@JsonSerializable()
class User {
final Location location;
User({this.location});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
O que o pacote vai fazer é tentar converter a instância de location
para string, e uma vez que ela não é string irá disparar uma esceção de conversão.
Para resolver este problema, nós devemos fazer duas coisas: dizer ao pacote para que chame a função fromJson
/toJson
em objectos desconhecidos, e adicionar tais funções em nossos objectos.
- Setando a propiedade
explicitToJson
paratrue
, o pacote vai então chamarfromJson
/toJson
sempre que precisar converter um tipo de dado desconhecido, neste caso quando ela precisar converter a propiedadelocation
.
@JsonSerializable(explicitToJson: true)
class User {
...
}
- Definir
fromJson
/toJson
na classe que precisa de conversão.
part of 'location.dart';
@JsonSerializable()
class Location {
final double lat;
final double lgn;
User({this.lat, this.lng});
factory Location.fromJson(Map<String, dynamic> json) => _$LocationFromJson(json);
Map<String, dynamic> toJson() => _$LocationToJson(this);
}
E com isso a conversão automática agora funciona com objectos de tipos desconhecidos, ou seja com classes criadas por nós.
OBS: o pacote pode ser encontrado aqui.
Por hoje é tudo, segue para a parte dois, onde veremos conceitos mais avançados deste pacote.
Top comments (0)