-
Hello everyone! Does anyone know why this code is replacing all the object values of the resulting response.data list by the values of the last object in the list? I've been struggling with this for a while and after debugging it seems that the values are being replaced somehow in the line " final query = useWatchQueryOnClient(client, watchQueryOptions);" of the file: graphql_flutter-5.1.2\lib\src\widgets\hooks\query.dart, but i still cannot find the problem. //This is the response I get from the server.
{
"data": {
"__typename": "Query",
"users": [
{
"__typename": "User",
"id": "",
"email": "[email protected]",
"phone": "1233456789",
"name": "John",
"surname1": "Smith",
"surname2": "",
"is_admin": false,
"created_at": "2021-02-01T00:00:00Z"
},
{
"__typename": "User",
"id": "",
"email": "[email protected]",
"phone": "1123456789",
"name": "Eva",
"surname1": "Fox",
"surname2": "",
"is_admin": false,
"created_at": "2021-02-01T00:00:00Z"
}
]
}
} This is the code that is replacing all the values of the user jhon smith by the values of eva fox resulting in a List of 2 objects but both objects with the values of eva fox. The values of the user jhon smith are completely replaced. **### //String from backend service**
static const String getAllUsers = """
query users {
users {
id
email
phone
name
surname1
surname2
is_admin
created_at
}
}
""";
**### //main.dart file**
void main() {
// Initialize REST and GraphQL clients
client = BrowserClient()..withCredentials = true;
final GraphQLClient graphqlClient = GraphQLClient(
link: HttpLink('http://localhost:8080/app', httpClient: client),
cache: GraphQLCache(),
);
final ValueNotifier<GraphQLClient> clientNotifier =
ValueNotifier<GraphQLClient>(graphqlClient);
runApp(MainApp(clientNotifier: clientNotifier));
}
class MainApp extends StatelessWidget {
final ValueNotifier<GraphQLClient> clientNotifier;
const MainApp({super.key, required this.clientNotifier});
@override
Widget build(BuildContext context) {
return GraphQLProvider(
client: clientNotifier,
child: MaterialApp(
debugShowCheckedModeBanner: false,
.....
**### //users.dart file -> build function of a stateful widget where I'm calling the Query method**
@override
Widget build(BuildContext context) {
return Query(
options: QueryOptions(document: gql(BackendService.getAllUsers)),
builder: (result, {fetchMore, refetch}) {
// todo what if there's a big list of users? use fetchMore
if (result.isLoading) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (result.hasException) {
return Center(
child: Text(result.exception.toString()),
);
}
List? users = result.data?['users'];
if (users == null) {
return const Text('No users found');
}
return Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Users',
style: !Responsive.isMobile(context)
? Theme.of(context).textTheme.displayLarge
: Theme.of(context).textTheme.displayMedium),
ElevatedButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder:
(BuildContext context, StateSetter setState) {
return const CreateUserModal();
},
);
},
).then((value) {
if (value != null && value) {
refetch!();
}
});
},
child: Padding(
padding: !Responsive.isMobile(context)
? Styles.defaultDesktopButtonPadding
: Styles.defaultMobileButtonPadding,
child: const Text('Create user'),
),
)
],
),
),
Expanded(
child: Container(
decoration: !Responsive.isMobile(context)
? Styles.radiusDecoration()
: null,
child: ListView.builder(
itemCount: users.length, //todo adapt
itemBuilder: (context, index) {
final isSelected = _selectedItemIndex == index;
final item = users[index];
return Column(
children: [
ListTile(
//change with user image
leading: const CircleAvatar(
backgroundImage: NetworkImage(
"https://image.freepik.com/free-photo/dreamy-girl-biting-sunglasses-looking-away-with-dreamy-face-purple-background_197531-7085.jpg"),
),
title: Row(
//TODO overflow when resizing the first time
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('${item['name']} ${item['surname1']}'),
Visibility(
visible: !Responsive.isMobile(context),
child: Text(
DateFormat('yyyy-MM-dd').format(
DateTime.parse(item['created_at'])),
),
),
Visibility(
visible: !Responsive.isMobile(context),
child: Text(
item['email'],
),
),
Text(
item['phone'],
),
],
),
subtitle: Responsive.isMobile(context)
? Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
DateFormat('yyyy-MM-dd').format(
DateTime.parse(item['created_at'])),
),
Text(
item['email'],
)
])
: null,
selected: isSelected,
onTap: () => _onItemPressed(index),
hoverColor: Theme.of(context).colorScheme.secondary,
selectedTileColor:
Theme.of(context).colorScheme.secondary,
),
if (isSelected) ...[
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton(
onPressed: () {
Navigator.pushNamed(context, '/show_lines');
},
child: const Text('Show lines'),
),
TextButton(
onPressed: _changeUserPassword,
child: const Text('Change password'),
),
TextButton(
onPressed: _deleteUser,
child: const Text('Delete'),
),
],
),
),
const Divider(),
],
],
);
},
),
),
),
],
);
},
);
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Your ID's are not unique, e.g. |
Beta Was this translation helpful? Give feedback.
Your ID's are not unique, e.g.
""
. This will treat both entries as the same object, and as such fetch the same item two times after normalization.