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

NoSuchMethodError: Class '_Map<String, Object>' has no instance getter 'toJson' #403

Open
mrasityilmaz opened this issue Dec 17, 2024 · 7 comments

Comments

@mrasityilmaz
Copy link

NoSuchMethodError: Class '_Map<String, Object>' has no instance getter 'toJson' in socket.io usage with EVENT type packets

Description

I am encountering a NoSuchMethodError with the following details:
This error occurs when I receive packets of type EVENT while using socket_io_client. To resolve this, I updated the package version from 3.0.0-beta.2 to 3.0.2 as I saw a similar issue addressed in socket_io_common. However, the issue persists in the latest version as well.

The problem seems to be related to a missing toJson method in the Map implementation. The issue likely stems from how packets are being handled or parsed within the socket library.

Steps to Reproduce

  1. Use the socket_io_client package version 3.0.2.
  2. Establish a socket connection to a server.
  3. Receive a packet of type EVENT.
  4. Observe the following error in the logs:
NoSuchMethodError: Class_Map<String, Object>’ has no instance getter ‘toJson’.
Receiver: _Map
Tried calling: toJson
---
NoSuchMethodError (NoSuchMethodError: Class '_Map<String, Object>' has no instance getter 'toJson'.
Receiver: _Map len:4
Tried calling: toJson)
---
NoSuchMethodError (NoSuchMethodError: Class 'int' has no instance getter 'toJSON'.
Receiver: 2
Tried calling: toJSON)
---
NoSuchMethodError (NoSuchMethodError: Class 'String' has no instance getter 'toJSON'.
Receiver: "exitRoom"
Tried calling: toJSON)
---
NoSuchMethodError (NoSuchMethodError: Class 'List<dynamic>' has no instance getter 'toJSON'.
Receiver: Instance(length:2) of '_GrowableList'
Tried calling: toJSON)

Environment

  • Package: socket_io_client 3.0.2
  • Dart/Flutter version: 3.5.4 - Dart SDK / 3.24.4 - Flutter SDK
  • Platform: IOS

Expected Behavior

The library should correctly handle or parse EVENT type packets without throwing a NoSuchMethodError. Ideally, any _Map object should be deserialized properly or handled internally.

Actual Behavior

The application throws a NoSuchMethodError when a toJson method is called on _Map<String, Object> during the handling of an EVENT type packet.

Attachments

  • A screenshot of the error is attached.

Ekran Resmi 2024-12-13 19 21 20

Example Code Snippet

socket.emit('eventName','StringValue');
@mostafasany
Copy link

I am getting the same issue.

@mostafasany
Copy link

@mrasityilmaz were you able to find out any workaround?

@jumperchen
Copy link
Member

It’s strange; this issue should not have occurred. According to the code, all exceptions should be caught by the try-catch statement. - https://github.com/rikulo/socket_io_common/blob/master/lib/src/parser/is_binary.dart#L67-L77

FYI, a few weeks ago, someone who encountered this issue cleared his environment and rebuilt his code, and everything went well.

@mostafasany
Copy link

mostafasany commented Jan 15, 2025

This is how i call the emit method

_socket?.emitWithAck('sync-messages', { 'messages': [message] }, 
ack: (dynamic ackResponse) {
});

In this screenshot its shows that .toJSON not exists on obj (Map)
Screenshot 2025-01-15 at 10 06 47

Also something doesn't look right in this function https://github.com/rikulo/socket_io_common/blob/master/lib/src/parser/is_binary.dart#L67-L77

Unnecessary Nesting of Try-Catch , the code in first Try and Catch is the same as in the second try and catch without adding any value.

Function? _getToJsonMethod(obj) {
  var toJsonMethod = null;
  try {
    // backwards compatibility for toJSON method
    var toJsonMethod = obj.toJSON;
    if (toJsonMethod is Function) {
      return toJsonMethod;
    }
  } catch (e) {
    try {
      // from dart-lang json.dart, the method is called toJson
      toJsonMethod = obj.toJson;
      if (toJsonMethod is Function) {
        return toJsonMethod;
      }
    } catch (e) {
      // Catch and ignore errors if the method is not present
    }
    // Catch and ignore errors if the method is not present
  }
  return null;
}

The old is_binary has this condition to guard .toJson again object without toJSON, and this condition not exists in latest version
if (obj['toJSON'] != null && obj['toJSON'] is Function && toJSON == false) {
return hasBinary(obj.toJSON(), true);
}

@mrasityilmaz
Copy link
Author

@mrasityilmaz were you able to find out any workaround?

No, I couldn’t find it. There hasn’t been any progress either.
I think I’ll fork it myself and remove this function.

@mostafasany
Copy link

@mrasityilmaz Can you share your forked repo when you have it?

@jumperchen
Copy link
Member

Maybe we can check the built in types first to see if that can help you.

For example,


Function? _getToJsonMethod(Object obj) {
  if (obj is Map || obj is List || obj is String || obj is num || obj is bool || obj == null) {
    return null; // Skip built-in types
  }

  try {
    // Dynamically check for `toJSON` method
    if ((obj as dynamic).toJSON != null && (obj as dynamic).toJSON is Function) {
      return (obj as dynamic).toJSON;
    }
  } catch (e) {
    // Ignore if `toJSON` is not found
  }

  try {
    // Dynamically check for `toJson` method
    if ((obj as dynamic).toJson != null && (obj as dynamic).toJson is Function) {
      return (obj as dynamic).toJson;
    }
  } catch (e) {
    // Ignore if `toJson` is not found
  }

  // If no suitable method is found, return null
  return null;
}

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

3 participants