FlutterArtist Block External Shelf Event ex1
In FlutterArtist, when you add, delete, or update an ITEM on a Block within a Shelf, this event can be broadcasted to notify other Shelf(s). This mechanism allows the application to react intelligently through a chain of events:
- Recipient Block: Automatically performs a re-query to update with the latest data.
- Recipient Scalar: Automatically refreshes its value.
Note: This article is related to the concepts of FilterInput and SingleItemBlock presented in the articles below:
- FlutterArtist FilterInput - Ví dụ 1
- FlutterArtist SingleItemBlock ex1 (***)
We will do a simple example (Demo27a):
- Supplier27aBlock: Displays the list of suppliers (belongs to Supplier27aShelf).
- SingleSupplierBlock là một Block có FormModel và thuộc SingleSupperShelf.

To modify a "supplier" of Supplier27aBlock, we call the Form of SingleSupplierBlock. After successfully saving, Supplier27aBlock will be queried again. To do this we need some configuration on Supplier27aBlock and SingleSupplierBlock:
- Configure so that when adding, removing or editing an ITEM on SingleSupplierBlock an event will be emitted outside the Shelf.
- Configure Supplier27aBlock to listen for appropriate events outside the Shelf to which it will respond by re-querying.
No ADS

- Download FlutterArtist Demo
- FlutterArtist Deferring External Shelf Events (Ex1) ***
1. Structure of the example


The SingleSupplierShelf example is written in a separate article below:
- FlutterArtist SingleItemBlock ex1 (***)

2. SingleSupplierShelf
On SingleSupplierShelf, we use the emitExternalShelfEvents property to define the type of event to be emitted when data changes.
SingleSupplierShelf > BlockConfig (*)
BlockConfig(
emitExternalShelfEvents: [
Event(SupplierData),
],
)- FlutterArtist SingleItemBlock ex1 (***)
single_supplier_shelf.dart
class SingleSupplierShelf extends Shelf {
@override
ShelfStructure defineShelfStructure() {
return ShelfStructure(
filterModels: {"single-supplier-filter-model": IntIdFilterModel()},
blocks: [
SingleSupplierBlock(
name: SingleSupplierBlock.blockName,
description: '',
config: BlockConfig(
emitExternalShelfEvents: [Event(SupplierData)], //
),
filterModelName: "single-supplier-filter-model",
formModel: SingleSupplierFormModel(),
childBlocks: [],
),
],
);
}
SingleSupplierBlock findSingleSupplierBlock() {
return findBlock(SingleSupplierBlock.blockName) as SingleSupplierBlock;
}
}3. Supplier27aShelf
On Supplier27aShelf, we configure onExternalShelfEvents to let this Block listen for relevant external signals.
supplier27a_shelf.dart
class Supplier27aShelf extends Shelf {
@override
ShelfStructure defineShelfStructure() {
return ShelfStructure(
filterModels: {},
blocks: [
Supplier27aBlock(
name: Supplier27aBlock.blkName,
description: null,
config: BlockConfig(
onExternalShelfEvents: const ExternalShelfEventBlockRecipient(
blockLevelReactionOn: [Event(SupplierData)],
),
),
filterModelName: null,
formModel: null,
childBlocks: [],
),
],
);
}
Supplier27aBlock findSupplier27aBlock() {
return findBlock(Supplier27aBlock.blkName) as Supplier27aBlock;
}
}4. Edit Supplier

At Supplier27aShelf:
When the user clicks the "Edit Supplier" button, the _onPressEditSupplierBtn() method will be called:
_onPressEditSupplierBtn()
Future<void> _onPressEditSupplierBtn(BuildContext context) async {
FlutterArtist.codeFlowLogger.addMethodCall(
ownerClassInstance: this,
currentStackTrace: StackTrace.current,
parameters: null,
);
//
SupplierInfo? supplierInfo = block.currentItem;
if (supplierInfo == null) {
return;
}
Coordinator coordinator = SingleSupplierEditCoordinator(
supplierId: supplierInfo.id,
config: CoordinatorConfig(),
customNavigate: (BuildContext context, bool success) {
if (success) {
Scaffold.of(context).openEndDrawer();
}
},
);
await coordinator.execute(context);
}At SingleSupplierShelf:
SingleSupplierEditCoordinator will query SingleSupplierBlock to find the correct record corresponding to the supplierId the user desires and then open SingleSupplierForm on an EndDrawer.
No ADS
single_supplier_edit_coordinator.dart
class SingleSupplierEditCoordinator extends Coordinator {
final int supplierId;
SingleSupplierEditCoordinator({
required this.supplierId,
required super.config,
required super.customNavigate,
});
@override
Future<bool> performSetupOperation() async {
SingleSupplierShelf shelf = FlutterArtist.storage.findShelf();
SingleSupplierBlock block = shelf.findSingleSupplierBlock();
IntIdFilterInput filterInput = IntIdFilterInput(idValue: supplierId);
// With SingleItemBlock, this query return a List with only one item (SupplierData).
BlockQueryResult result = await block.query(
filterInput: filterInput,
afterQueryAction: AfterQueryAction.setAnItemAsCurrentThenLoadForm,
);
if (!result.successForAll) {
return false;
}
return true;
}
@override
Future<void> defaultNavigate(BuildContext context, bool success) async {
if (success) {
await Get.to(() => SingleSupplierFormScreen());
}
}
}Tip: When you call a ShelfB from ShelfA, you should write code in a Coordinator and place it on the ShelfB side, this helps you to reuse and call ShelfB easily.

No ADS

5. Create Supplier
Similar to the editing scenario, when a user wants to create a new supplier, we coordinate the workflow through the SingleSupplierCreationCoordinator.
At Supplier27aShelf:
When the user clicks the "Create Supplier" button, the _onPressCreateSupplierBtn() method is called to initiate the process.

_onPressCreateSupplierBtn()
Future<void> _onPressCreateSupplierBtn(BuildContext context) async {
FlutterArtist.codeFlowLogger.addMethodCall(
ownerClassInstance: this,
currentStackTrace: StackTrace.current,
parameters: null,
);
//
Coordinator coordinator = SingleSupplierCreationCoordinator(
config: CoordinatorConfig(),
customNavigate: (BuildContext context, bool success) {
if (success) {
Scaffold.of(context).openEndDrawer();
}
},
);
await coordinator.execute(context);
}At SingleSupplierShelf:
SingleSupplierCreationCoordinator is responsible for preparing the state for the Block and Form, ensuring everything is ready for user input.
single_supplier_creation_coordinator.dart (***)
class SingleSupplierCreationCoordinator extends Coordinator {
SingleSupplierCreationCoordinator({
required super.config,
required super.customNavigate,
});
@override
Future<bool> performSetupOperation() async {
SingleSupplierShelf shelf = FlutterArtist.storage.findShelf();
SingleSupplierBlock block = shelf.findSingleSupplierBlock();
// Never been queried
if (block.dataState == DataState.pending) {
await block.queryEmpty();
}
PrepareItemCreationResult result = await block.prepareFormToCreateItem(
navigate: null,
);
if (!result.successForAll) {
return false;
}
return true;
}
@override
Future<void> defaultNavigate(BuildContext context, bool success) async {
if (success) {
await Get.to(() => SingleSupplierFormScreen());
}
}
}6. Smart Data Refresh Mechanism
You might wonder: "If Supplier27aBlock is not currently on screen (e.g., in another Tab or a previous page), will it waste resources by re-querying immediately?"
The answer is "No". FlutterArtist optimizes this with the following mechanism:
- Pending State: When an event is received while the Block is off-screen, it won't query immediately but instead switches its state to DataState.pending.
- Wake-up on Display: The Block will only re-query if and only if: It has a Block-Context-View currently visible on the screen or any of its child Block(s) (descendants) are visible.
No ADS
FlutterArtist
- Basic concepts in Flutter Artist
- FlutterArtist Block ex1
- FlutterArtist Form ex1
- FlutterArtist FormModel.patchFormFields() Ex1
- FlutterArtist BlockQuickItemUpdateAction Ex1
- FlutterArtist BlockNumberPagination Ex1
- FlutterArtist BlockQuickMultiItemCreationAction Ex1
- FlutterArtist ListView Infinite Scroll Pagination Example
- FlutterArtist Pagination
- FlutterArtist Sort DropdownSortPanel Example
- FlutterArtist BackgroundWebDownloadAction ex1
- FlutterArtist Block External Shelf Event ex1
- FlutterArtist Master-detail Blocks ex1
- FlutterArtist Scalar ex1
- FlutterArtist Pagination Davi table Infinite Scroll Ex1
- FlutterArtist Form Parent-child MultiOptFormProp ex1
- FlutterArtist Manual Sorting ReorderableGridView Example
- FlutterArtist Manual Sorting ReorderableListView
- FlutterArtist Scalar External Shelf Event ex1
- FlutterArtist Context Provider Views
- FlutterArtist Internal Shelf Event ex1
- FlutterArtist DropdownSortPanel
Show More