How to return and persist the null in a factory constructor?
I have a problem with the migration to null-safety of flutter, I know that in a factory it should no longer return null
so I return throw ArgumentError("")
, however in my services I bring the value of canvas as null and that is where it sends the error, but what I want is to continue the application and leave that value as null.
To explain it better; I have two models, ModelA has a variable called canva
of type ModelB. When I send a data mapping to ModelA, from the server the variable canva
arrives null, so it enters a condition and gives an error.
ModelA :
class ModelA extends A {
ModelA ({
required ModelB? background,
required ModelB? canvas,
}) : super(
background,
canvas,
);
factory ModelA.fromMap(Map<String, dynamic>? map) {
if (map == null) throw ArgumentError('ModelA map must not be null');
return ModelA(
background: ModelB.fromMap(map['background']), // go in with not-null service value
canvas: ModelB.fromMap(map['canvas']), // go in with null service value
);
}
}
ModelB :
class ModelB extends B {
ModelB({
String? content,
}) : super(
content;
);
factory ModelB.fromMap(Map<String, dynamic>? map) {
// * before the migration null-safety
// if (map == null) return null
if (map == null) throw ArgumentError('ModelB map must not be null'); // enter here (error)
return ModelB(
content: map['content'],
);
}
}
After the error, I enter my application without any problem, but it doesn't run any more my function...
This is where I do the programming to save and return my complete ModelA.
final someList = List<ModelA>.from(
listFromServer.where((i) {
return (i['someType'] == 1));
}).map(
(i) {
print("enter here");
final isBackOrCan = i['background'] ?? i['canvas'];
if (isBackOrCan != null) {
newListModelB
.add(ModelB.fromMap(isBackOrCan));
}
return ModelA.fromMap(i); // enter here the map background not null and also the canva null
},
),
);
[ ... more code that i want to continue ...]
} catch (e) {
print(e); // the message
throw CacheException();
}
Error :
If you want to preserve the old behavior of returning null
, just use a static
method instead of a factory
constructor. (factory
constructors provide almost no advantages to static
methods anyway.) That would be the simplest and most straightforward fix.
But if you really want to disallow null
, then ModelA.fromMap
and ModelB.fromMap
should require map
to be non-nullable in the first place, and then you would need to proceed up the call chain to make callers check for null
values. In your case:
class ModelA extends A {
ModelA({
required ModelB? background,
required ModelB? canvas,
}) : super(
background,
canvas,
);
factory ModelA.fromMap(Map<String, dynamic> map) {
var background = map['background'];
var canvas = map['canvas'];
return ModelA(
background: background == null
? null
: ModelB.fromMap(background), // go in with not-null service value
canvas: canvas == null
? null
: ModelB.fromMap(canvas), // go in with null service value
);
}
}