type; _compactlinkedHashset< string>'不是类型的子类型' map<动态,动态>?'
我正在关注 nofollow noreferrer“> tutorial” Rethinkdb。它尚未用于无效安全性,但我正在尝试使用最新的软件包进行学习并学习它。作为初学者,我去的最新版本的颤音。
我正在尝试测试输入通知,并且我会遇到一个无法破译的错误。
type '_CompactLinkedHashSet<String>' is not a subtype of type 'Map<dynamic, dynamic>?'
package:rethink_db_ns/src/ast.dart:1223
TypingNotification.send
package:chat/…/typing/typing_notification.dart:22
main.<fn>
test/typing_notification_test.dart:44
main.<fn>
test/typing_notification_test.dart:37
我拥有的所有映射都是Map&lt; string,Dynamic&gt;,因此我不确定地图&lt;动态,动态&gt;来自。我还使用包:rethink_db_ns而不是教程作者使用的内容,这是在添加NS之前的重新INK软件包。因此,我不确定我是否必须为新软件包更改更改。我还确保在尝试运行测试之前没有看到任何红色弯曲。
这是我的文件:
这是我尝试运行测试并获取上述错误的测试文件:
import 'package:chat/src/models/typing_event.dart';
import 'package:chat/src/models/user.dart';
import 'package:chat/src/services/typing/typing_notification.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:rethink_db_ns/rethink_db_ns.dart';
import 'helpers.dart';
void main() {
RethinkDb r = RethinkDb();
late Connection connection;
late TypingNotification sut;
setUp(() async {
connection = await r.connect();
await createDb(r, connection);
sut = TypingNotification(r, connection);
});
tearDown(() async {
sut.dispose();
await cleanDb(r, connection);
});
final user = User.fromJson({
'id': '1234',
'active': true,
'lastSeen': DateTime.now(),
});
final user2 = User.fromJson({
'id': '1111',
'active': true,
'lastSeen': DateTime.now(),
});
test('sent typing notification successfully', () async {
TypingEvent typingEvent = TypingEvent(
from: user2.id!,
to: user.id!,
event: Typing.start,
);
final res = await sut.send(event: typingEvent, to: user);
expect(res, true);
});
}
这是typing_notification.dart
:
import 'dart:async';
import 'package:chat/src/models/user.dart';
import 'package:chat/src/models/typing_event.dart';
import 'package:chat/src/services/typing/typing_notification_service_contract.dart';
import 'package:rethink_db_ns/rethink_db_ns.dart';
class TypingNotification implements ITypingNotification {
final Connection _connection;
final RethinkDb _r;
final _controller = StreamController<TypingEvent>.broadcast();
StreamSubscription? _changefeed; // added ? to this
TypingNotification(this._r, this._connection); //added this._change
@override
Future<bool> send({required TypingEvent event, required User to}) async {
if (!to.active) return false;
Map record = await _r
.table('typing_events')
.insert(event.toJson(), {'conflict:' 'update'}).run(_connection);
return record['inserted'] == 1;
}
@override
Stream<TypingEvent> subscribe(User user, List<String> userIds) {
_startReceivingTypingEvents(user, userIds);
return _controller.stream;
}
@override
void dispose() {
_changefeed?.cancel();
_controller.close();
}
_startReceivingTypingEvents(User user, List<String> userIds) {
_changefeed = _r
.table('typing_events')
.filter((event) {
return event('to')
.eq(user.id)
.and(_r.expr(userIds).contains(event('from')));
})
.changes({'include_initial': true})
.run(_connection)
.asStream()
.cast<Feed>()
.listen((event) {
event
.forEach((feedData) {
if (feedData['new_val'] == null) return;
final typing = _eventFromFeed(feedData);
_controller.sink.add(typing);
_removeEvent(typing);
})
.catchError((err) => print(err))
.onError((error, stackTrace) => print(error));
});
}
TypingEvent _eventFromFeed(feedData) {
return TypingEvent.fromJson(feedData['new_val']);
}
_removeEvent(TypingEvent event) {
_r
.table('typing_events')
.get(event.id)
.delete({'return_changes': false}).run(_connection);
}
}
这是typing_event.dart.dart.dart
:
enum Typing { start, stop }
extension TypingParser on Typing {
String value() {
return toString().split('.').last;
}
static Typing fromString(String event) {
return Typing.values.firstWhere((element) => element.value() == event);
}
}
class TypingEvent {
final String from;
final String to;
final Typing event;
String? _id;
String? get id => _id;
TypingEvent({
required this.from,
required this.to,
required this.event,
});
Map<String, dynamic> toJson() => {
'from': this.from,
'to': this.to,
'event': this.event.value(),
};
factory TypingEvent.fromJson(Map<String, dynamic> json) {
var event = TypingEvent(
from: json['from'],
to: json['to'],
event: TypingParser.fromString(json['event']),
);
event._id = json['id'];
return event;
}
}
and Code> :and Code>:这是typing_notification_service_contract.dart
:
import 'package:chat/src/models/typing_event.dart';
import 'package:chat/src/models/user.dart';
abstract class ITypingNotification {
Future<bool> send(
{required TypingEvent event, required User to}); // the tutorial did not include ", required User to" but I added it to prevent an error, since required User to is passed in another file
Stream<TypingEvent> subscribe(User user, List<String> userIds);
void dispose();
}
最后,typing_event.dart.dart
enum Typing { start, stop }
extension TypingParser on Typing {
String value() {
return toString().split('.').last;
}
static Typing fromString(String event) {
return Typing.values.firstWhere((element) => element.value() == event);
}
}
class TypingEvent {
final String from;
final String to;
final Typing event;
String? _id;
String? get id => _id;
TypingEvent({
required this.from,
required this.to,
required this.event,
});
Map<String, dynamic> toJson() => {
'from': this.from,
'to': this.to,
'event': this.event.value(),
};
factory TypingEvent.fromJson(Map<String, dynamic> json) {
var event = TypingEvent(
from: json['from'],
to: json['to'],
event: TypingParser.fromString(json['event']),
);
event._id = json['id'];
return event;
}
}
我是总体初学者&amp;试图推动自己学习无效安全性,因此我的错误很可能很简单,而且我只是看不到它。谁能向我指出正确的方向或在这里提供任何指导?如果您认为可能会有所帮助,我还可以根据要求添加更多详细信息。
I'm following a tutorial that builds a messaging app using flutter and rethinkdb. It hasn't been updated for null safety, but I'm trying to move forward and learn it with the most updated packages & latest version of flutter as I go, as a beginner.
I'm trying to test typing notifications, and I'm getting an error that I can't decipher.
type '_CompactLinkedHashSet<String>' is not a subtype of type 'Map<dynamic, dynamic>?'
package:rethink_db_ns/src/ast.dart:1223
TypingNotification.send
package:chat/…/typing/typing_notification.dart:22
main.<fn>
test/typing_notification_test.dart:44
main.<fn>
test/typing_notification_test.dart:37
All of the Maps that I have are Map<String, dynamic>, so I'm not sure where the Map<dynamic, dynamic> is coming from. I am also using package:rethink_db_ns instead of what the tutorial author uses, which is the rethink package before ns was added. So I'm not sure if I have to change things further for the new package. I also made sure I didn't see any red squiggles before I tried running the test.
Here are my files:
Here is the testing file where I try to run the test and get the aforementioned error:
import 'package:chat/src/models/typing_event.dart';
import 'package:chat/src/models/user.dart';
import 'package:chat/src/services/typing/typing_notification.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:rethink_db_ns/rethink_db_ns.dart';
import 'helpers.dart';
void main() {
RethinkDb r = RethinkDb();
late Connection connection;
late TypingNotification sut;
setUp(() async {
connection = await r.connect();
await createDb(r, connection);
sut = TypingNotification(r, connection);
});
tearDown(() async {
sut.dispose();
await cleanDb(r, connection);
});
final user = User.fromJson({
'id': '1234',
'active': true,
'lastSeen': DateTime.now(),
});
final user2 = User.fromJson({
'id': '1111',
'active': true,
'lastSeen': DateTime.now(),
});
test('sent typing notification successfully', () async {
TypingEvent typingEvent = TypingEvent(
from: user2.id!,
to: user.id!,
event: Typing.start,
);
final res = await sut.send(event: typingEvent, to: user);
expect(res, true);
});
}
Here is typing_notification.dart
:
import 'dart:async';
import 'package:chat/src/models/user.dart';
import 'package:chat/src/models/typing_event.dart';
import 'package:chat/src/services/typing/typing_notification_service_contract.dart';
import 'package:rethink_db_ns/rethink_db_ns.dart';
class TypingNotification implements ITypingNotification {
final Connection _connection;
final RethinkDb _r;
final _controller = StreamController<TypingEvent>.broadcast();
StreamSubscription? _changefeed; // added ? to this
TypingNotification(this._r, this._connection); //added this._change
@override
Future<bool> send({required TypingEvent event, required User to}) async {
if (!to.active) return false;
Map record = await _r
.table('typing_events')
.insert(event.toJson(), {'conflict:' 'update'}).run(_connection);
return record['inserted'] == 1;
}
@override
Stream<TypingEvent> subscribe(User user, List<String> userIds) {
_startReceivingTypingEvents(user, userIds);
return _controller.stream;
}
@override
void dispose() {
_changefeed?.cancel();
_controller.close();
}
_startReceivingTypingEvents(User user, List<String> userIds) {
_changefeed = _r
.table('typing_events')
.filter((event) {
return event('to')
.eq(user.id)
.and(_r.expr(userIds).contains(event('from')));
})
.changes({'include_initial': true})
.run(_connection)
.asStream()
.cast<Feed>()
.listen((event) {
event
.forEach((feedData) {
if (feedData['new_val'] == null) return;
final typing = _eventFromFeed(feedData);
_controller.sink.add(typing);
_removeEvent(typing);
})
.catchError((err) => print(err))
.onError((error, stackTrace) => print(error));
});
}
TypingEvent _eventFromFeed(feedData) {
return TypingEvent.fromJson(feedData['new_val']);
}
_removeEvent(TypingEvent event) {
_r
.table('typing_events')
.get(event.id)
.delete({'return_changes': false}).run(_connection);
}
}
Here is typing_event.dart
:
enum Typing { start, stop }
extension TypingParser on Typing {
String value() {
return toString().split('.').last;
}
static Typing fromString(String event) {
return Typing.values.firstWhere((element) => element.value() == event);
}
}
class TypingEvent {
final String from;
final String to;
final Typing event;
String? _id;
String? get id => _id;
TypingEvent({
required this.from,
required this.to,
required this.event,
});
Map<String, dynamic> toJson() => {
'from': this.from,
'to': this.to,
'event': this.event.value(),
};
factory TypingEvent.fromJson(Map<String, dynamic> json) {
var event = TypingEvent(
from: json['from'],
to: json['to'],
event: TypingParser.fromString(json['event']),
);
event._id = json['id'];
return event;
}
}
And here is typing_notification_service_contract.dart
:
import 'package:chat/src/models/typing_event.dart';
import 'package:chat/src/models/user.dart';
abstract class ITypingNotification {
Future<bool> send(
{required TypingEvent event, required User to}); // the tutorial did not include ", required User to" but I added it to prevent an error, since required User to is passed in another file
Stream<TypingEvent> subscribe(User user, List<String> userIds);
void dispose();
}
And finally, typing_event.dart
enum Typing { start, stop }
extension TypingParser on Typing {
String value() {
return toString().split('.').last;
}
static Typing fromString(String event) {
return Typing.values.firstWhere((element) => element.value() == event);
}
}
class TypingEvent {
final String from;
final String to;
final Typing event;
String? _id;
String? get id => _id;
TypingEvent({
required this.from,
required this.to,
required this.event,
});
Map<String, dynamic> toJson() => {
'from': this.from,
'to': this.to,
'event': this.event.value(),
};
factory TypingEvent.fromJson(Map<String, dynamic> json) {
var event = TypingEvent(
from: json['from'],
to: json['to'],
event: TypingParser.fromString(json['event']),
);
event._id = json['id'];
return event;
}
}
I'm a total beginner & trying to push myself to learn null safety, so there is a good chance my error is very simple and I'm just not seeing it. Can anyone point me in the right direction or offer any guidance here? I can also add more details upon request if you think it might be helpful.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试替换
为
typing_notification,.dart
第22行,它是期望的地图,可能是您的意思是:Try replacing
with
in
typing_notification,.dart
line 22, it's expecting Map, probably you meant to place ":" outside the string