From 1ddea720130203021a815253e37ebe5c06845dd2 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 1 Mar 2024 18:35:56 +0600 Subject: [PATCH] fix: spotify sending double instead of int for documented endpoints --- lib/src/models/_models.g.dart | 73 +++++++++++++++-------------- lib/src/models/audio_analysis.dart | 10 ++-- lib/src/models/audio_feature.dart | 6 ++- lib/src/models/device.dart | 2 +- lib/src/models/episode.dart | 3 +- lib/src/models/error.dart | 1 + lib/src/models/paging.dart | 8 +++- lib/src/models/player.dart | 9 ++-- lib/src/models/recommendations.dart | 3 ++ lib/src/models/show.dart | 6 ++- lib/src/models/track.dart | 13 ++--- lib/src/spotify_base.dart | 7 +-- lib/src/utils.dart | 4 ++ 13 files changed, 86 insertions(+), 59 deletions(-) diff --git a/lib/src/models/_models.g.dart b/lib/src/models/_models.g.dart index 0d978f0..9d98461 100644 --- a/lib/src/models/_models.g.dart +++ b/lib/src/models/_models.g.dart @@ -388,16 +388,17 @@ TrackAudioAnalysis _$TrackAudioAnalysisFromJson(Map json) => ..loudness = (json['loudness'] as num?)?.toDouble() ..tempo = (json['tempo'] as num?)?.toDouble() ..tempoConfidence = (json['tempo_confidence'] as num?)?.toDouble() - ..key = json['key'] as int? + ..key = convertToIntIfDoubleValue(json['key']) ..keyConfidence = (json['key_confidence'] as num?)?.toDouble() - ..mode = json['mode'] as int? + ..mode = convertToIntIfDoubleValue(json['mode']) ..modeConfidence = (json['mode_confidence'] as num?)?.toDouble() - ..timeSignature = json['time_signature'] as int? + ..timeSignature = convertToIntIfDoubleValue(json['time_signature']) ..timeSignatureConfidence = (json['time_signature_confidence'] as num?)?.toDouble() - ..numSamples = json['num_samples'] as int? - ..analysisSampleRate = json['analysis_sample_rate'] as int? - ..analysisChannels = json['analysis_channels'] as int? + ..numSamples = convertToIntIfDoubleValue(json['num_samples']) + ..analysisSampleRate = + convertToIntIfDoubleValue(json['analysis_sample_rate']) + ..analysisChannels = convertToIntIfDoubleValue(json['analysis_channels']) ..endOfFadeIn = (json['end_of_fade_in'] as num?)?.toDouble() ..startOfFadeOut = (json['start_of_fade_out'] as num?)?.toDouble() ..synchString = json['synchstring'] as String? @@ -413,11 +414,11 @@ Section _$SectionFromJson(Map json) => Section() ..loudness = (json['loudness'] as num?)?.toDouble() ..tempo = (json['tempo'] as num?)?.toDouble() ..tempoConfidence = (json['tempo_confidence'] as num?)?.toDouble() - ..key = json['key'] as int? + ..key = convertToIntIfDoubleValue(json['key']) ..keyConfidence = (json['key_confidence'] as num?)?.toDouble() - ..mode = json['mode'] as int? + ..mode = convertToIntIfDoubleValue(json['mode']) ..modeConfidence = (json['mode_confidence'] as num?)?.toDouble() - ..timeSignature = json['time_signature'] as int? + ..timeSignature = convertToIntIfDoubleValue(json['time_signature']) ..timeSignatureConfidence = (json['time_signature_confidence'] as num?)?.toDouble() ..start = (json['start'] as num?)?.toDouble(); @@ -446,17 +447,17 @@ AudioFeature _$AudioFeatureFromJson(Map json) => AudioFeature() ..acousticness = (json['acousticness'] as num?)?.toDouble() ..analysisUrl = json['analysis_url'] as String? ..danceability = (json['danceability'] as num?)?.toDouble() - ..durationMs = json['duration_ms'] as int? + ..durationMs = convertToIntIfDoubleValue(json['duration_ms']) ..energy = (json['energy'] as num?)?.toDouble() ..id = json['id'] as String? ..instrumentalness = (json['instrumentalness'] as num?)?.toDouble() - ..key = json['key'] as int? + ..key = convertToIntIfDoubleValue(json['key']) ..liveness = (json['liveness'] as num?)?.toDouble() ..loudness = (json['loudness'] as num?)?.toDouble() - ..mode = json['mode'] as int? + ..mode = convertToIntIfDoubleValue(json['mode']) ..speechiness = (json['speechiness'] as num?)?.toDouble() ..tempo = (json['tempo'] as num?)?.toDouble() - ..timeSignature = json['time_signature'] as int? + ..timeSignature = convertToIntIfDoubleValue(json['time_signature']) ..trackHref = json['track_href'] as String? ..type = json['type'] as String? ..uri = json['uri'] as String? @@ -487,7 +488,7 @@ Device _$DeviceFromJson(Map json) => Device() ..name = json['name'] as String? ..type = $enumDecodeNullable(_$DeviceTypeEnumMap, json['type'], unknownValue: DeviceType.Unknown) - ..volumePercent = json['volume_percent'] as int?; + ..volumePercent = convertToIntIfDoubleValue(json['volume_percent']); const _$DeviceTypeEnumMap = { DeviceType.Computer: 'Computer', @@ -506,7 +507,7 @@ const _$DeviceTypeEnumMap = { }; SpotifyError _$SpotifyErrorFromJson(Map json) => SpotifyError() - ..status = json['status'] as int? + ..status = convertToIntIfDoubleValue(json['status']) ..message = json['message'] as String?; Followers _$FollowersFromJson(Map json) => Followers() @@ -521,17 +522,17 @@ Image _$ImageFromJson(Map json) => Image() Paging _$PagingFromJson(Map json) => Paging() ..href = json['href'] as String? ..itemsNative = itemsNativeFromJson(json['items'] as List) - ..limit = json['limit'] as int + ..limit = convertToIntIfDoubleValueWithoutNull(json['limit']) ..next = json['next'] as String? - ..offset = json['offset'] as int? + ..offset = convertToIntIfDoubleValue(json['offset']) ..previous = json['previous'] as String? - ..total = json['total'] as int; + ..total = convertToIntIfDoubleValueWithoutNull(json['total']); CursorPaging _$CursorPagingFromJson(Map json) => CursorPaging() ..href = json['href'] as String? ..itemsNative = itemsNativeFromJson(json['items'] as List) - ..limit = json['limit'] as int + ..limit = convertToIntIfDoubleValueWithoutNull(json['limit']) ..next = json['next'] as String? ..cursors = json['cursors'] == null ? null @@ -542,11 +543,11 @@ Cursor _$CursorFromJson(Map json) => PlaybackState _$PlaybackStateFromJson(Map json) => PlaybackState() - ..timestamp = json['timestamp'] as int? + ..timestamp = convertToIntIfDoubleValue(json['timestamp']) ..context = json['context'] == null ? null : PlayerContext.fromJson(json['context'] as Map) - ..progressMs = json['progress_ms'] as int? + ..progressMs = convertToIntIfDoubleValue(json['progress_ms']) ..item = json['item'] == null ? null : Track.fromJson(json['item'] as Map) @@ -695,11 +696,13 @@ Recommendations _$RecommendationsFromJson(Map json) => RecommendationsSeed _$RecommendationsSeedFromJson(Map json) => RecommendationsSeed() - ..afterFilteringSize = json['afterFilteringSize'] as int? - ..afterRelinkingSize = json['afterRelinkingSize'] as int? + ..afterFilteringSize = + convertToIntIfDoubleValue(json['afterFilteringSize']) + ..afterRelinkingSize = + convertToIntIfDoubleValue(json['afterRelinkingSize']) ..href = json['href'] as String? ..id = json['id'] as String? - ..initialPoolSize = json['initialPoolSize'] as int? + ..initialPoolSize = convertToIntIfDoubleValue(json['initialPoolSize']) ..type = json['type'] as String?; Show _$ShowFromJson(Map json) => Show() @@ -727,12 +730,14 @@ Show _$ShowFromJson(Map json) => Show() ..publisher = json['publisher'] as String? ..type = json['type'] as String? ..uri = json['uri'] as String? - ..totalEpisodes = json['total_episodes'] as int? ?? 0; + ..totalEpisodes = json['total_episodes'] == null + ? 0 + : convertToIntIfDoubleValue(json['total_episodes']); Episode _$EpisodeFromJson(Map json) => Episode() ..audioPreviewUrl = json['audio_preview_url'] as String? ..description = json['description'] as String? - ..durationMs = json['duration_ms'] as int? + ..durationMs = convertToIntIfDoubleValue(json['duration_ms']) ..explicit = json['explicit'] as bool? ..externalUrls = json['external_urls'] == null ? null @@ -758,7 +763,7 @@ Episode _$EpisodeFromJson(Map json) => Episode() EpisodeFull _$EpisodeFullFromJson(Map json) => EpisodeFull() ..audioPreviewUrl = json['audio_preview_url'] as String? ..description = json['description'] as String? - ..durationMs = json['duration_ms'] as int? + ..durationMs = convertToIntIfDoubleValue(json['duration_ms']) ..explicit = json['explicit'] as bool? ..externalUrls = json['external_urls'] == null ? null @@ -794,8 +799,8 @@ Track _$TrackFromJson(Map json) => Track() ..availableMarkets = (json['available_markets'] as List?) ?.map((e) => $enumDecode(_$MarketEnumMap, e)) .toList() - ..discNumber = json['disc_number'] as int? - ..durationMs = json['duration_ms'] as int? + ..discNumber = convertToIntIfDoubleValue(json['disc_number']) + ..durationMs = convertToIntIfDoubleValue(json['duration_ms']) ..explicit = json['explicit'] as bool? ..externalIds = json['external_ids'] == null ? null @@ -812,7 +817,7 @@ Track _$TrackFromJson(Map json) => Track() ..name = json['name'] as String? ..popularity = convertToIntIfDoubleValue(json['popularity']) ..previewUrl = json['preview_url'] as String? - ..trackNumber = json['track_number'] as int? + ..trackNumber = convertToIntIfDoubleValue(json['track_number']) ..type = json['type'] as String? ..uri = json['uri'] as String?; @@ -823,8 +828,8 @@ TrackSimple _$TrackSimpleFromJson(Map json) => TrackSimple() ..availableMarkets = (json['available_markets'] as List?) ?.map((e) => $enumDecode(_$MarketEnumMap, e)) .toList() - ..discNumber = json['disc_number'] as int? - ..durationMs = json['duration_ms'] as int? + ..discNumber = convertToIntIfDoubleValue(json['disc_number']) + ..durationMs = convertToIntIfDoubleValue(json['duration_ms']) ..explicit = json['explicit'] as bool? ..externalUrls = json['external_urls'] == null ? null @@ -837,7 +842,7 @@ TrackSimple _$TrackSimpleFromJson(Map json) => TrackSimple() : TrackLink.fromJson(json['linked_from'] as Map) ..name = json['name'] as String? ..previewUrl = json['preview_url'] as String? - ..trackNumber = json['track_number'] as int? + ..trackNumber = convertToIntIfDoubleValue(json['track_number']) ..type = json['type'] as String? ..uri = json['uri'] as String?; @@ -860,7 +865,7 @@ TrackLink _$TrackLinkFromJson(Map json) => TrackLink() TracksLink _$TracksLinkFromJson(Map json) => TracksLink() ..href = json['href'] as String? - ..total = json['total'] as int?; + ..total = convertToIntIfDoubleValue(json['total']); User _$UserFromJson(Map json) => User() ..birthdate = json['birthdate'] as String? diff --git a/lib/src/models/audio_analysis.dart b/lib/src/models/audio_analysis.dart index 66505a0..d8cb8ec 100644 --- a/lib/src/models/audio_analysis.dart +++ b/lib/src/models/audio_analysis.dart @@ -49,6 +49,7 @@ abstract class _Section { /// The estimated overall key of the section. The values in this field /// ranging from `0 to `11` mapping to pitches using standard Pitch Class notation /// (E.g. `0 = C`, `1 = C♯/D♭`, `2 = D`, and so on). If no key was detected, the value is `-1`. + @JsonKey(fromJson: convertToIntIfDoubleValue) int? key; /// The confidence, from 0.0 to 1.0, of the reliability of the key. @@ -62,6 +63,7 @@ abstract class _Section { /// Note that the major key (e.g. C major) could more likely be confused /// with the minor key at `3` semitones lower (e.g. A minor) as both /// keys carry the same pitches. + @JsonKey(fromJson: convertToIntIfDoubleValue) int? mode; /// The confidence, from `0.0` to `1.0`, of the reliability of the mode. @@ -73,7 +75,7 @@ abstract class _Section { /// how many beats are in each bar (or measure). /// The time signature ranges from `3` to `7` indicating time signatures /// of “3/4”, to “7/4”. - @JsonKey(name: 'time_signature') + @JsonKey(name: 'time_signature', fromJson: convertToIntIfDoubleValue) int? timeSignature; /// The confidence, from `0.0` to `1.0`, of the reliability of the @@ -93,16 +95,16 @@ class TrackAudioAnalysis extends _Section { /// The exact number of audio samples analyzed from this track. /// See also [analysisSampleRate]. - @JsonKey(name: 'num_samples') + @JsonKey(name: 'num_samples', fromJson: convertToIntIfDoubleValue) int? numSamples; /// The sample rate used to decode and analyze this track. /// /// May differ from the actual sample rate of this track available on Spotify. - @JsonKey(name: 'analysis_sample_rate') + @JsonKey(name: 'analysis_sample_rate', fromJson: convertToIntIfDoubleValue) int? analysisSampleRate; - @JsonKey(name: 'analysis_channels') + @JsonKey(name: 'analysis_channels', fromJson: convertToIntIfDoubleValue) int? analysisChannels; /// The time, in seconds, at which the track's fade-in period ends. diff --git a/lib/src/models/audio_feature.dart b/lib/src/models/audio_feature.dart index 07fea95..b28a02f 100644 --- a/lib/src/models/audio_feature.dart +++ b/lib/src/models/audio_feature.dart @@ -27,7 +27,7 @@ class AudioFeature extends Object { double? danceability; /// The track length in milliseconds. - @JsonKey(name: 'duration_ms') + @JsonKey(name: 'duration_ms', fromJson: convertToIntIfDoubleValue) int? durationMs; /// The track length @@ -55,6 +55,7 @@ class AudioFeature extends Object { /// The key the track is in. Integers map to pitches using standard Pitch /// Class notation. E.g. `0 = C`, `1 = C♯/D♭`, `2 = D`, and so on. + @JsonKey(fromJson: convertToIntIfDoubleValue) int? key; /// Detects the presence of an audience in the recording. Higher liveness @@ -72,6 +73,7 @@ class AudioFeature extends Object { /// Mode indicates the modality (major or minor) of a track, the type of scale /// from which its melodic content is derived. Major is represented by 1 and /// minor is `0`. + @JsonKey(fromJson: convertToIntIfDoubleValue) int? mode; /// Speechiness detects the presence of spoken words in a track. The more @@ -91,7 +93,7 @@ class AudioFeature extends Object { /// An estimated overall time signature of a track. The time signature (meter) /// is a notational convention to specify how many beats are in each bar (or /// measure). - @JsonKey(name: 'time_signature') + @JsonKey(name: 'time_signature', fromJson: convertToIntIfDoubleValue) int? timeSignature; /// A link to the Web API endpoint providing full details of the track. diff --git a/lib/src/models/device.dart b/lib/src/models/device.dart index ab561cb..e7ab380 100644 --- a/lib/src/models/device.dart +++ b/lib/src/models/device.dart @@ -38,7 +38,7 @@ class Device extends Object { DeviceType? type; /// The current volume in percent. This may be `null`. - @JsonKey(name: 'volume_percent') + @JsonKey(name: 'volume_percent', fromJson: convertToIntIfDoubleValue) int? volumePercent; } diff --git a/lib/src/models/episode.dart b/lib/src/models/episode.dart index 3f85d5b..5de755e 100644 --- a/lib/src/models/episode.dart +++ b/lib/src/models/episode.dart @@ -18,7 +18,7 @@ class Episode extends Object { String? description; /// The episode length in milliseconds. - @JsonKey(name: 'duration_ms') + @JsonKey(name: 'duration_ms', fromJson: convertToIntIfDoubleValue) int? durationMs; /// Whether or not the episode has explicit content @@ -80,7 +80,6 @@ class Episode extends Object { /// Json representation of an episode with information about its show @JsonSerializable(createToJson: false) class EpisodeFull extends Episode { - EpisodeFull(); Show? show; diff --git a/lib/src/models/error.dart b/lib/src/models/error.dart index 9a02e6e..ed07a5f 100644 --- a/lib/src/models/error.dart +++ b/lib/src/models/error.dart @@ -13,6 +13,7 @@ class SpotifyError extends Object { /// The HTTP status code (also returned in the response header; see Response /// Status Codes for more information). + @JsonKey(fromJson: convertToIntIfDoubleValue) int? status; /// A short description of the cause of the error. diff --git a/lib/src/models/paging.dart b/lib/src/models/paging.dart index c3cda9e..5c4eb6c 100644 --- a/lib/src/models/paging.dart +++ b/lib/src/models/paging.dart @@ -25,11 +25,15 @@ class BasePaging extends Object { /// Note this is the raw JSON value. Use a [Page]'s [Page.items] to get the /// requested data as a deserialized list. @JsonKey( - name: 'items', fromJson: itemsNativeFromJson, toJson: itemsNativeToJson) + name: 'items', + fromJson: itemsNativeFromJson, + toJson: itemsNativeToJson, + ) Iterable? itemsNative; /// The maximum number of items in the response (as set in the query or by /// default). + @JsonKey(fromJson: convertToIntIfDoubleValueWithoutNull) int limit = 20; /// URL to the next page of items. (`null` if none) @@ -44,12 +48,14 @@ class Paging extends BasePaging { factory Paging.fromJson(Map json) => _$PagingFromJson(json); /// The offset of the items returned (as set in the query or by default). + @JsonKey(fromJson: convertToIntIfDoubleValue) int? offset; /// URL to the previous page of items. (null if none) String? previous; /// The total number of items available to return. + @JsonKey(fromJson: convertToIntIfDoubleValueWithoutNull) int total = 0; } diff --git a/lib/src/models/player.dart b/lib/src/models/player.dart index 335f963..099f3bf 100644 --- a/lib/src/models/player.dart +++ b/lib/src/models/player.dart @@ -12,13 +12,14 @@ class PlaybackState extends Object { _$PlaybackStateFromJson(json); /// Unix Millisecond Timestamp when data was fetched + @JsonKey(fromJson: convertToIntIfDoubleValue) int? timestamp; /// A [PlayerContext] Object. Can be `null`. PlayerContext? context; /// Progress into the currently playing track. Can be `null`. - @JsonKey(name: 'progress_ms') + @JsonKey(name: 'progress_ms', fromJson: convertToIntIfDoubleValue) int? progressMs; /// The currently playing track. Can be `null`. @@ -123,7 +124,6 @@ abstract class StartOrResumeOptions extends Object { @JsonSerializable(createFactory: false) class StartWithContextOptions extends StartOrResumeOptions { - StartWithContextOptions({this.contextUri, this.offset}); /// Optional. Spotify URI of the context to play. Valid contexts are albums, @@ -146,7 +146,6 @@ class StartWithContextOptions extends StartOrResumeOptions { @JsonSerializable(createFactory: false) class StartWithUrisOptions extends StartOrResumeOptions { - StartWithUrisOptions({this.uris, this.positionMs}); /// Optional. A JSON array of the Spotify track URIs to play. @@ -161,12 +160,11 @@ class StartWithUrisOptions extends StartOrResumeOptions { List? uris; /// Optional. The position in milliseconds to start playback. - @JsonKey(name: 'position_ms') + @JsonKey(name: 'position_ms', fromJson: convertToIntIfDoubleValue) int? positionMs; @override Map toJson() => _$StartWithUrisOptionsToJson(this); - } abstract class Offset { @@ -188,6 +186,7 @@ class UriOffset extends Offset { /// "position" is zero based and can’t be negative. @JsonSerializable(createFactory: false) class PositionOffset extends Offset { + @JsonKey(fromJson: convertToIntIfDoubleValueWithoutNull) final int position; PositionOffset(this.position) { diff --git a/lib/src/models/recommendations.dart b/lib/src/models/recommendations.dart index 044d52b..2def62b 100644 --- a/lib/src/models/recommendations.dart +++ b/lib/src/models/recommendations.dart @@ -26,9 +26,11 @@ class RecommendationsSeed extends Object { /// The number of tracks available after min_* and max_* filters /// have been applied. + @JsonKey(fromJson: convertToIntIfDoubleValue) int? afterFilteringSize; /// The number of tracks available after relinking for regional availability. + @JsonKey(fromJson: convertToIntIfDoubleValue) int? afterRelinkingSize; /// A link to the full track or artist data for this seed. @@ -43,6 +45,7 @@ class RecommendationsSeed extends Object { String? id; /// The number of recommended tracks available for this seed. + @JsonKey(fromJson: convertToIntIfDoubleValue) int? initialPoolSize; /// The entity type of this seed. One of artist, track or genre. diff --git a/lib/src/models/show.dart b/lib/src/models/show.dart index 329d335..ce96a7a 100644 --- a/lib/src/models/show.dart +++ b/lib/src/models/show.dart @@ -61,7 +61,11 @@ class Show { String? uri; /// The number of total episodes in this show - @JsonKey(name: 'total_episodes', defaultValue: 0) + @JsonKey( + name: 'total_episodes', + defaultValue: 0, + fromJson: convertToIntIfDoubleValue, + ) int? totalEpisodes; factory Show.fromJson(Map json) => _$ShowFromJson(json); diff --git a/lib/src/models/track.dart b/lib/src/models/track.dart index 2a02b4e..8db62b2 100644 --- a/lib/src/models/track.dart +++ b/lib/src/models/track.dart @@ -27,12 +27,12 @@ class Track extends Object implements TrackSimple { /// The disc number /// (usually `1` unless the album consists of more than one disc) - @JsonKey(name: 'disc_number') + @JsonKey(name: 'disc_number', fromJson: convertToIntIfDoubleValue) @override int? discNumber; /// The track length in milliseconds. - @JsonKey(name: 'duration_ms') + @JsonKey(name: 'duration_ms', fromJson: convertToIntIfDoubleValue) @override int? durationMs; @@ -106,7 +106,7 @@ class Track extends Object implements TrackSimple { /// The number of the track. If an album has several discs, the track number /// is the number on the specified disc. - @JsonKey(name: 'track_number') + @JsonKey(name: 'track_number', fromJson: convertToIntIfDoubleValue) @override int? trackNumber; @@ -138,11 +138,11 @@ class TrackSimple extends Object { /// The disc number /// (usually `1` unless the album consists of more than one disc) - @JsonKey(name: 'disc_number') + @JsonKey(name: 'disc_number', fromJson: convertToIntIfDoubleValue) int? discNumber; /// The track length in milliseconds. - @JsonKey(name: 'duration_ms') + @JsonKey(name: 'duration_ms', fromJson: convertToIntIfDoubleValue) int? durationMs; /// The track length @@ -185,7 +185,7 @@ class TrackSimple extends Object { /// The number of the track. If an album has several discs, the track number /// is the number on the specified disc. - @JsonKey(name: 'track_number') + @JsonKey(name: 'track_number', fromJson: convertToIntIfDoubleValue) int? trackNumber; /// The object type: "track". @@ -247,5 +247,6 @@ class TracksLink extends Object { String? href; /// Total number of tracks in the playlist + @JsonKey(fromJson: convertToIntIfDoubleValue) int? total; } diff --git a/lib/src/spotify_base.dart b/lib/src/spotify_base.dart index 473134d..fcfa179 100644 --- a/lib/src/spotify_base.dart +++ b/lib/src/spotify_base.dart @@ -159,7 +159,8 @@ abstract class SpotifyApiBase { } /// Expands shortened spotify [url] - Future expandLink(String url) async => _streamedHeadImpl(url, const {}); + Future expandLink(String url) async => + _streamedHeadImpl(url, const {}); Future _get(String path) { return _getImpl('$_baseUrl/$path', const {}); @@ -225,13 +226,13 @@ abstract class SpotifyApiBase { } try { var response = await request(); - + // distinguish between url redirect responses and body responses // note, that any response that also contains a redirect url // will be chosen instead of its body contents // FIXME: in future releases of http2, the url is a part of the [http.Response] type if (response case http.BaseResponseWithUrl(:final url)) { - return url.toString(); + return url.toString(); } return handleResponseWithBody(response as http.Response); } on ApiRateException catch (ex) { diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 544f27a..3916273 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -27,3 +27,7 @@ int? convertToIntIfDoubleValue(dynamic jsonValue) { return null; } } + +int convertToIntIfDoubleValueWithoutNull(dynamic jsonValue) { + return convertToIntIfDoubleValue(jsonValue) ?? 0; +}