Pipes feature enables you to separate value conversion/transformation from the UI code in a convenient way.
For example, one of the most useful pipe is translate:
<Text text="ctrl.greatingText | translate" />Result:
Text(_pipeProvider.transform(context, "translate", ctrl.greatingText, []))To create the translate pipe extend the Pipe class and override the transform & name:
class MyTranslatePipe extends Pipe {
String get name => 'translate'; // unique name
dynamic transform(BuildContext context, value, args) {
// write your own logic...
// AppLocalizations class generated by this extension if you have JSON files inside lib/i18n folder.
return AppLocalizations.of(context).getTranslation(value) ?? '';
}
}Then register your pipe in the main file:
PipeProvider pipeProvider = new PipeProvider();
pipeProvider.register(new MyTranslatePipe());
runApp(
MultiProvider(
providers: [
Provider<PipeProvider>(builder: (_) => pipeProvider)
],
...
)
)<Text text="ctrl.greatingTextStream | stream" />Result:
StreamBuilder(
initialData: null,
stream: ctrl.greatingTextStream,
builder: (BuildContext context, textSnapshot) {
final textValue = textSnapshot.data;
if (textValue == null) {
return Container(height: 0, width: 0);
}
return Text(
textValue
);
}
);If you want to add initialData you can pass it as parameter:
<Text text="ctrl.greatingTextStream | stream:'Please wait...'" />Result:
StreamBuilder(
initialData: 'Please wait...',
stream: ctrl.greatingTextStream,
builder: (BuildContext context, textSnapshot) {
final textValue = textSnapshot.data;
if (textValue == null) {
return Container(height: 0, width: 0);
}
return Text(
textValue
);
}
);Or if you have a BehaviorSubject you can pass its value as initialData parameter:
<Text text="ctrl.greatingTextBehaviorSubject | stream:ctrl.greatingTextBehaviorSubject.value" />This is the same as stream but used with BehaviorSubject and add its value to the initialValue of StreamBuilder, to simplify last example can be written:
<Text text="ctrl.greatingTextBehaviorSubject | behavior" /><Text text="ctrl.greatingTextFuture | future" />Result:
FutureBuilder(
future: ctrl.greatingTextFuture,
builder: (BuildContext context, textSnapshot) {
final textValue = textSnapshot.data;
if (textValue == null) {
return Container(height: 0, width: 0);
}
return Text(
textValue
);
}
);NOTE You can't use stream, behavior or future pipe for a property of non-widget element (e.g. InputDecoration), because StreamBuilder and FutureBuilder can only returns of Widget type.
<Container width="50 | widthPercent" height="50 | widthPercent" />You can use multiple pipes with (braces):
<Text text="'${(ctrl.greatingText | translate)}: ${(ctrl.counterStream | stream)}'" />
<!-- or -->
<Text text="(ctrl.greatingText | translate) + (ctrl.anotherTextStream | stream)" />You also can use pipes chaining:
<Text text="ctrl.greatingTextStream | stream | translate" />NOTE You can't use multi-chained stream or future e.g. text="streamThatReturnsStream | stream | stream" or text="textStream | stream | anotherPipe | stream". only one stream/future per chain, but you can, of course, use grouped pipes and each group has one stream or future.