Home > Net >  Flutter - How to compare two objects while using freezed with custom jsonkey
Flutter - How to compare two objects while using freezed with custom jsonkey

Time:02-04

I've created a custom class that implements freezed, and I'm trying to compare a saved Settings Object with a current one and when I compare both objects with the same values it returns it's not the same

The problem is because of the dateFormat, because with the other values works

Settings settings1 = Settings(
    dateFormat: DateFormat('dd/MM/yyyy'),
    movementType: StandardMovement.type905,
    autoBatch: true,
);
Settings settings2 = Settings(
    dateFormat: DateFormat('dd/MM/yyyy'),
    movementType: StandardMovement.type905,
    autoBatch: true,
);
print(settings1 == settings2);

Actually I need more objects, but I've only placed dateFormat to make it easier to read

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:intl/intl.dart';
part 'settings.freezed.dart';
part 'settings.g.dart';

enum StandardMovement { type905, type101 }

@freezed
class Settings with _$Settings {
  const factory Settings({
    /// Example:
    /// ```dart
    /// DateFormat('dd.MM.yyyy');
    /// ```
    @JsonKey(
      fromJson: _dateFormatFromJson,
      toJson: _dateFormatToJson,
      name: 'dateFormat',
    )
    required DateFormat dateFormat,

    required StandardMovement movementType,

    required bool autoBatch,
  }) = _Settings;

  factory Settings.fromJson(Map<String, dynamic> json) =>
      _$SettingsFromJson(json);
}

DateFormat _dateFormatFromJson(String pattern) => DateFormat(pattern);
String _dateFormatToJson(DateFormat dateFormat) => dateFormat.pattern!;

EDIT: Solved

You can have a look @ the comment below but tldr with Equatable:


@freezed
class Settings extends Equatable with _$Settings {
  const Settings._();

  @override
  List<Object?> get props => [
        dateFormat.pattern,
        movementType,
        autoBatch,
      ];
... etc

CodePudding user response:

Haven't used freezed, but can you override the equality operator of Settings? If so, you can add the following:

enum StandardMovement { type905, type101 }

// SAMPLE GENERATED CLASS
@immutable
abstract class _$Settings {
  const _$Settings(this.dateFormat, this.standardMovement);

  final DateFormat dateFormat;
  final StandardMovement standardMovement;
}

class Settings extends _$Settings {
  const Settings(DateFormat dateFormat, StandardMovement standardMovement) : super(dateFormat, standardMovement);

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }

    return other is _$Settings 
      && other.dateFormat == dateFormat // <- Update this by adding your custom equality checks
      && other.standardMovement == standardMovement;
  }

  @override
  int get hashCode => dateFormat.hashCode ^ standardMovement.hashCode;
}

You need to override the equality operator if you want to include some custom class properties to the checking.

CodePudding user response:

Got it working with Equatable like:


@freezed // Extended Equatable
class Settings extends Equatable with _$Settings {
  const Settings._(); // <- Added this cause if not I got errors adding equatable

  @override
  List<Object?> get props => [ // <- custom class properties to check
        dateFormat.pattern,
        movementType,
        autoBatch,
      ];

I also got this working without Equatable:

enum StandardMovement { type905, type101 }

@freezed
class Settings with _$Settings {

  const Settings._(); // <- Added

  const factory Settings({
    /// Example:
    /// ```dart
    /// DateFormat('dd.MM.yyyy');
    /// ```
    @JsonKey(
      fromJson: _dateFormatFromJson,
      toJson: _dateFormatToJson,
      name: 'dateFormat',
    )
    required DateFormat dateFormat,

    required StandardMovement movementType,

    required bool autoBatch,
  }) = _Settings;

  factory Settings.fromJson(Map<String, dynamic> json) =>
      _$SettingsFromJson(json);

  @override // <- Added
  bool operator ==(dynamic other) {
    return identical(this, other) ||
        (
          other.runtimeType == runtimeType && other is _Settings &&
          const DeepCollectionEquality().equals(other.dateFormat.pattern, dateFormat.pattern) && // <- Custom check
          const DeepCollectionEquality().equals(other.movementType, movementType) &&
          const DeepCollectionEquality().equals(other.autoBatch, autoBatch)
        );
  }

  @override // <- Added
  int get hashCode => Object.hash(
        runtimeType,
        const DeepCollectionEquality().hash(dateFormat.locale), // <- Custom check
        const DeepCollectionEquality().hash(movementType),
        const DeepCollectionEquality().hash(autoBatch),
      );
}

DateFormat _dateFormatFromJson(String pattern) => DateFormat(pattern);
String _dateFormatToJson(DateFormat dateFormat) => dateFormat.pattern!;
  •  Tags:  
  • Related