Flutter apply condition on text widget if data isnt available - flutter

I am showing data in text widget like this
Text(
posts[position]['OrderDetailModifiers'][0]['ModifierName'].toString() ?? 'N/A',
style: TextStyle(
fontFamily: 'SFPROBOLD',
fontSize: 13, color: Colors.grey),
),
Issue is some time posts[position]['OrderDetailModifiers'] is null
right now its look like this
"OrderDetailModifiers": [
{
"ModifierName": "Single",
}
]
But some time its look like
"OrderDetailModifiers": [
]
Need to know how can I apply condition in my text widget if its null or not available so don't show text widget.

You can make if statement in your widget tree.
if (posts[position]['OrderDetailModifiers'].isNotEmpty)
Text(
posts[position]['OrderDetailModifiers'][0]['ModifierName'].toString(),
...
),

You can simply check the length and then show
Text(
posts[position]['OrderDetailModifiers'].length>0?posts[position]['OrderDetailModifiers'][0]['ModifierName'].toString(): 'N/A',
style: TextStyle(
fontFamily: 'SFPROBOLD',
fontSize: 13, color: Colors.grey),
),

Try using null-aware operators like this:
void main() {
printFirstModifierName(data); // Azerty
printFirstModifierName([]); // N/A
printFirstModifierName(null); // N/A
}
void printFirstModifierName(List<Map<String, dynamic>> data) {
print((data?.firstOrNull ?? const {})['ModifierName']?.toString() ?? 'N/A');
}
extension ListX<T> on List<T> {
T get firstOrNull => isEmpty ? null : first;
}
final data = [
{ 'ModifierName': 'Azerty' },
{ 'ModifierName': 'Qwerty' },
{ 'ModifierName': 'Tyuiop' },
];

Related

How to style my text widget dynamically in flutter

I am new to flutter and I have an issue to change text style dynamically.
I fetch data from firestore database in map like this
Map data = {"amount": "", "type": ""}
Example data1
data = { "amount": "3000", "type": "income" }
Example data2
data = { "amount": "3000", "type": "expense" }
I want to print this data in text widget like
Text('$ : ${data['amount']', style: $data['type'])"
my style.dart
final textStyle income = TextStyle {
color: Colors.blue,
fontSize: 24,
}
final textStyle expense = TextStyle {
color: Colors.red,
fontSize: 24
}
Can anyone suggest how I can do that?
You can do a condition check to change based on type like
Text('${data['amount']}', style: data['type'] == "expense" ? TextStyle(fontSize: 20, color: Colors.red) : TextStyle(fontSize: 12, color: Colors.blue)),

The argument type 'String?' can't be assigned to the parameter type 'String' because 'String?' is nullable and 'String' isn't in Text widget

I am trying to display the name and email of the person when he logs in to the profile screen using Getx
Column(
children: [
Text(
controller.userModel!.name,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Kprimarycolor,
),
),
Text(
controller.userModel!.email,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Kprimarycolor,
),
),
],
),
],
but this error keep showing Error in vs code
and Error in terminal
the related code to name and email is
class UserModel {
late String? userId, email, name, pic;
UserModel({
required this.userId,
required this.email,
required this.name,
required this.pic,
});
UserModel.fromJson(Map<dynamic, dynamic> map) {
userId = map['userId'];
email = map['email'];
name = map['name'];
pic = map['pic'];
}
toJson() {
return {
'userId': userId,
'email': email,
'name': name,
'pic': pic,
};
}
}
I tried to add .toString() and as String but the error keeps showing after debugging
Column(
children: [
Text(
controller.userModel!.name!,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Kprimarycolor,
),
),
Text(
controller.userModel!.email!,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Kprimarycolor,
),
),
],
),
],
I added '!' character, it should work.
In your model, late String? userId, email, name, pic; and #Salih Can answer will be work.
Here, String? means string can accept null value. But Text widget don't accept null value. You need to use bang operator ! to handle it and by adding ! means this value is not null anymore. A better practice would be checking if it is null or not, then assign on Text. It can be
Text(myVal==null? "defalut value": myVal)
Text(myVal??"default Value")
if(myval!=null) Text(myVal) and it will render only if string is not null.

Can a single TextField in flutter have variable line height?

I'm implementing a simple rich text editor that renders text with a text editing controller that recognises basic markdown syntax, I'll link some code down below.
Everything works fine, the only problem I'm having is when a text style requires a bigger line height, for instance an # h1 that should be rendered as a title and therefore require a bigger line height overlaps over the previous line, as you can see in the screenshot below.
I've not been able so far to make the line height in a TextView variable based on the style of the text that is being displayed, is such thing even achievable in a Flutter TextView?
Here's a snippet of my text editing controller and a screenshot detailing my problem.
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class AddNotePage extends StatelessWidget {
final TextEditingController _controller = MarkdownTextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add Note'),
),
body: GestureDetector(
onVerticalDragDown: (_) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: TextField(
style: defaultTextStyle,
controller: _controller,
decoration: InputDecoration(
hintText: "Insert your message",
border: UnderlineInputBorder(
borderSide: BorderSide.none,
),
),
scrollPadding: EdgeInsets.all(20.0),
keyboardType: TextInputType.multiline,
maxLines: null,
),
),
],
),
),
);
}
}
const Map<String, TextStyle> defaultMarkdownStyleMap = {
r'^# .*?$': TextStyle(
fontWeight: FontWeight.bold,
fontSize: 50,
),
r'^## .*?$': TextStyle(
fontWeight: FontWeight.bold,
fontSize: 40,
),
r'^### .*?$': TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
),
r'__(.*?)\__': TextStyle(fontStyle: FontStyle.italic, fontSize: 20),
r'~~(.*?)~~': TextStyle(decoration: TextDecoration.lineThrough, fontSize: 20),
r'\*\*(.*?)\*\*': TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
};
const TextStyle defaultTextStyle = TextStyle(fontSize: 20);
class MarkdownTextEditingController extends TextEditingController {
final Map<String, TextStyle> styleMap;
final Pattern pattern;
MarkdownTextEditingController({this.styleMap = defaultMarkdownStyleMap})
: pattern = RegExp(
styleMap.keys.map((key) {
return key;
}).join('|'),
multiLine: true);
#override
TextSpan buildTextSpan(
{required BuildContext context,
TextStyle? style,
required bool withComposing}) {
final List<InlineSpan> children = [];
text.splitMapJoin(
pattern,
onMatch: (Match match) {
TextStyle? markdownStyle = styleMap[styleMap.keys.firstWhere(
(e) {
return RegExp(e).hasMatch(match[0]!);
},
)];
children.add(TextSpan(
text: match[0],
style: style!.merge(markdownStyle),
));
return "";
},
onNonMatch: (String text) {
children
.add(TextSpan(text: text, style: style!.merge(defaultTextStyle)));
return "";
},
);
return TextSpan(style: style, children: children);
}
}
I've found a solution.
All I needed to do was to play around with the strutStyle property of the TextField.
As the documentation states:
The strut style used for the vertical layout.
StrutStyle is used to establish a predictable vertical layout. Since
fonts may vary depending on user input and due to font fallback,
StrutStyle.forceStrutHeight is enabled by default to lock all lines to
the height of the base TextStyle, provided by style. This ensures the
typed text fits within the allotted space.

Flutter : How to add dynamic list to Dropdown ? Edited #2

I have list received from previous page and want to put it in Dropdown menu ,the list is contain many items :
List myItems = [];
getItem() {
categories.forEach((item) {
print(item.name); //----------the print result is correct
myItems.add(item.name);
});
return myItems;
}
I put it thus in Dropdown menu :
DropdownButton(
onChanged: (v) {
_selected = prod.get_cat(v);
},
elevation: 16,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 22),
underline: SizedBox(),
value: _selected,
items:
getItem().map<DropdownMenuItem<String>>((value) {
return DropdownMenuItem<String>(
value: value[id],
child: Center(child: Text(value[name])),
);
}).toList(),
)
the value change in provider :
get_cat(id) {
_selectedValue = id;
return _selectedValue;
}
I get error :
A non-null String must be provided to a Text widget. 'package:flutter/src/widgets/text.dart': Failed assertion: line 370 pos 10: 'data != null'
How can I solve this?
The identifiers should be strings.
value: value['id'],
child: Center(child: Text(value['name'])),

Update flutter font with a function

I want to update the displaying font in flutter using a function.I've tried with following method but it won't update.I can't find the problem.
Function
_fontselect(String ){
if (_character==1) {
return "Font";
} else{
return "Font2";
}
}
context
Center(child: Text(text,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily:_fontselect(String),
fontWeight: FontWeight.bold,
fontSize: 28.0,
color: Colors.red)
),
),
Use Ternary Operator within the fontFamily itself.
Center(child: Text(text,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: _character==1 ? "Font" : "Font2",
fontWeight: FontWeight.bold,
fontSize: 28.0,
color: Colors.red)
),
),
Your function needs a String variable to use inside of the function.
_fontselect(String character){
if (character==1) {
return "Font";
} else{
return "Font2";
}
}
Also it looks like character is an int but you are sending a String over to the function you should call the function with an int if this makes more sense.