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.