entity_state 1.2.5

  • Readme
  • Changelog
  • Example
  • Installing
  • 58

Entity State #

Entity State to manage records in your redux state.

Installation #

Add this to your project's pubspec.yaml

dependencies:
  entity_state: ^1.2.5

Usage #

In your redux state

abstract class ReminderState
    with EntityState<Reminder, int, ReminderState, ReminderStateBuilder>
    implements Built<ReminderState, ReminderStateBuilder> {
  // This is mandatory to add
  BuiltList<int> get ids;

  // This is mandatory to add
  BuiltMap<int, Reminder> get entities;

  ReminderState._();

  factory ReminderState([updates(ReminderStateBuilder b)]) = _$ReminderState;

  static Serializer<ReminderState> get serializer => _$reminderStateSerializer;
  
  // This will tell the entity state what is the unique identifier of the model.
  @override
    int getId(Reminder data) {
      return data.id;
    }
}

In your reducer

To Add One #

AppNotificationState listNotificationComplete(
    AppNotificationState appNotificationState,
    ListNotificationComplete action) {
  return appNotificationState
        // action.notification is `Notification`
      .addOne(action.notification)
      .rebuild((b) => b..isLoading = false);
}

To Add All (replaces any data that was previously present) #

AppNotificationState listNotificationComplete(
    AppNotificationState appNotificationState,
    ListNotificationComplete action) {
  return appNotificationState
        // action.notifications is `List<Notification>`
      .addAll(action.notifications)
      .rebuild((b) => b..isLoading = false);
}

To Add Many (appends to previous data) #

AppNotificationState listNotificationComplete(
    AppNotificationState appNotificationState,
    ListNotificationComplete action) {
  return appNotificationState
        // action.notifications is `List<Notification>`
      .addMany(action.notifications)
      .rebuild((b) => b..isLoading = false);
}

To Update One #

AppNotificationState listNotificationComplete(
    AppNotificationState appNotificationState,
    ListNotificationComplete action) {
  return appNotificationState
        // action.notification is `Notification`
      .updateOne(action.notification)
      .rebuild((b) => b..isLoading = false);
}

To Update Many #

AppNotificationState listNotificationComplete(
    AppNotificationState appNotificationState,
    ListNotificationComplete action) {
  return appNotificationState
        // action.notifications is `List<Notification>`
      .updateMany(action.notifications)
      .rebuild((b) => b..isLoading = false);
}

To Remove One #

AppNotificationState listNotificationComplete(
    AppNotificationState appNotificationState,
    ListNotificationComplete action) {
  return appNotificationState
        // action.notification is `int`
      .removeOne(action.notificationId)
      .rebuild((b) => b..isLoading = false);
}

To Remove Many #

AppNotificationState listNotificationComplete(
    AppNotificationState appNotificationState,
    ListNotificationComplete action) {
  return appNotificationState
        // action.notifications is `List<Notification>`
      .removeMany(action.notifications)
      .rebuild((b) => b..isLoading = false);
}

To Remove All #

AppNotificationState listNotificationComplete(
    AppNotificationState appNotificationState,
    ListNotificationComplete action) {
  return appNotificationState
        // action.notifications is `List<Notification>`
      .removeAll()
      .rebuild((b) => b..isLoading = false);
}

How to get the data #

static _ViewModel fromStore(Store<AppState> store) {
       return _ViewModel(
           notifications: store.state.appNotification.getAll(),
           isLoading: store.state.appNotification.isLoading,
           notificationTapped: (AppNotification notification) {
             store.dispatch(UpdateNotification(notification: notification));
           });
     }

How to get the sorted data #

static _ViewModel fromStore(Store<AppState> store) {
       return _ViewModel(
           notifications: store.state.appNotification.getAll((notif1,notif2)=>notif1.id.compareTo(notif2.id),
           });
     }

[1.0.0] - April 2, 2019 #

[1.2.0] - July 7, 2019 #

example/lib/main.dart

import 'package:example/actions/user_action.dart';
import 'package:example/middleware/user_middleware.dart';
import 'package:example/models/user.dart';
import 'package:example/models/user_state.dart';
import 'package:example/reducers/user_reducer.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';

typedef OnDelete = void Function(String userId);
typedef OnUpdate = void Function(User user);

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  final store = Store<UserState>(userReducer,
      initialState: UserState(), middleware: [userMiddleware]);

  MyApp() {
    store.dispatch(ListUsers());
  }

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return StoreProvider(
      store: store,
      child: MaterialApp(
        title: 'Entity State',
        home: HomePageContainer(),
      ),
    );
  }
}

class HomePageContainer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StoreConnector<UserState, _ViewModel>(
      converter: _ViewModel.fromStore,
      builder: (BuildContext context, _ViewModel model) => MyHomePage(
        isLoading: model.isLoading,
        users: model.users,
        deletingIds: model.deletingIds,
        onDelete: model.onDelete,
        onDeleteAll: model.onDeleteAll,
        onDeleteMany: model.onDeleteMany,
        entities: model.entities,
        addOne: model.addOne,
        addMany: model.addMany,
        ids: model.ids,
        updateOne: model.updateOne,
        updateMany: model.updateMany,
      ),
    );
  }
}

class _ViewModel {
  final bool isLoading;
  final List<User> users;
  final Map<String, bool> deletingIds;

  final OnDelete onDelete;
  final Function onDeleteMany;

  final Function onDeleteAll;

  final Function addOne;
  final Function addMany;
  final Function updateOne;
  final Function updateMany;
  final Map<String, User> entities;
  final List<String> ids;

  _ViewModel(
      {@required this.entities,
      @required this.ids,
      @required this.addOne,
      @required this.addMany,
      @required this.updateOne,
      @required this.updateMany,
      @required this.isLoading,
      @required this.users,
      @required this.onDelete,
      @required this.onDeleteMany,
      @required this.deletingIds,
      @required this.onDeleteAll});

  static _ViewModel fromStore(Store<UserState> store) {
    return _ViewModel(
      ids: store.state.getIds(),
      addOne: (user) => store.dispatch(AddOneUser(user)),
      addMany: (users) => store.dispatch(AddManyUser(users)),
      updateOne: (user) => store.dispatch(UpdateUser(user)),
      updateMany: (users) => store.dispatch(UpdateManyUser(users)),
      entities: store.state.getEntities(),
      isLoading: store.state.isLoading,
      users: store.state.getAll((a, b) => a.fullName.compareTo(b.fullName)),
      onDelete: (String userId) => store.dispatch(DeleteUser(userId)),
      onDeleteMany: (usersIds) => store.dispatch(DeleteManyUser(usersIds)),
      deletingIds: store.state.deletingIds.toMap(),
      onDeleteAll: () {
        store.dispatch(DeleteAllUsers());
      },
    );
  }
}

class MyHomePage extends StatefulWidget {
  final bool isLoading;
  final List<User> users;
  final Map<String, bool> deletingIds;

  final OnDelete onDelete;
  final Function onDeleteAll;
  final Function onDeleteMany;

  final Function addOne;
  final Function addMany;
  final Function updateOne;
  final Function updateMany;

  final Map<String, User> entities;
  final List<String> ids;

  MyHomePage(
      {@required this.entities,
      @required this.ids,
      @required this.addOne,
      @required this.addMany,
      @required this.updateMany,
      @required this.updateOne,
      @required this.isLoading,
      @required this.users,
      @required this.onDelete,
      @required this.onDeleteMany,
      @required this.deletingIds,
      @required this.onDeleteAll});

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController _textFieldController = TextEditingController();
  bool val = false;
  Map<String, User> selectedValues = new Map();
  List<User> users = new List();

  @override
  Widget build(BuildContext context) {
    users
      ..add(new User((b) => b
        ..firstName = "Mclean 1"
        ..id = "5d20ecfc59cb1c0f2c386cee"));
    users
      ..add(new User((b) => b
        ..firstName = "Terri 1"
        ..id = "5d20ecfccbdf7fb08c86c798"));
    users
      ..add(new User((b) => b
        ..firstName = "Sherrie 1"
        ..id = "5d20ecfcd435256672973f26"));
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {
//          widget.addMany(users);
          _addOneDialog(context);
        },
        child: Icon(Icons.add),
      ),
      appBar: AppBar(
        title: Text("Entity State"),
        actions: <Widget>[
          (selectedValues.length > 0)
              ? Row(
                  children: <Widget>[
                    FlatButton(
                      child: Text("Update Selected"),
                      onPressed: () {
                        _updateManyDialog(
                            context, selectedValues.keys.toList());
                      },
                    ),
                    FlatButton(
                      child: Text("Delete Selected"),
                      onPressed: () {
                        widget.onDeleteMany(selectedValues.keys.toList());
                        setState(() {
                          selectedValues = new Map();
                        });
                      },
                    )
                  ],
                )
              : FlatButton(
                  child: Text("Delete All"),
                  onPressed: () {
                    widget.onDeleteAll();
                  },
                )
        ],
      ),
      body: Center(
        child: widget.isLoading
            ? CircularProgressIndicator()
            : ListView.builder(
                itemCount: widget.users.length,
                itemBuilder: (BuildContext context, int index) {
                  final user = widget.users.elementAt(index);
                  return Card(
                    child: Container(
                      padding: EdgeInsets.all(12),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          Checkbox(
                            value: (selectedValues.containsKey(user.id))
                                ? true
                                : false,
                            onChanged: (bool value) {
                              setState(() {
                                if (selectedValues.containsKey(user.id))
                                  selectedValues.remove(user.id);
                                else
                                  selectedValues.addAll({user.id: user});
                              });
                            },
                          ),
                          Expanded(child: Text(user.fullName)),
                          FlatButton(
                            child: Icon(Icons.edit),
                            onPressed: () => _updateOneDialog(context, user),
                          ),
                          FlatButton(
                            child: (widget.deletingIds[user.id] != null &&
                                    widget.deletingIds[user.id])
                                ? CircularProgressIndicator(
                                    valueColor: AlwaysStoppedAnimation<Color>(
                                        Colors.red),
                                  )
                                : Icon(
                                    Icons.delete,
                                    color: Colors.red,
                                  ),
                            onPressed: () {
                              widget.onDelete(user.id);
                            },
                          )
                        ],
                      ),
                    ),
                  );
                }),
      ),
    );
  }

  _addOneDialog(BuildContext context) async {
    return showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('Enter Your Name'),
            content: TextField(
              controller: _textFieldController,
            ),
            actions: <Widget>[
              FlatButton(
                child: Text('SAVE'),
                onPressed: () {
                  User user = new User((b) => b
                    ..id = "5d20ecfccbdf7fb08c86c798"
                    ..firstName = _textFieldController.text);
                  widget.addOne(user);
                  Navigator.of(context).pop();
                },
              ),
              FlatButton(
                child: Text('CANCEL'),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              )
            ],
          );
        });
  }

  _updateOneDialog(BuildContext context, User user) {
    return showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('Enter Your Name'),
            content: TextField(
              decoration: InputDecoration(hintText: user.fullName),
              controller: _textFieldController,
            ),
            actions: <Widget>[
              FlatButton(
                child: Text('UPDATE'),
                onPressed: () {
                  user = user
                      .rebuild((b) => b..firstName = _textFieldController.text);
                  widget.updateOne(user);
                  Navigator.of(context).pop();
                },
              ),
              FlatButton(
                child: Text('CANCEL'),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              )
            ],
          );
        });
  }

  _updateManyDialog(BuildContext context, List<String> idsList) {
    return showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('Enter Your Name'),
            content: TextField(
              controller: _textFieldController,
            ),
            actions: <Widget>[
              FlatButton(
                child: Text('UPDATE'),
                onPressed: () {
                  List<User> updatedUsers = new List();
                  idsList.forEach((id) {
                    updatedUsers
                      ..add(selectedValues[id].rebuild(
                          (b) => b..firstName = _textFieldController.text));
                  });
                  setState(() {
                    selectedValues = new Map();
                  });
                  widget.updateMany(updatedUsers);
                  Navigator.of(context).pop();
                },
              ),
              FlatButton(
                child: Text('CANCEL'),
                onPressed: () {
                  setState(() {
                    selectedValues = new Map();
                  });
                  Navigator.of(context).pop();
                },
              )
            ],
          );
        });
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  entity_state: ^1.2.5

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:entity_state/entity_state.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
16
Health:
Code health derived from static analysis. [more]
99
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
58
Learn more about scoring.

We analyzed this package on Mar 24, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6

Health suggestions

Fix lib/entity_state.dart. (-1 points)

Analysis of lib/entity_state.dart reported 2 hints:

line 59 col 21: Avoid types as parameter names.

line 114 col 25: Use isEmpty instead of length

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
built_collection ^4.2.0 4.3.2
Transitive dependencies
collection 1.14.12
matcher 0.12.6
meta 1.1.8
path 1.6.4
quiver 2.1.3
stack_trace 1.9.3