Passing null to NumberFormat.simpleCurrency in flutter app - flutter

I am using NumberFormat.simpleCurrency to format dollar amounts in my flutter app. It works great if trxns.contractPrice is not null. When it is null I get the following error:
The getter 'isNegative' was called on null.
Receiver: null
Tried calling: isNegative
Here is the code snippet:
TextSpan(
text:
'\nPrice: ${NumberFormat.simpleCurrency().format(trxns.contractPrice) ?? 'n/a'}\nStatus: ${trxns.trxnStatus ?? 'n/a'}',
style: TextStyle(
fontWeight: FontWeight.w900,
color: Colors.blueGrey),
)
I have not been able to find anything for this error. Can anyone please help me with how to deal with nulls?

First check that traxns value is not null, then check its property or method contractPrice is not null. Right now, you're getting null for one of those things and an exception is being thown by the format method from NumberFormat. Once possiable example is:
TextSpan(
text:'\nPrice: ${trxns!.contractPrice == null ? 'n/a' : NumberFormat.simpleCurrency().format(trxns.contractPrice)}\nStatus: ${trxns!.trxnStatus ?? 'n/a'}',
style: TextStyle(fontWeight: FontWeight.w900, color: Colors.blueGrey),
);

Have a null check for the contractPrice before format
Sample:
Text(
'\nPrice: ${(contractPrice != null) ? NumberFormat.simpleCurrency().format(contractPrice) : 'n/a'}',
)

Related

This Code wont run due to "Expected Identifier" and "Expected to find ":" " in flutter

child: Text(
title,
style: TextStyle(color : Colors.grey[700], decoration: _enabledMap[title] == true ? TextDecoration.lineThrough)
),
Hi there, I am new to coding and I need help, please can you show me where I'm going wrong
You are providing data only for _enabledMap[title] == true. But you also need to provide when data is false for ternary case. You can provide null if you don't like to pass any TextDecoration
decoration: _enabledMap[title] == true
? TextDecoration.lineThrough
: null
For more info, see the Dart docs on conditional expressions

How to Flutter test TextThemes

I need to test the following piece of code to basically check if trailingIconButton == null then a certain text theme should be applied.
Text(
type == TileType.org
? orgInfo!.name!
: type == TileType.user
? '${userInfo!.firstName!} ${userInfo!.lastName!}'
: option!.title,
style: type == TileType.org
? Theme.of(context).textTheme.headline5
: type == TileType.user
? Theme.of(context).textTheme.headline6
: option!.trailingIconButton == null
? Theme.of(context).textTheme.bodyText2
: Theme.of(context)
.textTheme
.headline5!
.copyWith(fontSize: 18),
key: const Key('trailingIconButton'),
),
what I wrote
testWidgets('Creating Custom List (giving custom options)', (tester) async {
await tester.pumpWidget(createCustomListTileUser(
option: Options(
icon: const Icon(Icons.add),
title: 'henlo',
subtitle: 'yesh',
trailingIconButton: null)));
final Text text =
tester.firstWidget(find.byKey(const Key('trailingIconButton')));
//equals bodyText2
expect(text.style!.getTextStyle(),
equals(Theme.of(MockBuildContext()).textTheme.bodyText2));
});
The problem is that you're using different contexts to get theme which results in different themes. In your application you probably have defined a Theme which is returned when you're using Theme.of(context) but that's not the case in your tests. When you're doing Theme.of(MockBuildContext()) You're getting different one.
So to solve this you need to wrap your widgets with a theme provider with the same theme used in your application. Then use this code to compare themes:
expect(
text.style!.getTextStyle(),
equals(Theme.of(
tester.element(find.byKey(const Key('trailingIconButton'))))
.textTheme
.bodyText2));

Is it possible to supply a default value to a Text widget?

As the question states, I would like to supply a default value to a Text Widget. I have four Text widgets. I use a variable in each Text Widget to display data. There is a chance that some data may not exist depending on the user and I would like to be able to default these Text Widgets to 0 if the value doesn't exist to prevent an error. Is this possible? Thanks!
Below is how it is currently.
Text(
'\$${quarter['data'][0].funds}',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold),
),
You can provide a default value using the ?? operator, which returns the expression on its left unless that expression’s value is null, in which case it evaluates and returns the expression on its right (and you might need to add question marks for conditional property access in case quarter['data'] and quarter['data'][0] are nullable):
Text(
'\$${quarter['data']?[0]?.funds ?? 0}',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
)
To safely access the funds at an index of the quarter['data'] list, you can create a helper method:
int fundsAt(int index) {
// This will return 0 if no element exists at the given index
return index >= 0 && index < quarter['data'].length
? quarter['data'][index].funds
: 0;
}
Here is the example of using fundsAt():
Text(
'\$${fundsAt(0)}',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
)
You can try something like this :
'\$${quarter['data'][0].funds ?? 0}'
You can try these:
If the value can be null, then you can try this:
Text(myNullableData ?? "Default value");
Text(myNullableData == null ? "" : "Default value");
The ?? operator use your value if it is not null. If yes, it will use the default value you want.
Otherwise if some data may not exist depending means that the variable can be just an empty string: '""', then you can use the ?: operator:
Text(myData == "" ? "Default value" : myData);

The getter title isnt defined for the type "TextTheme"

I just upgraded to flutter v2. I am getting the following error
title: Text("Foo", style: Theme
.of(context)
.textTheme
.title
.copyWith(fontWeight: FontWeight.bold, color: Colors.red),)),
Any suggestions on what the equivalent will be ?
In 2018 many text styles were renamed. The “title” style is now called “headline6”.
You can read more about migrating here: https://api.flutter.dev/flutter/material/TextTheme-class.html

Dropdown Menu based on List, A non-null String must be provided to a Text widget

I am trying to generate a list of dropdown options for my user. I have created a custom model to use and here it is:
class UserFontModel {
String fontFamily;
FontWeight fontWeight;
UserFontModel({this.fontFamily, this.fontWeight});
}
I then create an instance here:
List<UserFontModel> _fonts = [
UserFontModel(fontFamily: 'Bold', fontWeight: FontWeight.w700),
UserFontModel(fontFamily: 'Medium', fontWeight: FontWeight.w500),
UserFontModel(fontFamily: 'Regular', fontWeight: FontWeight.w400),
UserFontModel(fontFamily: 'Light', fontWeight: FontWeight.w300),
UserFontModel(fontFamily: 'Thin', fontWeight: FontWeight.w100),
];
I then create a dropdown menu with the items based on the above list:
new DropdownButton<String>(
hint: Text('Style'),
items: _fonts.map((fonts) => DropdownMenuItem<String> (
child: Container(
width: MediaQuery.of(context).size.width * 0.2,
child: Text(fonts.fontFamily, style: TextStyle(fontWeight: fonts.fontWeight),),
),
)).toList(),
onChanged: (String _) {
setState(() {
print(_);
});
},
),
But for some reason (probably a simple one that i'm missing), I can't work out why i'm getting the error:
A non-null String must be provided to a Text widget.
Any thoughts?
Well, my obvious thought is: post a minimal compilable example, with the full error message.
But another thought that might actually help you to find the mistake yourself is: don't make programming hard on yourself. You are human. Let the machine do the hard work, that is the way we should do this. You want to make sure you never accidentally have a null value in your models? Then write the model so a null value is not possible without your compiler telling you exactly where you failed at compile time:
class UserFontModel {
final String fontFamily;
final FontWeight fontWeight;
const UserFontModel({#required this.fontFamily, #required this.fontWeight})
: assert(fontFamily != null),
assert(fontWeight != null);
}
This class is not instatiable without both fontFamily and fontWeight given, it will warn you at runtime, if you gave one and it was null and it makes sure you cannot accidentally change the fields after they have been checked to be correct. The point here is: this is your compiler. the machine does the work for you. As it should be.
This will not fix your actual problem, but it should fix your problem of not finding your actual problem.