Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Transaction com valor não nulo

Estou com o mesmo problema postado pela Natalie há alguns meses, mas nenhuma das soluções funcionou.

Ao colocar "?" em Future<Transaction?>, aparece o erro:

A value of type 'Transaction?' can't be assigned to a variable of type 'Transaction' because 'Transaction?' is nullable and 'Transaction' isn't.
 - 'Transaction' is from 'package:projetos2/models/transaction.dart' ('lib/models/transaction.dart').
        await _webClient.save(transactionCreated, password).catchError((e) {
        ^

Usando a solução do Fábio, acontece outro erro:

A non-null value must be returned since the return type 'Transaction' doesn't allow null.
 - 'Transaction' is from 'package:projetos2/models/transaction.dart' ('lib/models/transaction.dart').
  Future<Transaction> save(Transaction transaction, String password) async {

Como posso corrigir?

8 respostas

Olá, Lucas! Vou tentar te ajudar mostrando como fiz, acredito que no decorrer das aulas irei modificar para algo mais elegante.

Segue abaixo a imagem que você postou. Insira aqui a descrição dessa imagem para ajudar na acessibilidade

O problema é que se não entrar no IF do "Code 200" a função não retornará nada. A função precisa retornar algo. Para resolver essa questão, adicionei o mesmo conteúdo do "return" após o "throw", veja:

_throwHttpError(response.statusCode);
return Transaction.fromJson(jsonDecode(response.body));

Então, ficou assim:

Future<Transaction> save(Transaction transaction, String password) async {
    final String transactionJson = jsonEncode(transaction.toJson());

    final Response response = await client.post(Uri.parse(baseURL),
        headers: {
          'Content-type': 'application/json',
          'password': password,
        },
        body: transactionJson);

    if (response.statusCode == 200){
      return Transaction.fromJson(jsonDecode(response.body));
    }
    _throwHttpError(response.statusCode);
    return Transaction.fromJson(jsonDecode(response.body));
  }

  void _throwHttpError(int statusCode) => throw Exception(_statusCodeResponses[statusCode]);

  static final Map<int, String> _statusCodeResponses = {
    400 : 'there was an error submitting transaction',
    401 : 'authentication failed'
  };

Lucas, no vídeo seguinte ele realiza a implementação do throw HttpException para substituir o _throwHttpError. Desta forma, o problema é resolvido sem precisar utilizar o "return" extra que mencionei.

Fiz a implementação do throw HttpException da aula seguinte, mas agora tenho outro erro.

Na linha throw HttpException(_statusCodeResponses[response.statusCode]); aparece o erro "The argument type 'String?' can't be assigned to the parameter type 'String'."

O IntelliJ dá a dica de adicionar um Null check (!), mas mesmo assim continua com o mesmo erro.

Por favor, envie o código completo.

solução!

Sem visualizar o código, chutaria que você não colocou a interrogação "?" após a String na definição de chave/valor do Mapa: Map<int, String?>

  static final Map<int, String?> _statusCodeResponses = {
    400 : 'there was an error submitting transaction',
    401 : 'authentication failed',
    404 : 'page not found',
    409 : 'transaction always exists'
  };

Observe a classe HttpException com a "?" após o tipo String da variável message:

class HttpException implements Exception {
  final String? message;

  HttpException(this.message);


}
  String? _getMessage(int statuscode) {
    if (_statusCodeResponses.containsKey(statuscode)){
      return _statusCodeResponses[statuscode];
    }
    return 'Unknow error H.';
  }

Estou chamando assim:

throw HttpException(_getMessage(response.statusCode));

Não tinha colocado interrogação, mas ao adicionar, funcionou.

Está assim:

class TransactionWebClient {
  Future<List<Transaction>> findAll() async {
    final Response response = await get(baseUrl);
    final List<dynamic> decodedJson = jsonDecode(response.body);
    return decodedJson
        .map((dynamic json) => Transaction.fromJson(json))
        .toList();
  }

  Future<Transaction> save(Transaction transaction, String password) async {
    final String transactionJson = jsonEncode(transaction.toJson());

    final Response response = await client.post(baseUrl,
        headers: {'Content-type': 'application/json', 'password': password},
        body: transactionJson);


    if(response.statusCode == 200) {
      return Transaction.fromJson(jsonDecode(response.body));
    }
    throw HttpException(_statusCodeResponses[response.statusCode]);
  }

  static final Map<int, String> _statusCodeResponses = {
    400 :'There was an error submitting transaction.',
    401 : 'Authentication failed!'
  };
}

class HttpException implements Exception {
  final String? message;

  HttpException(this.message);
}

Que bom que funcionou! Por favor, coloque o tópico como concluído e vamos partir para a próxima ;D

Muito obrigado!