I'm following a tutorial series that creates a messaging app in flutter. It's slightly outdated but I'm trying to follow along with the most updated version.
I'm getting the following error:
The argument type 'Object?' can't be assigned to the parameter type 'String'.
For this code snippet: (everything after tryParse is underlined in red).
return chatsWithLatestMessage.map<Chat>((row) {
final int? unread = int.tryParse(chatsWithUnreadMessages.firstWhere(
(ele) => row['chat_id'] == ele['chat_id'],
orElse: () => {'unread': 0})['unread']);
I tried adding .toString() at the end, but then I get more errors because it's supposed to be int:
Use a non-nullable type for a final variable initialized with a non-nullable value.dartunnecessary_nullable_for_final_variable_declarations
A value of type 'String' can't be assigned to a variable of type 'int?'.
Try changing the type of the variable, or casting the right-hand type to 'int?'.dartinvalid_assignment
The argument type 'Object?' can't be assigned to the parameter type 'String'.
I also tried adding .toString() in a few other places in the code, but then got errors saying that what came after .toString() could not be used with Strings.
I think there's something more going on here with all the types. Any ideas what I can do? I'm a total beginner so odds are, the fix is something very basic that I'm just not seeing. I can edit to include more code & files upon request.
This is the whole function that the code snippet lives in:
@override
Future<List<Chat>> findAllChats() {
return _db.transaction((txn) async {
final chatsWithLatestMessage = await txn.rawQuery(''' SELECT messages.* FROM
(SELECT
chat_id, MAX(created_at) AS created_at
FROM messages
GROUP BY chat_id
) AS latest_messages
INNER JOIN messages
ON messages.chat_id = latest_messages.chat_id
AND messages.created_at = latest_messages.created_at
''');
final chatsWithUnreadMessages =
await txn.rawQuery('''SELECT chat_id, count(*) as unread
FROM messages
WHERE receipt = ?
GROUP BY chat_id
''', ['delivered']);
return chatsWithLatestMessage.map<Chat>((row) {
final int? unread = int.tryParse(chatsWithUnreadMessages.firstWhere(
(ele) => row['chat_id'] == ele['chat_id'],
orElse: () => {'unread': 0})['unread']).toString();
final chat = Chat.fromMap(row);
chat.unread = unread!;
chat.mostRecent = LocalMessage.fromMap(row);
return chat;
}).toList();
});
}
Edit: here is the chat model:
import 'package:rethink_chat/models/local_message.dart';
class Chat {
late String id; // added late
int unread = 0;
List<LocalMessage>? messages = [];
LocalMessage? mostRecent; // added late
Chat(this.id, {this.messages, this.mostRecent});
toMap() => {'id': id};
factory Chat.fromMap(Map<String, dynamic> json) => Chat(json['id']);
}
The first bug, is that you are declaring the value
final int? unread...and assign it to value that will never be anull, and it will never be null because you are using theorElsepart,To solve this, you can do one of the following:
1- declare your
unreadvalue as afinal int unread2- or remove the
orElsepart and set your chat.unread tochat.unread = unread ?? 0;The second bug, is that you've declared the
unreadvalue as anint?but you are assigning it to a string value by writingorElse: () => {'unread': 0})['unread']).toString()the.toString()and this must be removed for either of the solutions above---- Update:
The above code will return for you a List<Map<String, dynamic>>, Ex:
and after mapping them, the
firstWherewill return for you a whole record of the list, so if it found a record that metsrow['chat_id'] == ele['chat_id']it will return the whole row and the whole row will be something like:and that is an
Objectto flutter and it is not String so it cannot be parse-able!I believe that this would solve the problem