Flutter - Error implementing interface with Freezed

8k views Asked by At

I'm trying to programme to an interface with Freezed. I want to be able to specify all over my app, the type IUserRegistrationEntity;

My interface:

abstract class IUserRegistrationEntity {
  String nickName;
  String email;
  String confirmEmail;
  String password;
  String confirmPassword;
}

My freezed class:

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:vepo/domain/user_registration/i_user_registration_entity.dart';

part 'user_registration_entity.freezed.dart';

@freezed
abstract class UserRegistrationEntity with _$UserRegistrationEntity {
  @Implements(IUserRegistrationEntity)
  factory UserRegistrationEntity(
      {String nickName,
      String email,
      String confirmEmail,
      String password,
      String confirmPassword}) = _UserRegistrationEntity;
}

Getting the error when running the app:

lib/domain/user_registration/user_registration_entity.freezed.dart:165:7: Error: The non-abstract class '_$_UserRegistrationEntity' is missing implementations for these members:
 - IUserRegistrationEntity.confirmEmail
 - IUserRegistrationEntity.confirmPassword
 - IUserRegistrationEntity.email
 - IUserRegistrationEntity.nickName
 - IUserRegistrationEntity.password
Try to either
 - provide an implementation,
 - inherit an implementation from a superclass or mixin,
 - mark the class as abstract, or
 - provide a 'noSuchMethod' implementation.

class _$_UserRegistrationEntity implements _UserRegistrationEntity {
      ^^^^^^^^^^^^^^^^^^^^^^^^^
lib/domain/user_registration/i_user_registration_entity.dart:4:10: Context: 'IUserRegistrationEntity.confirmEmail' is defined here.
  String confirmEmail;

         ^^^^^^^^^^^^
lib/domain/user_registration/i_user_registration_entity.dart:6:10: Context: 'IUserRegistrationEntity.confirmPassword' is defined here.
  String confirmPassword;
         ^^^^^^^^^^^^^^^
lib/domain/user_registration/i_user_registration_entity.dart:3:10: Context: 'IUserRegistrationEntity.email' is defined here.
  String email;
         ^^^^^
lib/domain/user_registration/i_user_registration_entity.dart:2:10: Context: 'IUserRegistrationEntity.nickName' is defined here.
  String nickName;
         ^^^^^^^^

lib/domain/user_registration/i_user_registration_entity.dart:5:10: Context: 'IUserRegistrationEntity.password' is defined here.
  String password;

         ^^^^^^^^

What am I doing wrong?

Edit: Does this quote from the package docs mean it is not possible?.

Note 2: You cannot use @With/@Implements with freezed classes. Freezed classes can neither be extended nor implemented.

Keen to know if people think this is a drawback if so.

3

There are 3 answers

4
rkdupr0n On BEST ANSWER

I tested out your code and found the problem from the generated file. Thing is, freezed doesn't override setters from the implemented abstract class. So, for your IUserRegistrationEntity, make the parameters as getters. Like so:

abstract class IUserRegistrationEntity {
  String get nickName;
  String get email;
  String get confirmEmail;
  String get password;
  String get confirmPassword;
}
0
BeniaminoBaggins On

I used rkdupr0n's solution. I would just like to say that I also made the IUserRegistrationEntity interface know about the Freezed package's functions so that I could call them when programming to the IUserRegistrationEntity interface. Well, just the ones that I need currently. I will add the rest soon.

Freezed class becomes:

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:vepo/domain/user_registration/i_user_registration_entity.dart';

part 'user_registration_entity.freezed.dart';
part 'user_registration_entity.g.dart';

@freezed
abstract class UserRegistrationEntity with _$UserRegistrationEntity {
  @Implements.fromString(
      'IUserRegistrationEntity<\$UserRegistrationEntityCopyWith<IUserRegistrationEntity>>')
  const factory UserRegistrationEntity(
      {String nickName,
      String email,
      String confirmEmail,
      String password,
      String confirmPassword}) = _IUserRegistrationEntity;

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

Interface:

abstract class IUserRegistrationEntity<T> extends FreezedClass<T> {
  String get nickName;
  String get email;
  String get confirmEmail;
  String get password;
  String get confirmPassword;
}

abstract class FreezedClass<T> {
  T get copyWith;
  Map<String, dynamic> toJson();
}
0
Hardik Bamania On

add private empty constructer code

example if you are are generating a freezed user class

@freezed
abstract class User with _$User {
  const User._(); // add this
}

it would look like that