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

copyWith throws TypeError when built for web #39

Closed
phr4fh opened this issue Jun 10, 2024 · 4 comments
Closed

copyWith throws TypeError when built for web #39

phr4fh opened this issue Jun 10, 2024 · 4 comments

Comments

@phr4fh
Copy link

phr4fh commented Jun 10, 2024

Hi, thanks for your awesome library! I just encountered a bug that was extremely difficult to trace and I don't know what happens here exactly...

I'm using Message.copyWith in the process of creating my messages to diplay them in a chat UI. On Flutter Web, the following code throws a TypeError:

   flyerTypes.Message method1(flyerTypes.Message raw) {
    return raw.copyWith(id: "msg001"); // this throws TypeError: Instance of '_Type': type '_Type' is not a subtype of type 'Map<String, dynamic>?'
   }

I fixed it by passing metadata as parameter to copyWith:

   flyerTypes.Message method2(flyerTypes.Message raw) {
    return raw.copyWith(id: "msg002", metadata: raw.metadata); // this works fine
   }
  • It is also fine (both ways) on Android, iOS and Windows.
  • It is also fine when I debug it locally in the browser.
  • Only when built and deployed to docker, it results in TypeError: Instance of '_Type': type '_Type' is not a subtype of type 'Map<String, dynamic>?'

Could it be something to do with dynamic metadata = _Unset in the copyWith implementation? Maybe minifying to JS optimizes the _Unset type away?

@demchenkoalex
Copy link
Member

Hello. Oh man this looks hard haha.. the dynamic unset approach is the only way to make copyWith work with values and nulls without resetting all fields of the message. I already re-written this library for my upcoming v2 implementation and I used the same approach, cause there is literally no alternative. I wonder what can I even do here 🤔

@phr4fh
Copy link
Author

phr4fh commented Jun 12, 2024

Is something like the copy_with_extension not an option?

@demchenkoalex
Copy link
Member

did not know about this package, let me test it :)

@demchenkoalex
Copy link
Member

For the v2 types I was able to use freezed to generate pretty much everything, my final types would look something like this:

import 'package:freezed_annotation/freezed_annotation.dart';

import 'epoch_date_time_converter.dart';
import 'link_preview.dart';

part 'message.freezed.dart';
part 'message.g.dart';

@Freezed(unionKey: 'type', fallbackUnion: 'unsupported')
sealed class Message with _$Message {
  const factory Message.text({
    required String id,
    required String senderId,
    @EpochDateTimeConverter() required DateTime timestamp,
    Map<String, dynamic>? metadata,
    required String text,
    LinkPreview? linkPreview,
  }) = TextMessage;

  const factory Message.image({
    required String id,
    required String senderId,
    @EpochDateTimeConverter() required DateTime timestamp,
    Map<String, dynamic>? metadata,
    required String source,
    String? thumbhash,
    String? blurhash,
    double? width,
    double? height,
  }) = ImageMessage;

  const factory Message.unsupported({
    required String id,
    required String senderId,
    @EpochDateTimeConverter() required DateTime timestamp,
    Map<String, dynamic>? metadata,
  }) = UnsupportedMessage;

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants