|
| 1 | +--- |
| 2 | +"@tanstack/db": patch |
| 3 | +--- |
| 4 | + |
| 5 | +Improve error messages for custom getKey with joined queries |
| 6 | + |
| 7 | +Enhanced `DuplicateKeySyncError` to provide context-aware guidance when duplicate keys occur with custom `getKey` and joined queries. |
| 8 | + |
| 9 | +**The Issue:** |
| 10 | + |
| 11 | +When using custom `getKey` with joins, duplicate keys can occur if the join produces multiple rows with the same key value. This is valid for 1:1 relationships but problematic for 1:many relationships, and the previous error message didn't explain what went wrong or how to fix it. |
| 12 | + |
| 13 | +**What's New:** |
| 14 | + |
| 15 | +When a duplicate key error occurs in a live query collection that uses both custom `getKey` and joins, the error message now: |
| 16 | + |
| 17 | +- Explains that joined queries can produce multiple rows with the same key |
| 18 | +- Suggests using a composite key in your `getKey` function |
| 19 | +- Provides concrete examples of solutions |
| 20 | +- Helps distinguish between correctly structured 1:1 joins vs problematic 1:many joins |
| 21 | + |
| 22 | +**Example:** |
| 23 | + |
| 24 | +```typescript |
| 25 | +// ✅ Valid - 1:1 relationship with unique keys |
| 26 | +const userProfiles = createLiveQueryCollection({ |
| 27 | + query: (q) => |
| 28 | + q |
| 29 | + .from({ profile: profiles }) |
| 30 | + .join({ user: users }, ({ profile, user }) => |
| 31 | + eq(profile.userId, user.id) |
| 32 | + ), |
| 33 | + getKey: (profile) => profile.id, // Each profile has unique ID |
| 34 | +}) |
| 35 | +``` |
| 36 | + |
| 37 | +```typescript |
| 38 | +// ⚠️ Problematic - 1:many relationship with duplicate keys |
| 39 | +const userComments = createLiveQueryCollection({ |
| 40 | + query: (q) => |
| 41 | + q |
| 42 | + .from({ user: users }) |
| 43 | + .join({ comment: comments }, ({ user, comment }) => |
| 44 | + eq(user.id, comment.userId) |
| 45 | + ), |
| 46 | + getKey: (item) => item.userId, // Multiple comments share same userId! |
| 47 | +}) |
| 48 | + |
| 49 | +// Enhanced error message: |
| 50 | +// "Cannot insert document with key "user1" from sync because it already exists. |
| 51 | +// This collection uses a custom getKey with joined queries. Joined queries can |
| 52 | +// produce multiple rows with the same key when relationships are not 1:1. |
| 53 | +// Consider: (1) using a composite key in your getKey function (e.g., `${item.key1}-${item.key2}`), |
| 54 | +// (2) ensuring your join produces unique rows per key, or (3) removing the |
| 55 | +// custom getKey to use the default composite key behavior." |
| 56 | +``` |
0 commit comments