question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[dart-dio-next][DISCUSSION] non-nullable model properties without a default value should be treated as required by default

See original GitHub issue

currently when generating model types the property’s nullability is determined by 2 things

  1. the property must be nullable
  2. the property must be required

for example, this model:

"PaymentInfo": {
  "type": "object",
  "properties": {
    "redirectUrl": {
      "type": "string",
      "nullable": true
    },
    "invoiceId": {
      "type": "integer",
      "format": "int64"
    }
  },
  "additionalProperties": false
}

is generated as:

import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';

part 'payment_info.g.dart';

/// PaymentInfo
///
/// Properties:
/// * [redirectUrl]
/// * [invoiceId]
abstract class PaymentInfo implements Built<PaymentInfo, PaymentInfoBuilder> {
  @BuiltValueField(wireName: r'redirectUrl')
  String? get redirectUrl;

  @BuiltValueField(wireName: r'invoiceId')
  int? get invoiceId;

  PaymentInfo._();

  @BuiltValueHook(initializeBuilder: true)
  static void _defaults(PaymentInfoBuilder b) => b;

  factory PaymentInfo([void updates(PaymentInfoBuilder b)]) = _$PaymentInfo;

  @BuiltValueSerializer(custom: true)
  static Serializer<PaymentInfo> get serializer => _$PaymentInfoSerializer();
}
//stripped serializer for simplicty

as you can see, the invoiceId here is marked as nullable in the generated object, this is counter intuitive and leads to spamming ! everywhere in code

this problem is due to a limitation in built value, see:

  1. https://github.com/google/built_value.dart/issues/1050
  2. https://github.com/google/built_value.dart/issues/912

my suggestion is to provide an alternative factory method in addition to the built-in builder e.g.

abstract class PaymentInfo implements Built<PaymentInfo, PaymentInfoBuilder> {
  @BuiltValueField(wireName: r'redirectUrl')
  String? get redirectUrl;

  @BuiltValueField(wireName: r'invoiceId')
  int get invoiceId;

  factory PaymentInfo.strict({
    //parameters defined to reflict the matching OAS3 specification
    String? redirectUrl,
    required int invoiceId,
  }) {
    //delegate the construction to the built-in builder
    final resB = PaymentInfoBuilder();
    resB.redirectUrl = redirectUrl;
    resB.invoiceId = invoiceId;
    return resB.build();
  }

  PaymentInfo._();

  @BuiltValueHook(initializeBuilder: true)
  static void _defaults(PaymentInfoBuilder b) => b;

  factory PaymentInfo([void updates(PaymentInfoBuilder b)]) = _$PaymentInfo;

  @BuiltValueSerializer(custom: true)
  static Serializer<PaymentInfo> get serializer => _$PaymentInfoSerializer();
}

the signatures would then be handled as such:

  1. non-nullable and required model property
    • non-nullable class property
    • required non-nullable factory parameter if there is no default value provided
    • non-nullable factory parameter if there is a default value provided
  2. nullable and required model properties
    • nullable class property
    • required nullable factory parameter if there is no default value provided
    • nullable factory parameter if there is a default value provided
  3. non-nullable and non-required model properties is this allowed ??
    • non-nullable class property
    • required non-nullable factory parameter if there is no default value provided
    • non-nullable factory parameter if there is a default value provided
  4. nullable and non-required model properties
    • nullable class property
    • nullable factory parameter if there is no default value provided
    • nullable factory parameter if there is a default value provided

what are your opinions on this?

@jaumard (2018/09) @josh-burton (2019/12) @amondnet (2019/12) @sbu-WBT (2020/12) @kuhnroyal (2020/12) @agilob (2020/12)

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
noordawodcommented, Dec 18, 2021

My 2 cents: “non-nullable model properties should be treated as required by default” -> should be instead: “non-nullable model properties WITHOUT A DEFAULT VALUE should be treated as required”. If it has a default value, then it shouldn’t be required unless the model says so.

0reactions
ahmednfwelacommented, Nov 29, 2021

@wing328 what do you think should be done here?

Read more comments on GitHub >

github_iconTop Results From Across the Web

You are trying to add a non-nullable field 'name' to comment ...
you need to set a default value to populate the previous rows, add: default="" to name attribute like this: name = models.
Read more >
Non-nullable Property Must Contain a Non-null Value in .NET 6
Non-nullable property must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
Read more >
MySQL 8.0 Reference Manual :: 11.6 Data Type Default Values
The default value specified in a DEFAULT clause can be a literal constant or an expression. With one exception, enclose expression default values...
Read more >
Understanding null safety - Dart
A deep dive into Dart language and library changes related to null safety. ... class permits the value null . We've made all...
Read more >
Dart Null Safety: The Ultimate Guide to Non-Nullable Types
But if all types are now non-nullable by default, how can we declare nullable ... to a non-nullable value, and the null-aware operator...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found