Skip to content

Complete fix: Deserialize observable query response data for all transfer modes (#2173)#2177

Merged
einari merged 1 commit into
mainfrom
fix/observable-query-full-deserialization
Apr 28, 2026
Merged

Complete fix: Deserialize observable query response data for all transfer modes (#2173)#2177
einari merged 1 commit into
mainfrom
fix/observable-query-full-deserialization

Conversation

@einari
Copy link
Copy Markdown
Contributor

@einari einari commented Apr 28, 2026

Fixed

  • Observable query response data is now properly deserialized for all transfer modes, fixing Guid fields and other strongly-typed fields losing their methods (guid.equals is not a function #2173)

Summary

The initial fix (PR #2176) only addressed delta mode changeSet deserialization, but the root cause affects all observable query responses, not just delta updates.

The Problem

When observable query responses arrive from the server, the data is transmitted as plain JSON objects. The code was never deserializing this data into model instances with their @field decorators applied. This caused:

  • Guid fields to lose their .equals() method
  • DateTime fields to be plain strings instead of Date instances
  • Other strongly-typed fields to lack their methods
  • Downstream components (like ChecklistValidation) to crash when calling methods

Root Cause

The issue exists in ALL response paths:

  1. Initial response with full data array — QueryResultWithState.fromQueryResult() just passes data through without deserializing
  2. Subsequent full-data responses (non-delta mode) — Same issue
  3. Delta mode with changeSet items — The changeSet items were deserialized in PR Fix Guid field deserialization in observable query delta reconstruction (#2173) #2176, but...
  4. Delta mode fallback (no previous result) — Falls back to un-deserialized data

The Fix

Added deserializeResponseData() function that:

  • Checks if data is an array and modelType is available
  • Calls JsonSerializer.deserializeArrayFromInstance() to instantiate all items with proper types
  • Covers all response paths in the subscription callback

Now all response data, regardless of transfer mode, is properly instantiated with @field decorators applied and methods available.

Testing

…odes

The previous delta-only fix was incomplete. The root cause affects ALL responses:
- Initial/full data responses (standard mode)
- Delta mode responses with full data fallback
- All modes where response.data needs model deserialization

The issue: response.data arrives as plain JSON objects from the server and was
never being deserialized into model instances with @field decorators applied.
This caused Guid fields and other strongly-typed fields to remain as plain
objects without their methods (e.g., Guid.equals()), breaking downstream code.

Solution: Deserialize ALL response.data using JsonSerializer.deserializeFromInstance()
whenever the observable query has a modelType, covering all code paths:

1. Initial response with full data
2. Subsequent full-data responses (non-delta mode)
3. Delta mode fallback when no previous result exists

This ensures Guid and other typed fields are properly instantiated regardless
of transfer mode or response path.
@einari einari added the patch label Apr 28, 2026
@einari einari merged commit f56ae65 into main Apr 28, 2026
6 checks passed
@einari einari deleted the fix/observable-query-full-deserialization branch April 28, 2026 09:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant