Skip to content

Latest commit

 

History

History
145 lines (120 loc) · 3.63 KB

pipes.md

File metadata and controls

145 lines (120 loc) · 3.63 KB

Pipes

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)
      ],
      ...
    )
  )

Built-in pipes

1. stream

<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" />

2. behavior

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" />

3. future

<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.

4. widthPercent & heightPercent

<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.