top of page

[Flutter/dart] Support item deletion with Redux pattern


Background

Consider the following case.

  • There is a list of items

  • There is a page that displays details for a specific item.

  • You can delete the item on the details page.

  • After deleting, return to other pages (list page, etc.)

I think this is a common pattern in apps.


Issue

If you are using the redux pattern, or more specifically if you are managing the state with a Provider, you probably have a configuration like below.


  1. The entire app is a child of StoreProvider, and when the contents of the store change, the entire app will be rebuilt.

  2. The item details page extracts the item from the store using the StoreConnector.

  3. When deleting an item on the item details page, move to the specified page

//move to item details page
await Navigator.of(context).push(
  MaterialPageRoute(
    builder: (context)=> StoreConnector<AppState, ItemDetailViewModel>(
      converter: (store) 
      => ItemDetailViewModel.create(store, itemId), 
      //2 extract item from store
      builder: (context, model) {
        return ItemDetailPage(model);  //item details page
      },
    )
  )
);
Widget _itemDeleteButton(){
  return GestureDetector(
    child: const Icon(Icons.delete),
    onTap: ()async{
       await _deleteItem();  
       await Navigator.of(context).push(
         //3 move to other page
       );
    }
}

In this case, the following issues arise:


  • StoreProvider rebuilds the entire app when an item is deleted

  • The details page creation process will also be executed again.

  • In other words, "function to extract the specified item from the store" (2) is also executed again.

  • Since that item no longer exists, it will throw an exception.

Of course, if the exit from the details page is ealier than the process in step 2, this problem will not occur (since the details page is no longer displayed, the page creation process will not run).

However, since the rebuild by StoreProvider runs asynchronously with the processing on the details page, we cannot guarantee that you will be able to exit first.



Solution

  • In process 2, if the specified item does not exist in the store, return null.

  • In the item extraction process by StoreConnector, if the return value of the converter is null, move to another separately prepared page (such as displaying "This item has been deleted")

await Navigator.of(context).push(
  MaterialPageRoute(
    builder: (context)=> StoreConnector<AppState, ItemDetailViewModel?>(
      converter: (store) => 
      ItemDetailViewModel.create(store, itemId),
      builder: (context, model) {
        if(model == null){
          return ItemDeletedPage(); 
          //"This item has been deleted" is displayed
        }
        return ItemDetailPage(model);
      },
    )
  )
);


Lastly

I don't feel like it's a fundamental solution, but I think it can't be helped that there will be some restrictions on the design when using a platform.


When using a provider, not just redux, the page may be rebuilt at unexpected and uncontrollable timing, so you need to be careful.


In fact, it's my fault that I didn't handle exceptions because I thought, ``There's no chance to extract deleted items,'' lol.

Recent Posts

See All

Comments


Let's do our best with our partner:​ ChatReminder

iphone6.5p2.png

It is an application that achieves goals in a chat format with partners.

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png

Let's do our best with our partner:​ ChatReminder

納品:iPhone6.5①.png

It is an application that achieves goals in a chat format with partners.

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png

Theme diary: Decide the theme and record for each genre

It is a diary application that allows you to post and record with themes and sub-themes for each genre.

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png
bottom of page