PlatformException on Web Table Fetch

Hi,
I run into an Data fetching Problem as soon as I try to fetch a Table with Flutter Web. The same code works fine on Flutter Android and iOS Build. Login and Server communication works also fine and on my Networktraffic, I can see that the Table Fetch and Backendless response looks good and normal.

This is the error Message I got on my console:

Resolving DataTable classes from the global scope is deprecated and it won’t be supported in the nearest future. Instead, you should register your DataTable classes using the following method Backendless.Data.mapTableToClass
Error: PlatformException(error, TypeError: s is not a constructor, null, null)
dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw
packages/flutter/src/services/message_codecs.dart 653:7 decodeEnvelope
packages/flutter/src/services/platform_channel.dart 296:18 _invokeMethod
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50
dart-sdk/lib/async/zone.dart 1653:54 runUnary
dart-sdk/lib/async/future_impl.dart 147:18 handleValue
dart-sdk/lib/async/future_impl.dart 766:44 handleValueCallback
dart-sdk/lib/async/future_impl.dart 795:13 _propagateToListeners
dart-sdk/lib/async/future_impl.dart 566:5 [_completeWithValue]
dart-sdk/lib/async/future_impl.dart 639:7 callback
dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15

Im running Flutter 3.3.10 and backendless sdk: 7.2.7 on MacOS and Chrome.

In my understanding, this is a backendless sdk exception right?

Hi @Stephan_Tomforde ,

It looks like a client side problem - seems that SDK unable to locate appropriate constructor in class associated with data table. Maybe your class lacks no-args constructor?
It just guess from my side since I am not Flutter dev. If it is not a reason of the problem I will create an internal ticket and my colleague will look to it during this week when he returns from vacation.

Regards, Andriy

Hi Andriy,

my Flutter Dataclass isn’t something fancy:

@freezed
class Department with $Department {
const Department.
();

@JsonSerializable(explicitToJson: true)
const factory Department({
@JsonKey(name: ‘objectId’) required String id,
Location? location,
Company? company,
@Default(0) int num,
required String title,
String? ownerId,
@JsonKey(fromJson: fromIntToDateTime, toJson: toIntFromDateTime) required DateTime created,
@JsonKey(fromJson: fromIntToDateTimeMaybe, toJson: toIntFromDateTimeMaybe) DateTime? updated,
}) = _Department;

factory Department.fromJson(Map<dynamic, dynamic> json) => _$DepartmentFromJson(prepareMap(json));
}

and they work fine on iOS and Android. I did not expect such kind of issues on my Web Port.

Regards, Stephan

@Stephan_Tomforde

I have created an internal ticket BKNDLSS-30878 for this problem. My colleague should reach you out till the end of this week.
Sorry for inconvenience.

Regards, Andriy

1 Like

Hello, @Stephan_Tomforde.

Make sure you have specified the jsApiKey or it might be a mistake.
If everything is correct, post all the code that causes the error. or provide a minimally reproducible example.

Best Regards, Nikita.

jsApiKey is submitted and over my Network monitor an can see that Backendless Server responded with the right response.

The user login function also works on Android, iOS, and the web. The data request also works, but the conversion to the class does not.

@override
Future<List> loadUserDepartments({String? whereUserId}) async {
final queryBuilder = DataQueryBuilder();
if (whereUserId != null) {
queryBuilder.excludeProperties = [‘num’, ‘created’, ‘updated’, ‘ownerId’, ‘user.*’];
queryBuilder.related = [‘user’, ‘department’, ‘department.company’, ‘department.location’];
queryBuilder.relationsDepth = 0;
queryBuilder.whereClause = “user.objectId=‘$whereUserId’”;
}

final query = await _plugin.service.of('employee').find(queryBuilder);
return query != null && query.isNotEmpty && query.first!.containsKey('department')
    ? List<Department>.generate(
        query.first!['department'].length, (index) => _parseDepartment(query.first!['department'][index]!))
    : [];

}

This is my function which throw the exception I posted in my first post.

The request completed successfully. So the problem is not in the backendless-sdk.
I can only tell you that you are not parsing your object correctly.
I cannot reproduce error with correct data.

class Admins {
  String? ChatId;
  String? Username;
  String? objectId;
}

Admins parseAdmins(Map map) {
  return Admins()
    ..Username = map['Username']
    ..ChatId = map['ChatId']
    ..objectId = map['objectId'];
}
    var queryBuilder = DataQueryBuilder()
      ..related = ['admins']
      ..excludeProperties = ['created', 'updated', 'ownerId']
      ..whereClause = 'objectId=\'4D0B8FC4-7F55-48E0-AE9E-79ED5A0B556B\''
      ..relationsDepth = 0;

    var res = await Backendless.data.of('Person').find(queryBuilder);

    List<Admins> admins = List<Admins>.generate(res!.first!['admins'].length,
        (index) => parseAdmins(res.first!['admins'][index]));

    print(admins);

Code above works great. I can reproduce your error only if I try to get object with incorrect index, or if my table has relation 1 : 1(in this case it has Admin object, not List of Admins).

Best Regards, Nikita.

I try to figure out what went wrong and found a hint. If i change my query from:

queryBuilder.related = [‘user’, ‘department’, ‘department.company’, ‘department.location’];
to
queryBuilder.related = [‘user’, ‘department’, ‘department.company’];

and the exception disappeared.

There is also the Massage “Resolving DataTable classes from the global scope is deprecated and it won’t be supported in the nearest future. Instead, you should register your DataTable classes using the following method Backendless.Data.mapTableToClass” which I did not nee on iOS and Android.

Since the classname Location is unfortunately very general, could it be that on Flutter Web the SDK confuses the class with a class with the same name? Can I somehow find out which Classes are registered for which table?

ps.: Parsing the pure JSON outside the “.find(queryBuilder)” went fine on any platform.

Regards,
Stephan

Can you try to change name of ‘location’ to ‘uniqueLocation’ or ‘appLocation’ maybe? Let me know if your problem persists

Best Regards, Nikita.

I tried that yesterday but without success. I also tried to pinpoint the class like this

Backendless.data.mapTableToClass(“Location”, Location);

with all my classes, but that didn’t made a difference.
Is there maybe a special “Flutter JS Compiler” flag, which I cloud try?
I did some unit test, where I pipe the original Backendless response against my Classes and everything worked fine.

Could you explain me the error “Resolving DataTable classes from the global scope is deprecated and it won’t be supported in the nearest future. Instead, you should register your DataTable classes using the following method Backendless.Data.mapTableToClass” ? Maybe this is a hint, because this message is independent comes even if I register all my DataTable classes and it comes only on Flutter Web.

Regards,
Stephan

Ok, thank you for this information, we are working on this problem.

Best Regards, Nikita.

1 Like

We reproduced the issue and found a solution. The problem is that JS looks in the global scope for a class called Location and finds the system class.
But the release will be in the coming weeks.

As a workaround, you can simply rename the Location table to, for example, LocationUniq or Location2.

P.S:
Additionally, regarding the warning, it fires when JS looks for a class by name in the global scope. This functionality will be changed and the warning will no longer appear. It will be included in the release, along with a fix for the problem described above.

Internal tiecket: BKNDLSS-30972.

Best Regards, Nikita.

1 Like

Thanks Nikita and the team behind you. In my case, renaming the Backendless Table would have larger side effects and the behavior with already shipped iOS and Android apps is currently unknown. Therefore, I am looking forward to the fix included in the next release and will wait to continue my work on the web port until then.

Best Regards, Stephan

1 Like

Hello, @Stephan_Tomforde.

The fix was released out of order, so it was fixed earlier than expected. Use version 7.2.11.
Let me know if everything as expected.

Best Regards, Nikita.

Hello @Nikita_Fedorishchev, the fix works like a charm. Thanks :slight_smile: