Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Equatable should override toString and return a String with the name of each property and value #27

Closed
GiancarloCode opened this issue Jul 28, 2019 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@GiancarloCode
Copy link

Is your feature request related to a problem? Please describe.

If you have a Credential class:

class Credentials extends Equatable {
  final String username;
  final String password;

  Credentials({this.username, this.password}) : super([username, password]);
}

When you create a credential and print:

final credentials = Credentials(username: 'Joe', password: 'password123');
print(credentials)

The output is:

Instance of 'Credentials'

In most cases you want to show the name of class, the property name and the value of each property, so you need to override toString() manually:

class Credentials extends Equatable {
  final String username;
  final String password;

  Credentials({this.username, this.password}) : super([username, password]);

  @override
  String toString() =>
      'Credentials { userName: $username, password: $password }';
}

And now the output is:

Credentials { userName: Joe, password: password123 }

Describe the solution you'd like

Equatable accept a map instead of list.

import 'package:meta/meta.dart';
import './equatable_utils.dart';

@immutable
abstract class Equatable {
  final Map props;

  Equatable([this.props = const {}]);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Equatable &&
          runtimeType == other.runtimeType &&
          equals(props.values.toList(), other.props.values.toList());

  @override
  int get hashCode =>
      runtimeType.hashCode ^ mapPropsToHashCode(props.values.toList());

  @override
  String toString() => '$runtimeType${_propsToString()}';

  String _propsToString() {
    StringBuffer _result = StringBuffer();

    if (props.isNotEmpty) {
      _result.write(' {');
      for (int i = 0; i < props.length; i++) {
        _result
          ..write(' ')
          ..write(props.keys.elementAt(i))
          ..write(': ')
          ..write(props.values.elementAt(i));
        if (i != props.length - 1) _result..write(',');
      }
      _result.write(' }');
    }

    return _result.toString();
  }
}

Now you need to pass a Map to the super constructor, when the key is the String for show in toString() method, and the value, is the value to use to override == and hashcode

class Credentials extends Equatable {
  final String username;
  final String password;

  Credentials({this.username, this.password})
      : super({'userName': username, 'password': password});
}

And now the output is:

Credentials { userName: Joe, password: password123 }

Thanks 😀

@felangel felangel self-assigned this Aug 4, 2019
@felangel felangel added the enhancement New feature or request label Aug 4, 2019
@felangel
Copy link
Owner

felangel commented Aug 4, 2019

@GiancarloCode thanks for the feature request!

Based on our discussion on gitter, I am going to update toString to default to runtimeType because passing a map increases the complexity and is also tangential to the focus of the package.

@felangel felangel mentioned this issue Aug 4, 2019
3 tasks
@felangel
Copy link
Owner

felangel commented Aug 4, 2019

Published in v0.4.0 of equatable 🎉

@felangel felangel closed this as completed Aug 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants