[{"data":1,"prerenderedAt":2778},["ShallowReactive",2],{"navigation_docs_en":3,"-en-recipes-optimistic-updates":342,"-en-recipes-optimistic-updates-surround":2773},[4,45,91,137,195,236,257,291,327],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Getting Started","i-lucide-rocket","/en/getting-started","en/01.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"What is Qora?","/en/getting-started/what-is-qora","en/01.getting-started/2.what-is-qora","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","/en/getting-started/installation","en/01.getting-started/3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":6},"Quick Start","/en/getting-started/quick-start","en/01.getting-started/4.quick-start",{"title":25,"path":26,"stem":27,"icon":28},"Comparison","/en/getting-started/comparison","en/01.getting-started/5.comparison","i-lucide-scale",{"title":30,"path":31,"stem":32,"icon":33},"Coming from TanStack Query","/en/getting-started/coming-from-tanstack-query","en/01.getting-started/6.coming-from-tanstack-query","i-lucide-arrow-left-right",{"title":35,"path":36,"stem":37,"icon":38},"Migrating from Other Libraries","/en/getting-started/migrating-from-other-libraries","en/01.getting-started/7.migrating-from-other-libraries","i-lucide-arrow-right-left",{"title":40,"path":41,"stem":42,"icon":43},"AI Assistants","/en/getting-started/ai-assistants","en/01.getting-started/8.ai-assistants","i-lucide-sparkles",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"Core Concepts","i-lucide-book-open","/en/core-concepts","en/02.core-concepts",[51,56,61,66,71,76,81,86],{"title":52,"path":53,"stem":54,"icon":55},"Queries","/en/core-concepts/queries","en/02.core-concepts/1.queries","i-lucide-database",{"title":57,"path":58,"stem":59,"icon":60},"Query Keys","/en/core-concepts/query-keys","en/02.core-concepts/2.query-keys","i-lucide-key-round",{"title":62,"path":63,"stem":64,"icon":65},"Query States","/en/core-concepts/query-states","en/02.core-concepts/3.query-states","i-lucide-activity",{"title":67,"path":68,"stem":69,"icon":70},"Caching","/en/core-concepts/caching","en/02.core-concepts/4.caching","i-lucide-layers-3",{"title":72,"path":73,"stem":74,"icon":75},"Stale-While-Revalidate","/en/core-concepts/stale-while-revalidate","en/02.core-concepts/5.stale-while-revalidate","i-lucide-timer-reset",{"title":77,"path":78,"stem":79,"icon":80},"Deduplication","/en/core-concepts/deduplication","en/02.core-concepts/6.deduplication","i-lucide-copy-minus",{"title":82,"path":83,"stem":84,"icon":85},"Mutations & Invalidation","/en/core-concepts/mutations","en/02.core-concepts/7.mutations","i-lucide-pencil-line",{"title":87,"path":88,"stem":89,"icon":90},"Offline & Network","/en/core-concepts/offline","en/02.core-concepts/8.offline","i-lucide-wifi-off",{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":44},"Flutter Integration","i-lucide-smartphone","/en/flutter-integration","en/03.flutter-integration",[97,102,107,112,117,122,127,132],{"title":98,"path":99,"stem":100,"icon":101},"Setup","/en/flutter-integration/setup","en/03.flutter-integration/1.setup","i-lucide-wrench",{"title":103,"path":104,"stem":105,"icon":106},"QoraScope","/en/flutter-integration/qora-scope","en/03.flutter-integration/2.qora-scope","i-lucide-share-2",{"title":108,"path":109,"stem":110,"icon":111},"QoraBuilder","/en/flutter-integration/qora-builder","en/03.flutter-integration/3.qora-builder","i-lucide-blocks",{"title":113,"path":114,"stem":115,"icon":116},"QoraMutationBuilder","/en/flutter-integration/qora-mutation-builder","en/03.flutter-integration/4.qora-mutation-builder","i-lucide-pencil",{"title":118,"path":119,"stem":120,"icon":121},"InfiniteQueryBuilder","/en/flutter-integration/infinite-query-builder","en/03.flutter-integration/5.infinite-query-builder","i-lucide-infinity",{"title":123,"path":124,"stem":125,"icon":126},"Hooks (flutter_hooks)","/en/flutter-integration/hooks","en/03.flutter-integration/6.hooks","i-lucide-anchor",{"title":128,"path":129,"stem":130,"icon":131},"Network Status Widgets","/en/flutter-integration/network-status","en/03.flutter-integration/7.network-status","i-lucide-wifi",{"title":133,"path":134,"stem":135,"icon":136},"Best Practices","/en/flutter-integration/best-practices","en/03.flutter-integration/8.best-practices","i-lucide-badge-check",{"title":138,"icon":139,"path":140,"stem":141,"children":142,"page":44},"Recipes","i-lucide-chef-hat","/en/recipes","en/04.recipes",[143,147,152,157,162,166,171,176,181,186,191],{"title":144,"path":145,"stem":146,"icon":85},"Mutations","/en/recipes/mutations","en/04.recipes/02.mutations",{"title":148,"path":149,"stem":150,"icon":151},"Optimistic Updates","/en/recipes/optimistic-updates","en/04.recipes/03.optimistic-updates","i-lucide-zap",{"title":153,"path":154,"stem":155,"icon":156},"Persistence","/en/recipes/persistence","en/04.recipes/04.persistence","i-lucide-hard-drive",{"title":158,"path":159,"stem":160,"icon":161},"Network Aware","/en/recipes/network-aware","en/04.recipes/05.network-aware","i-lucide-signal",{"title":163,"path":164,"stem":165,"icon":121},"Infinite Queries","/en/recipes/infinite-queries","en/04.recipes/06.infinite-queries",{"title":167,"path":168,"stem":169,"icon":170},"Dependent Queries","/en/recipes/dependent-queries","en/04.recipes/07.dependent-queries","i-lucide-link-2",{"title":172,"path":173,"stem":174,"icon":175},"Cancellation","/en/recipes/cancel-token","en/04.recipes/08.cancel-token","i-lucide-circle-slash",{"title":177,"path":178,"stem":179,"icon":180},"SSR Hydration","/en/recipes/ssr-hydration","en/04.recipes/09.ssr-hydration","i-lucide-server",{"title":182,"path":183,"stem":184,"icon":185},"Error Handling","/en/recipes/error-handling","en/04.recipes/10.error-handling","i-lucide-shield-alert",{"title":187,"path":188,"stem":189,"icon":190},"Testing","/en/recipes/testing","en/04.recipes/11.testing","i-lucide-flask-conical",{"title":192,"path":193,"stem":194},"Route-Level Prefetching","/en/recipes/prefetch","en/04.recipes/12.prefetch",{"title":196,"icon":197,"path":198,"stem":199,"children":200,"page":44},"API Reference","i-lucide-file-code","/en/api-reference","en/05.api-reference",[201,206,210,214,219,224,228,232],{"title":202,"path":203,"stem":204,"icon":205},"QoraClient","/en/api-reference/qora-client","en/05.api-reference/1.qora-client","i-lucide-cpu",{"title":207,"path":208,"stem":209,"icon":60},"QoraKey","/en/api-reference/qora-key","en/05.api-reference/2.qora-key",{"title":211,"path":212,"stem":213,"icon":65},"QoraState","/en/api-reference/qora-state","en/05.api-reference/3.qora-state",{"title":215,"path":216,"stem":217,"icon":218},"QoraOptions","/en/api-reference/qora-options","en/05.api-reference/4.qora-options","i-lucide-sliders-horizontal",{"title":220,"path":221,"stem":222,"icon":223},"QoraClientConfig","/en/api-reference/qora-client-config","en/05.api-reference/5.qora-client-config","i-lucide-settings-2",{"title":225,"path":226,"stem":227,"icon":85},"Mutation API","/en/api-reference/qora-mutation","en/05.api-reference/6.qora-mutation",{"title":229,"path":230,"stem":231,"icon":156},"PersistQoraClient","/en/api-reference/persist-qora-client","en/05.api-reference/7.persist-qora-client",{"title":233,"path":234,"stem":235,"icon":121},"Infinite Query","/en/api-reference/infinite-query","en/05.api-reference/8.infinite-query",{"title":237,"icon":238,"path":239,"stem":240,"children":241,"page":44},"DevTools","i-lucide-bug","/en/devtools","en/06.devtools",[242,247,252],{"title":243,"path":244,"stem":245,"icon":246},"Overview","/en/devtools/overview","en/06.devtools/1.overview","i-lucide-layout-dashboard",{"title":248,"path":249,"stem":250,"icon":251},"In-App Overlay","/en/devtools/overlay","en/06.devtools/2.overlay","i-lucide-layers",{"title":253,"path":254,"stem":255,"icon":256},"Data Serialization","/en/devtools/data-display","en/06.devtools/4.data-display","i-lucide-eye",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":44},"Third Party","i-lucide-puzzle","/en/third-party","en/07.third-party",[263,268,272,277,282,286],{"title":264,"path":265,"stem":266,"icon":267},"With Provider","/en/third-party/with-provider","en/07.third-party/1.with-provider","i-lucide-plug",{"title":269,"path":270,"stem":271,"icon":111},"With BLoC","/en/third-party/with-bloc","en/07.third-party/2.with-bloc",{"title":273,"path":274,"stem":275,"icon":276},"With Riverpod","/en/third-party/with-riverpod","en/07.third-party/3.with-riverpod","i-lucide-droplets",{"title":278,"path":279,"stem":280,"icon":281},"With RxDart","/en/third-party/with-rxdart","en/07.third-party/4.with-rxdart","i-lucide-git-branch",{"title":283,"path":284,"stem":285},"With Dio","/en/third-party/with-dio","en/07.third-party/5.with-dio",{"title":287,"path":288,"stem":289,"icon":290},"With GraphQL","/en/third-party/with-graphql","en/07.third-party/6.with-graphql","i-lucide-binary",{"title":292,"icon":190,"path":293,"stem":294,"children":295,"page":44},"Examples","/en/examples","en/08.examples",[296,301,305,310,314,318,322],{"title":297,"path":298,"stem":299,"icon":300},"Case Study: User List & Detail","/en/examples/basic-query","en/08.examples/1.basic-query","i-lucide-play-circle",{"title":302,"path":303,"stem":304,"icon":151},"Case Study: Optimistic Mutations & Rollback","/en/examples/mutations-optimistic","en/08.examples/2.mutations-optimistic",{"title":306,"path":307,"stem":308,"icon":309},"Case Study: Infinite Scroll Feed","/en/examples/infinite-scroll","en/08.examples/3.infinite-scroll","i-lucide-scroll",{"title":311,"path":312,"stem":313,"icon":90},"Case Study: Offline-First Todo App","/en/examples/offline-first","en/08.examples/4.offline-first",{"title":315,"path":316,"stem":317,"icon":161},"Case Study: Network Awareness","/en/examples/network-awareness","en/08.examples/5.network-awareness",{"title":319,"path":320,"stem":321,"icon":126},"Case Study: Hooks Integration","/en/examples/hooks-integration","en/08.examples/6.hooks-integration",{"title":323,"path":324,"stem":325,"icon":326},"Case Study: Complete Todo App","/en/examples/complete-todo-app","en/08.examples/7.complete-todo-app","i-lucide-check-square",{"title":328,"icon":329,"path":330,"stem":331,"children":332,"page":44},"Help","i-lucide-life-buoy","/en/help","en/09.help",[333,338],{"title":334,"path":335,"stem":336,"icon":337},"FAQ","/en/help/faq","en/09.help/1.faq","i-lucide-circle-help",{"title":339,"path":340,"stem":341,"icon":101},"Troubleshooting","/en/help/troubleshooting","en/09.help/2.troubleshooting",{"id":343,"title":148,"body":344,"description":2766,"extension":2767,"links":2768,"meta":2769,"navigation":2770,"path":149,"seo":2771,"stem":150,"__hash__":2772},"docs_en/en/04.recipes/03.optimistic-updates.md",{"type":345,"value":346,"toc":2752},"minimark",[347,356,359,425,428,433,936,941,1045,1047,1051,2213,2219,2243,2245,2249,2255,2370,2380,2382,2391,2394,2433,2515,2517,2520,2524,2640,2644,2712,2714,2718,2748],[348,349,350,351,355],"p",{},"An ",[352,353,354],"strong",{},"optimistic update"," applies a local state change before server confirmation. If the request fails, the previous data is restored.",[348,357,358],{},"Qora provides three primitives that make this pattern straightforward:",[360,361,362,375],"table",{},[363,364,365],"thead",{},[366,367,368,372],"tr",{},[369,370,371],"th",{},"Method",[369,373,374],{},"Description",[376,377,378,402,412],"tbody",{},[366,379,380,387],{},[381,382,383],"td",{},[384,385,386],"code",{},"client.getQueryData\u003CT>(key)",[381,388,389,390,393,394,397,398,401],{},"Snapshot the current data (",[384,391,392],{},"T?","), or ",[384,395,396],{},"null"," if not in ",[384,399,400],{},"Success"," state",[366,403,404,409],{},[381,405,406],{},[384,407,408],{},"client.setQueryData\u003CT>(key, data)",[381,410,411],{},"Push data directly into the cache: all subscribed widgets update instantly",[366,413,414,419],{},[381,415,416],{},[384,417,418],{},"client.restoreQueryData\u003CT>(key, snapshot)",[381,420,421,422,424],{},"Restore a previously snapshotted data value; ",[384,423,396],{}," removes the entry",[426,427],"hr",{},[429,430,432],"h2",{"id":431},"the-pattern","The Pattern",[434,435,441],"pre",{"className":436,"code":437,"filename":438,"language":439,"meta":440,"style":440},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","Future\u003Cvoid> updateUserName(BuildContext context, int userId, String newName) async {\n  final client = context.qora;\n  final key = ['users', userId];\n\n  // 1. Snapshot the current data for rollback\n  final previousUser = client.getQueryData\u003CUser>(key);\n\n  try {\n    // 2. Apply the optimistic update: UI reflects the change instantly\n    if (previousUser != null) {\n      client.setQueryData\u003CUser>(key, previousUser.copyWith(name: newName));\n    }\n\n    // 3. Fire the mutation\n    final updatedUser = await UserApi.updateUser(userId, newName);\n\n    // 4. Confirm with the authoritative server response\n    client.setQueryData\u003CUser>(key, updatedUser);\n\n    // 5. Invalidate related queries (e.g. the list that shows the name)\n    client.invalidateWhere((key) => key.firstOrNull == 'users');\n  } catch (error) {\n    // 6. Rollback to the pre-mutation data\n    client.restoreQueryData\u003CUser>(key, previousUser);\n\n    if (context.mounted) {\n      ScaffoldMessenger.of(context).showSnackBar(\n        SnackBar(content: Text('Failed to update: $error')),\n      );\n    }\n  }\n}\n","update_user.dart","dart","",[384,442,443,501,524,548,555,562,590,595,603,609,627,666,672,677,683,715,720,726,749,754,760,795,807,813,836,841,854,876,911,919,924,930],{"__ignoreMap":440},[444,445,448,452,456,460,463,467,470,473,476,480,483,486,488,491,494,498],"span",{"class":446,"line":447},"line",1,[444,449,451],{"class":450},"sBMFI","Future",[444,453,455],{"class":454},"sTEyZ","\u003C",[444,457,459],{"class":458},"spNyl","void",[444,461,462],{"class":454},"> ",[444,464,466],{"class":465},"s2Zo4","updateUserName",[444,468,469],{"class":454},"(",[444,471,472],{"class":450},"BuildContext",[444,474,475],{"class":454}," context",[444,477,479],{"class":478},"sMK4o",",",[444,481,482],{"class":450}," int",[444,484,485],{"class":454}," userId",[444,487,479],{"class":478},[444,489,490],{"class":450}," String",[444,492,493],{"class":454}," newName) ",[444,495,497],{"class":496},"s7zQu","async",[444,499,500],{"class":454}," {\n",[444,502,504,507,510,513,515,518,521],{"class":446,"line":503},2,[444,505,506],{"class":458},"  final",[444,508,509],{"class":454}," client ",[444,511,512],{"class":478},"=",[444,514,475],{"class":454},[444,516,517],{"class":478},".",[444,519,520],{"class":454},"qora",[444,522,523],{"class":478},";\n",[444,525,527,529,532,534,537,541,543,546],{"class":446,"line":526},3,[444,528,506],{"class":458},[444,530,531],{"class":454}," key ",[444,533,512],{"class":478},[444,535,536],{"class":454}," [",[444,538,540],{"class":539},"sfazB","'users'",[444,542,479],{"class":478},[444,544,545],{"class":454}," userId]",[444,547,523],{"class":478},[444,549,551],{"class":446,"line":550},4,[444,552,554],{"emptyLinePlaceholder":553},true,"\n",[444,556,558],{"class":446,"line":557},5,[444,559,561],{"class":560},"sHwdD","  // 1. Snapshot the current data for rollback\n",[444,563,565,567,570,572,575,577,580,582,585,588],{"class":446,"line":564},6,[444,566,506],{"class":458},[444,568,569],{"class":454}," previousUser ",[444,571,512],{"class":478},[444,573,574],{"class":454}," client",[444,576,517],{"class":478},[444,578,579],{"class":465},"getQueryData",[444,581,455],{"class":454},[444,583,584],{"class":450},"User",[444,586,587],{"class":454},">(key)",[444,589,523],{"class":478},[444,591,593],{"class":446,"line":592},7,[444,594,554],{"emptyLinePlaceholder":553},[444,596,598,601],{"class":446,"line":597},8,[444,599,600],{"class":496},"  try",[444,602,500],{"class":454},[444,604,606],{"class":446,"line":605},9,[444,607,608],{"class":560},"    // 2. Apply the optimistic update: UI reflects the change instantly\n",[444,610,612,615,618,621,624],{"class":446,"line":611},10,[444,613,614],{"class":496},"    if",[444,616,617],{"class":454}," (previousUser ",[444,619,620],{"class":478},"!=",[444,622,623],{"class":478}," null",[444,625,626],{"class":454},") {\n",[444,628,630,633,635,638,640,642,645,647,650,652,655,658,661,664],{"class":446,"line":629},11,[444,631,632],{"class":454},"      client",[444,634,517],{"class":478},[444,636,637],{"class":465},"setQueryData",[444,639,455],{"class":454},[444,641,584],{"class":450},[444,643,644],{"class":454},">(key",[444,646,479],{"class":478},[444,648,649],{"class":454}," previousUser",[444,651,517],{"class":478},[444,653,654],{"class":465},"copyWith",[444,656,657],{"class":454},"(name",[444,659,660],{"class":478},":",[444,662,663],{"class":454}," newName))",[444,665,523],{"class":478},[444,667,669],{"class":446,"line":668},12,[444,670,671],{"class":454},"    }\n",[444,673,675],{"class":446,"line":674},13,[444,676,554],{"emptyLinePlaceholder":553},[444,678,680],{"class":446,"line":679},14,[444,681,682],{"class":560},"    // 3. Fire the mutation\n",[444,684,686,689,692,694,697,700,702,705,708,710,713],{"class":446,"line":685},15,[444,687,688],{"class":458},"    final",[444,690,691],{"class":454}," updatedUser ",[444,693,512],{"class":478},[444,695,696],{"class":496}," await",[444,698,699],{"class":450}," UserApi",[444,701,517],{"class":478},[444,703,704],{"class":465},"updateUser",[444,706,707],{"class":454},"(userId",[444,709,479],{"class":478},[444,711,712],{"class":454}," newName)",[444,714,523],{"class":478},[444,716,718],{"class":446,"line":717},16,[444,719,554],{"emptyLinePlaceholder":553},[444,721,723],{"class":446,"line":722},17,[444,724,725],{"class":560},"    // 4. Confirm with the authoritative server response\n",[444,727,729,732,734,736,738,740,742,744,747],{"class":446,"line":728},18,[444,730,731],{"class":454},"    client",[444,733,517],{"class":478},[444,735,637],{"class":465},[444,737,455],{"class":454},[444,739,584],{"class":450},[444,741,644],{"class":454},[444,743,479],{"class":478},[444,745,746],{"class":454}," updatedUser)",[444,748,523],{"class":478},[444,750,752],{"class":446,"line":751},19,[444,753,554],{"emptyLinePlaceholder":553},[444,755,757],{"class":446,"line":756},20,[444,758,759],{"class":560},"    // 5. Invalidate related queries (e.g. the list that shows the name)\n",[444,761,763,765,767,770,773,776,779,781,784,787,790,793],{"class":446,"line":762},21,[444,764,731],{"class":454},[444,766,517],{"class":478},[444,768,769],{"class":465},"invalidateWhere",[444,771,772],{"class":454},"((key) ",[444,774,775],{"class":478},"=>",[444,777,778],{"class":454}," key",[444,780,517],{"class":478},[444,782,783],{"class":454},"firstOrNull ",[444,785,786],{"class":478},"==",[444,788,789],{"class":539}," 'users'",[444,791,792],{"class":454},")",[444,794,523],{"class":478},[444,796,798,801,804],{"class":446,"line":797},22,[444,799,800],{"class":454},"  } ",[444,802,803],{"class":496},"catch",[444,805,806],{"class":454}," (error) {\n",[444,808,810],{"class":446,"line":809},23,[444,811,812],{"class":560},"    // 6. Rollback to the pre-mutation data\n",[444,814,816,818,820,823,825,827,829,831,834],{"class":446,"line":815},24,[444,817,731],{"class":454},[444,819,517],{"class":478},[444,821,822],{"class":465},"restoreQueryData",[444,824,455],{"class":454},[444,826,584],{"class":450},[444,828,644],{"class":454},[444,830,479],{"class":478},[444,832,833],{"class":454}," previousUser)",[444,835,523],{"class":478},[444,837,839],{"class":446,"line":838},25,[444,840,554],{"emptyLinePlaceholder":553},[444,842,844,846,849,851],{"class":446,"line":843},26,[444,845,614],{"class":496},[444,847,848],{"class":454}," (context",[444,850,517],{"class":478},[444,852,853],{"class":454},"mounted) {\n",[444,855,857,860,862,865,868,870,873],{"class":446,"line":856},27,[444,858,859],{"class":450},"      ScaffoldMessenger",[444,861,517],{"class":478},[444,863,864],{"class":465},"of",[444,866,867],{"class":454},"(context)",[444,869,517],{"class":478},[444,871,872],{"class":465},"showSnackBar",[444,874,875],{"class":454},"(\n",[444,877,879,882,885,887,890,892,895,898,902,905,908],{"class":446,"line":878},28,[444,880,881],{"class":450},"        SnackBar",[444,883,884],{"class":454},"(content",[444,886,660],{"class":478},[444,888,889],{"class":450}," Text",[444,891,469],{"class":454},[444,893,894],{"class":539},"'Failed to update: ",[444,896,897],{"class":454},"$",[444,899,901],{"class":900},"sHdIc","error",[444,903,904],{"class":539},"'",[444,906,907],{"class":454},"))",[444,909,910],{"class":478},",\n",[444,912,914,917],{"class":446,"line":913},29,[444,915,916],{"class":454},"      )",[444,918,523],{"class":478},[444,920,922],{"class":446,"line":921},30,[444,923,671],{"class":454},[444,925,927],{"class":446,"line":926},31,[444,928,929],{"class":454},"  }\n",[444,931,933],{"class":446,"line":932},32,[444,934,935],{"class":454},"}\n",[937,938,940],"h3",{"id":939},"step-by-step","Step-by-step",[360,942,943,956],{},[363,944,945],{},[366,946,947,950,953],{},[369,948,949],{},"Step",[369,951,952],{},"Call",[369,954,955],{},"Effect",[376,957,958,977,993,1006,1019,1032],{},[366,959,960,963,968],{},[381,961,962],{},"1",[381,964,965],{},[384,966,967],{},"getQueryData(key)",[381,969,970,971,973,974,976],{},"Returns the current ",[384,972,392],{}," data value, or ",[384,975,396],{}," if not in cache",[366,978,979,982,987],{},[381,980,981],{},"2",[381,983,984],{},[384,985,986],{},"setQueryData(key, optimisticData)",[381,988,989,990,992],{},"Cache updated → all active ",[384,991,108],{}," widgets rebuild",[366,994,995,998,1003],{},[381,996,997],{},"3",[381,999,1000],{},[384,1001,1002],{},"UserApi.updateUser(...)",[381,1004,1005],{},"Network request in flight",[366,1007,1008,1011,1016],{},[381,1009,1010],{},"4",[381,1012,1013],{},[384,1014,1015],{},"setQueryData(key, serverData)",[381,1017,1018],{},"Cache confirmed with authoritative data from the server",[366,1020,1021,1024,1029],{},[381,1022,1023],{},"5",[381,1025,1026],{},[384,1027,1028],{},"invalidateWhere(...)",[381,1030,1031],{},"Related queries (e.g. the user list) will refetch",[366,1033,1034,1037,1042],{},[381,1035,1036],{},"6",[381,1038,1039],{},[384,1040,1041],{},"restoreQueryData(key, previousUser)",[381,1043,1044],{},"Cache reverted → UI snaps back to the pre-mutation state",[426,1046],{},[429,1048,1050],{"id":1049},"full-example-edit-profile-screen","Full Example: Edit Profile Screen",[434,1052,1055],{"className":436,"code":1053,"filename":1054,"language":439,"meta":440,"style":440},"class EditProfileScreen extends StatefulWidget {\n  final int userId;\n\n  const EditProfileScreen({super.key, required this.userId});\n\n  @override\n  State\u003CEditProfileScreen> createState() => _EditProfileScreenState();\n}\n\nclass _EditProfileScreenState extends State\u003CEditProfileScreen> {\n  late final TextEditingController _nameController;\n  bool _isSaving = false;\n\n  @override\n  void initState() {\n    super.initState();\n    final currentUser = context.qora.getQueryData\u003CUser>(['users', widget.userId]);\n    _nameController = TextEditingController(text: currentUser?.name ?? '');\n  }\n\n  @override\n  void dispose() {\n    _nameController.dispose();\n    super.dispose();\n  }\n\n  Future\u003Cvoid> _save() async {\n    if (_isSaving) return;\n    setState(() => _isSaving = true);\n\n    final client = context.qora;\n    final key = ['users', widget.userId];\n    final previousUser = client.getQueryData\u003CUser>(key);\n\n    try {\n      // Optimistic update\n      if (previousUser != null) {\n        client.setQueryData\u003CUser>(\n          key,\n          previousUser.copyWith(name: _nameController.text),\n        );\n      }\n\n      final updated = await UserApi.updateUser(\n        widget.userId,\n        _nameController.text,\n      );\n\n      client.setQueryData\u003CUser>(key, updated);\n      client.invalidateWhere((k) => k.firstOrNull == 'users');\n\n      if (mounted) Navigator.pop(context);\n    } catch (error) {\n      client.restoreQueryData\u003CUser>(key, previousUser);\n\n      if (mounted) {\n        ScaffoldMessenger.of(context).showSnackBar(\n          SnackBar(content: Text('Save failed: $error')),\n        );\n        setState(() => _isSaving = false);\n      }\n    }\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Edit Profile'),\n        actions: [\n          TextButton(\n            onPressed: _isSaving ? null : _save,\n            child: _isSaving\n                ? const SizedBox(\n                    width: 16,\n                    height: 16,\n                    child: CircularProgressIndicator(strokeWidth: 2),\n                  )\n                : const Text('Save'),\n          ),\n        ],\n      ),\n      body: Padding(\n        padding: const EdgeInsets.all(16),\n        child: TextField(\n          controller: _nameController,\n          decoration: const InputDecoration(labelText: 'Name'),\n        ),\n      ),\n    );\n  }\n}\n","screens/edit_profile_screen.dart",[384,1056,1057,1073,1083,1087,1117,1121,1126,1154,1158,1162,1180,1196,1209,1213,1217,1228,1242,1282,1315,1319,1323,1327,1336,1350,1362,1366,1370,1390,1402,1423,1427,1443,1466,1489,1494,1502,1508,1522,1539,1547,1570,1578,1584,1589,1610,1623,1636,1643,1648,1670,1699,1704,1724,1734,1755,1760,1768,1786,1813,1820,1841,1846,1851,1856,1861,1866,1882,1893,1906,1928,1939,1947,1970,1981,1994,2008,2020,2043,2049,2068,2076,2084,2091,2104,2131,2144,2156,2181,2188,2195,2203,2208],{"__ignoreMap":440},[444,1058,1059,1062,1065,1068,1071],{"class":446,"line":447},[444,1060,1061],{"class":478},"class",[444,1063,1064],{"class":450}," EditProfileScreen",[444,1066,1067],{"class":478}," extends",[444,1069,1070],{"class":450}," StatefulWidget",[444,1072,500],{"class":454},[444,1074,1075,1077,1079,1081],{"class":446,"line":503},[444,1076,506],{"class":458},[444,1078,482],{"class":450},[444,1080,485],{"class":454},[444,1082,523],{"class":478},[444,1084,1085],{"class":446,"line":526},[444,1086,554],{"emptyLinePlaceholder":553},[444,1088,1089,1092,1094,1097,1099,1102,1104,1107,1110,1112,1115],{"class":446,"line":550},[444,1090,1091],{"class":458},"  const",[444,1093,1064],{"class":450},[444,1095,1096],{"class":454},"({super",[444,1098,517],{"class":478},[444,1100,1101],{"class":454},"key",[444,1103,479],{"class":478},[444,1105,1106],{"class":458}," required",[444,1108,1109],{"class":454}," this",[444,1111,517],{"class":478},[444,1113,1114],{"class":454},"userId})",[444,1116,523],{"class":478},[444,1118,1119],{"class":446,"line":557},[444,1120,554],{"emptyLinePlaceholder":553},[444,1122,1123],{"class":446,"line":564},[444,1124,1125],{"class":458},"  @override\n",[444,1127,1128,1131,1133,1136,1138,1141,1144,1146,1149,1152],{"class":446,"line":592},[444,1129,1130],{"class":450},"  State",[444,1132,455],{"class":454},[444,1134,1135],{"class":450},"EditProfileScreen",[444,1137,462],{"class":454},[444,1139,1140],{"class":465},"createState",[444,1142,1143],{"class":454},"() ",[444,1145,775],{"class":478},[444,1147,1148],{"class":450}," _EditProfileScreenState",[444,1150,1151],{"class":454},"()",[444,1153,523],{"class":478},[444,1155,1156],{"class":446,"line":597},[444,1157,935],{"class":454},[444,1159,1160],{"class":446,"line":605},[444,1161,554],{"emptyLinePlaceholder":553},[444,1163,1164,1166,1168,1170,1173,1175,1177],{"class":446,"line":611},[444,1165,1061],{"class":478},[444,1167,1148],{"class":450},[444,1169,1067],{"class":478},[444,1171,1172],{"class":450}," State",[444,1174,455],{"class":454},[444,1176,1135],{"class":450},[444,1178,1179],{"class":454},"> {\n",[444,1181,1182,1185,1188,1191,1194],{"class":446,"line":629},[444,1183,1184],{"class":458},"  late",[444,1186,1187],{"class":458}," final",[444,1189,1190],{"class":450}," TextEditingController",[444,1192,1193],{"class":454}," _nameController",[444,1195,523],{"class":478},[444,1197,1198,1201,1204,1206],{"class":446,"line":668},[444,1199,1200],{"class":450},"  bool",[444,1202,1203],{"class":454}," _isSaving ",[444,1205,512],{"class":478},[444,1207,1208],{"class":478}," false;\n",[444,1210,1211],{"class":446,"line":674},[444,1212,554],{"emptyLinePlaceholder":553},[444,1214,1215],{"class":446,"line":679},[444,1216,1125],{"class":458},[444,1218,1219,1222,1225],{"class":446,"line":685},[444,1220,1221],{"class":458},"  void",[444,1223,1224],{"class":465}," initState",[444,1226,1227],{"class":454},"() {\n",[444,1229,1230,1233,1235,1238,1240],{"class":446,"line":717},[444,1231,1232],{"class":454},"    super",[444,1234,517],{"class":478},[444,1236,1237],{"class":465},"initState",[444,1239,1151],{"class":454},[444,1241,523],{"class":478},[444,1243,1244,1246,1249,1251,1253,1255,1257,1259,1261,1263,1265,1268,1270,1272,1275,1277,1280],{"class":446,"line":722},[444,1245,688],{"class":458},[444,1247,1248],{"class":454}," currentUser ",[444,1250,512],{"class":478},[444,1252,475],{"class":454},[444,1254,517],{"class":478},[444,1256,520],{"class":454},[444,1258,517],{"class":478},[444,1260,579],{"class":465},[444,1262,455],{"class":454},[444,1264,584],{"class":450},[444,1266,1267],{"class":454},">([",[444,1269,540],{"class":539},[444,1271,479],{"class":478},[444,1273,1274],{"class":454}," widget",[444,1276,517],{"class":478},[444,1278,1279],{"class":454},"userId])",[444,1281,523],{"class":478},[444,1283,1284,1287,1289,1291,1294,1296,1299,1302,1305,1308,1311,1313],{"class":446,"line":728},[444,1285,1286],{"class":454},"    _nameController ",[444,1288,512],{"class":478},[444,1290,1190],{"class":450},[444,1292,1293],{"class":454},"(text",[444,1295,660],{"class":478},[444,1297,1298],{"class":454}," currentUser",[444,1300,1301],{"class":478},"?.",[444,1303,1304],{"class":454},"name ",[444,1306,1307],{"class":478},"??",[444,1309,1310],{"class":539}," ''",[444,1312,792],{"class":454},[444,1314,523],{"class":478},[444,1316,1317],{"class":446,"line":751},[444,1318,929],{"class":454},[444,1320,1321],{"class":446,"line":756},[444,1322,554],{"emptyLinePlaceholder":553},[444,1324,1325],{"class":446,"line":762},[444,1326,1125],{"class":458},[444,1328,1329,1331,1334],{"class":446,"line":797},[444,1330,1221],{"class":458},[444,1332,1333],{"class":465}," dispose",[444,1335,1227],{"class":454},[444,1337,1338,1341,1343,1346,1348],{"class":446,"line":809},[444,1339,1340],{"class":454},"    _nameController",[444,1342,517],{"class":478},[444,1344,1345],{"class":465},"dispose",[444,1347,1151],{"class":454},[444,1349,523],{"class":478},[444,1351,1352,1354,1356,1358,1360],{"class":446,"line":815},[444,1353,1232],{"class":454},[444,1355,517],{"class":478},[444,1357,1345],{"class":465},[444,1359,1151],{"class":454},[444,1361,523],{"class":478},[444,1363,1364],{"class":446,"line":838},[444,1365,929],{"class":454},[444,1367,1368],{"class":446,"line":843},[444,1369,554],{"emptyLinePlaceholder":553},[444,1371,1372,1375,1377,1379,1381,1384,1386,1388],{"class":446,"line":856},[444,1373,1374],{"class":450},"  Future",[444,1376,455],{"class":454},[444,1378,459],{"class":458},[444,1380,462],{"class":454},[444,1382,1383],{"class":465},"_save",[444,1385,1143],{"class":454},[444,1387,497],{"class":496},[444,1389,500],{"class":454},[444,1391,1392,1394,1397,1400],{"class":446,"line":878},[444,1393,614],{"class":496},[444,1395,1396],{"class":454}," (_isSaving) ",[444,1398,1399],{"class":496},"return",[444,1401,523],{"class":478},[444,1403,1404,1407,1410,1412,1414,1416,1419,1421],{"class":446,"line":913},[444,1405,1406],{"class":465},"    setState",[444,1408,1409],{"class":454},"(() ",[444,1411,775],{"class":478},[444,1413,1203],{"class":454},[444,1415,512],{"class":478},[444,1417,1418],{"class":478}," true",[444,1420,792],{"class":454},[444,1422,523],{"class":478},[444,1424,1425],{"class":446,"line":921},[444,1426,554],{"emptyLinePlaceholder":553},[444,1428,1429,1431,1433,1435,1437,1439,1441],{"class":446,"line":926},[444,1430,688],{"class":458},[444,1432,509],{"class":454},[444,1434,512],{"class":478},[444,1436,475],{"class":454},[444,1438,517],{"class":478},[444,1440,520],{"class":454},[444,1442,523],{"class":478},[444,1444,1445,1447,1449,1451,1453,1455,1457,1459,1461,1464],{"class":446,"line":932},[444,1446,688],{"class":458},[444,1448,531],{"class":454},[444,1450,512],{"class":478},[444,1452,536],{"class":454},[444,1454,540],{"class":539},[444,1456,479],{"class":478},[444,1458,1274],{"class":454},[444,1460,517],{"class":478},[444,1462,1463],{"class":454},"userId]",[444,1465,523],{"class":478},[444,1467,1469,1471,1473,1475,1477,1479,1481,1483,1485,1487],{"class":446,"line":1468},33,[444,1470,688],{"class":458},[444,1472,569],{"class":454},[444,1474,512],{"class":478},[444,1476,574],{"class":454},[444,1478,517],{"class":478},[444,1480,579],{"class":465},[444,1482,455],{"class":454},[444,1484,584],{"class":450},[444,1486,587],{"class":454},[444,1488,523],{"class":478},[444,1490,1492],{"class":446,"line":1491},34,[444,1493,554],{"emptyLinePlaceholder":553},[444,1495,1497,1500],{"class":446,"line":1496},35,[444,1498,1499],{"class":496},"    try",[444,1501,500],{"class":454},[444,1503,1505],{"class":446,"line":1504},36,[444,1506,1507],{"class":560},"      // Optimistic update\n",[444,1509,1511,1514,1516,1518,1520],{"class":446,"line":1510},37,[444,1512,1513],{"class":496},"      if",[444,1515,617],{"class":454},[444,1517,620],{"class":478},[444,1519,623],{"class":478},[444,1521,626],{"class":454},[444,1523,1525,1528,1530,1532,1534,1536],{"class":446,"line":1524},38,[444,1526,1527],{"class":454},"        client",[444,1529,517],{"class":478},[444,1531,637],{"class":465},[444,1533,455],{"class":454},[444,1535,584],{"class":450},[444,1537,1538],{"class":454},">(\n",[444,1540,1542,1545],{"class":446,"line":1541},39,[444,1543,1544],{"class":454},"          key",[444,1546,910],{"class":478},[444,1548,1550,1553,1555,1557,1559,1561,1563,1565,1568],{"class":446,"line":1549},40,[444,1551,1552],{"class":454},"          previousUser",[444,1554,517],{"class":478},[444,1556,654],{"class":465},[444,1558,657],{"class":454},[444,1560,660],{"class":478},[444,1562,1193],{"class":454},[444,1564,517],{"class":478},[444,1566,1567],{"class":454},"text)",[444,1569,910],{"class":478},[444,1571,1573,1576],{"class":446,"line":1572},41,[444,1574,1575],{"class":454},"        )",[444,1577,523],{"class":478},[444,1579,1581],{"class":446,"line":1580},42,[444,1582,1583],{"class":454},"      }\n",[444,1585,1587],{"class":446,"line":1586},43,[444,1588,554],{"emptyLinePlaceholder":553},[444,1590,1592,1595,1598,1600,1602,1604,1606,1608],{"class":446,"line":1591},44,[444,1593,1594],{"class":458},"      final",[444,1596,1597],{"class":454}," updated ",[444,1599,512],{"class":478},[444,1601,696],{"class":496},[444,1603,699],{"class":450},[444,1605,517],{"class":478},[444,1607,704],{"class":465},[444,1609,875],{"class":454},[444,1611,1613,1616,1618,1621],{"class":446,"line":1612},45,[444,1614,1615],{"class":454},"        widget",[444,1617,517],{"class":478},[444,1619,1620],{"class":454},"userId",[444,1622,910],{"class":478},[444,1624,1626,1629,1631,1634],{"class":446,"line":1625},46,[444,1627,1628],{"class":454},"        _nameController",[444,1630,517],{"class":478},[444,1632,1633],{"class":454},"text",[444,1635,910],{"class":478},[444,1637,1639,1641],{"class":446,"line":1638},47,[444,1640,916],{"class":454},[444,1642,523],{"class":478},[444,1644,1646],{"class":446,"line":1645},48,[444,1647,554],{"emptyLinePlaceholder":553},[444,1649,1651,1653,1655,1657,1659,1661,1663,1665,1668],{"class":446,"line":1650},49,[444,1652,632],{"class":454},[444,1654,517],{"class":478},[444,1656,637],{"class":465},[444,1658,455],{"class":454},[444,1660,584],{"class":450},[444,1662,644],{"class":454},[444,1664,479],{"class":478},[444,1666,1667],{"class":454}," updated)",[444,1669,523],{"class":478},[444,1671,1673,1675,1677,1679,1682,1684,1687,1689,1691,1693,1695,1697],{"class":446,"line":1672},50,[444,1674,632],{"class":454},[444,1676,517],{"class":478},[444,1678,769],{"class":465},[444,1680,1681],{"class":454},"((k) ",[444,1683,775],{"class":478},[444,1685,1686],{"class":454}," k",[444,1688,517],{"class":478},[444,1690,783],{"class":454},[444,1692,786],{"class":478},[444,1694,789],{"class":539},[444,1696,792],{"class":454},[444,1698,523],{"class":478},[444,1700,1702],{"class":446,"line":1701},51,[444,1703,554],{"emptyLinePlaceholder":553},[444,1705,1707,1709,1712,1715,1717,1720,1722],{"class":446,"line":1706},52,[444,1708,1513],{"class":496},[444,1710,1711],{"class":454}," (mounted) ",[444,1713,1714],{"class":450},"Navigator",[444,1716,517],{"class":478},[444,1718,1719],{"class":465},"pop",[444,1721,867],{"class":454},[444,1723,523],{"class":478},[444,1725,1727,1730,1732],{"class":446,"line":1726},53,[444,1728,1729],{"class":454},"    } ",[444,1731,803],{"class":496},[444,1733,806],{"class":454},[444,1735,1737,1739,1741,1743,1745,1747,1749,1751,1753],{"class":446,"line":1736},54,[444,1738,632],{"class":454},[444,1740,517],{"class":478},[444,1742,822],{"class":465},[444,1744,455],{"class":454},[444,1746,584],{"class":450},[444,1748,644],{"class":454},[444,1750,479],{"class":478},[444,1752,833],{"class":454},[444,1754,523],{"class":478},[444,1756,1758],{"class":446,"line":1757},55,[444,1759,554],{"emptyLinePlaceholder":553},[444,1761,1763,1765],{"class":446,"line":1762},56,[444,1764,1513],{"class":496},[444,1766,1767],{"class":454}," (mounted) {\n",[444,1769,1771,1774,1776,1778,1780,1782,1784],{"class":446,"line":1770},57,[444,1772,1773],{"class":450},"        ScaffoldMessenger",[444,1775,517],{"class":478},[444,1777,864],{"class":465},[444,1779,867],{"class":454},[444,1781,517],{"class":478},[444,1783,872],{"class":465},[444,1785,875],{"class":454},[444,1787,1789,1792,1794,1796,1798,1800,1803,1805,1807,1809,1811],{"class":446,"line":1788},58,[444,1790,1791],{"class":450},"          SnackBar",[444,1793,884],{"class":454},[444,1795,660],{"class":478},[444,1797,889],{"class":450},[444,1799,469],{"class":454},[444,1801,1802],{"class":539},"'Save failed: ",[444,1804,897],{"class":454},[444,1806,901],{"class":900},[444,1808,904],{"class":539},[444,1810,907],{"class":454},[444,1812,910],{"class":478},[444,1814,1816,1818],{"class":446,"line":1815},59,[444,1817,1575],{"class":454},[444,1819,523],{"class":478},[444,1821,1823,1826,1828,1830,1832,1834,1837,1839],{"class":446,"line":1822},60,[444,1824,1825],{"class":465},"        setState",[444,1827,1409],{"class":454},[444,1829,775],{"class":478},[444,1831,1203],{"class":454},[444,1833,512],{"class":478},[444,1835,1836],{"class":478}," false",[444,1838,792],{"class":454},[444,1840,523],{"class":478},[444,1842,1844],{"class":446,"line":1843},61,[444,1845,1583],{"class":454},[444,1847,1849],{"class":446,"line":1848},62,[444,1850,671],{"class":454},[444,1852,1854],{"class":446,"line":1853},63,[444,1855,929],{"class":454},[444,1857,1859],{"class":446,"line":1858},64,[444,1860,554],{"emptyLinePlaceholder":553},[444,1862,1864],{"class":446,"line":1863},65,[444,1865,1125],{"class":458},[444,1867,1869,1872,1875,1877,1879],{"class":446,"line":1868},66,[444,1870,1871],{"class":450},"  Widget",[444,1873,1874],{"class":465}," build",[444,1876,469],{"class":454},[444,1878,472],{"class":450},[444,1880,1881],{"class":454}," context) {\n",[444,1883,1885,1888,1891],{"class":446,"line":1884},67,[444,1886,1887],{"class":496},"    return",[444,1889,1890],{"class":450}," Scaffold",[444,1892,875],{"class":454},[444,1894,1896,1899,1901,1904],{"class":446,"line":1895},68,[444,1897,1898],{"class":454},"      appBar",[444,1900,660],{"class":478},[444,1902,1903],{"class":450}," AppBar",[444,1905,875],{"class":454},[444,1907,1909,1912,1914,1917,1919,1921,1924,1926],{"class":446,"line":1908},69,[444,1910,1911],{"class":454},"        title",[444,1913,660],{"class":478},[444,1915,1916],{"class":458}," const",[444,1918,889],{"class":450},[444,1920,469],{"class":454},[444,1922,1923],{"class":539},"'Edit Profile'",[444,1925,792],{"class":454},[444,1927,910],{"class":478},[444,1929,1931,1934,1936],{"class":446,"line":1930},70,[444,1932,1933],{"class":454},"        actions",[444,1935,660],{"class":478},[444,1937,1938],{"class":454}," [\n",[444,1940,1942,1945],{"class":446,"line":1941},71,[444,1943,1944],{"class":450},"          TextButton",[444,1946,875],{"class":454},[444,1948,1950,1953,1955,1957,1960,1962,1965,1968],{"class":446,"line":1949},72,[444,1951,1952],{"class":454},"            onPressed",[444,1954,660],{"class":478},[444,1956,1203],{"class":454},[444,1958,1959],{"class":478},"?",[444,1961,623],{"class":478},[444,1963,1964],{"class":478}," :",[444,1966,1967],{"class":454}," _save",[444,1969,910],{"class":478},[444,1971,1973,1976,1978],{"class":446,"line":1972},73,[444,1974,1975],{"class":454},"            child",[444,1977,660],{"class":478},[444,1979,1980],{"class":454}," _isSaving\n",[444,1982,1984,1987,1989,1992],{"class":446,"line":1983},74,[444,1985,1986],{"class":478},"                ?",[444,1988,1916],{"class":458},[444,1990,1991],{"class":450}," SizedBox",[444,1993,875],{"class":454},[444,1995,1997,2000,2002,2006],{"class":446,"line":1996},75,[444,1998,1999],{"class":454},"                    width",[444,2001,660],{"class":478},[444,2003,2005],{"class":2004},"sbssI"," 16",[444,2007,910],{"class":478},[444,2009,2011,2014,2016,2018],{"class":446,"line":2010},76,[444,2012,2013],{"class":454},"                    height",[444,2015,660],{"class":478},[444,2017,2005],{"class":2004},[444,2019,910],{"class":478},[444,2021,2023,2026,2028,2031,2034,2036,2039,2041],{"class":446,"line":2022},77,[444,2024,2025],{"class":454},"                    child",[444,2027,660],{"class":478},[444,2029,2030],{"class":450}," CircularProgressIndicator",[444,2032,2033],{"class":454},"(strokeWidth",[444,2035,660],{"class":478},[444,2037,2038],{"class":2004}," 2",[444,2040,792],{"class":454},[444,2042,910],{"class":478},[444,2044,2046],{"class":446,"line":2045},78,[444,2047,2048],{"class":454},"                  )\n",[444,2050,2052,2055,2057,2059,2061,2064,2066],{"class":446,"line":2051},79,[444,2053,2054],{"class":478},"                :",[444,2056,1916],{"class":458},[444,2058,889],{"class":450},[444,2060,469],{"class":454},[444,2062,2063],{"class":539},"'Save'",[444,2065,792],{"class":454},[444,2067,910],{"class":478},[444,2069,2071,2074],{"class":446,"line":2070},80,[444,2072,2073],{"class":454},"          )",[444,2075,910],{"class":478},[444,2077,2079,2082],{"class":446,"line":2078},81,[444,2080,2081],{"class":454},"        ]",[444,2083,910],{"class":478},[444,2085,2087,2089],{"class":446,"line":2086},82,[444,2088,916],{"class":454},[444,2090,910],{"class":478},[444,2092,2094,2097,2099,2102],{"class":446,"line":2093},83,[444,2095,2096],{"class":454},"      body",[444,2098,660],{"class":478},[444,2100,2101],{"class":450}," Padding",[444,2103,875],{"class":454},[444,2105,2107,2110,2112,2114,2117,2119,2122,2124,2127,2129],{"class":446,"line":2106},84,[444,2108,2109],{"class":454},"        padding",[444,2111,660],{"class":478},[444,2113,1916],{"class":458},[444,2115,2116],{"class":450}," EdgeInsets",[444,2118,517],{"class":478},[444,2120,2121],{"class":465},"all",[444,2123,469],{"class":454},[444,2125,2126],{"class":2004},"16",[444,2128,792],{"class":454},[444,2130,910],{"class":478},[444,2132,2134,2137,2139,2142],{"class":446,"line":2133},85,[444,2135,2136],{"class":454},"        child",[444,2138,660],{"class":478},[444,2140,2141],{"class":450}," TextField",[444,2143,875],{"class":454},[444,2145,2147,2150,2152,2154],{"class":446,"line":2146},86,[444,2148,2149],{"class":454},"          controller",[444,2151,660],{"class":478},[444,2153,1193],{"class":454},[444,2155,910],{"class":478},[444,2157,2159,2162,2164,2166,2169,2172,2174,2177,2179],{"class":446,"line":2158},87,[444,2160,2161],{"class":454},"          decoration",[444,2163,660],{"class":478},[444,2165,1916],{"class":458},[444,2167,2168],{"class":450}," InputDecoration",[444,2170,2171],{"class":454},"(labelText",[444,2173,660],{"class":478},[444,2175,2176],{"class":539}," 'Name'",[444,2178,792],{"class":454},[444,2180,910],{"class":478},[444,2182,2184,2186],{"class":446,"line":2183},88,[444,2185,1575],{"class":454},[444,2187,910],{"class":478},[444,2189,2191,2193],{"class":446,"line":2190},89,[444,2192,916],{"class":454},[444,2194,910],{"class":478},[444,2196,2198,2201],{"class":446,"line":2197},90,[444,2199,2200],{"class":454},"    )",[444,2202,523],{"class":478},[444,2204,2206],{"class":446,"line":2205},91,[444,2207,929],{"class":454},[444,2209,2211],{"class":446,"line":2210},92,[444,2212,935],{"class":454},[348,2214,2215,2216,660],{},"When the user taps ",[352,2217,2218],{},"Save",[2220,2221,2222,2234,2237,2240],"ol",{},[2223,2224,2225,2226,2229,2230,2233],"li",{},"The ",[384,2227,2228],{},"UserDetailScreen"," (which uses ",[384,2231,2232],{},"QoraBuilder\u003CUser>",") immediately reflects the new name: no spinner, no delay.",[2223,2235,2236],{},"The network request fires in the background.",[2223,2238,2239],{},"If it succeeds, the server response confirms the data.",[2223,2241,2242],{},"If it fails, the name reverts to what it was before the tap.",[426,2244],{},[429,2246,2248],{"id":2247},"invalidating-related-queries","Invalidating Related Queries",[348,2250,2251,2252,2254],{},"After a successful mutation you typically want to invalidate related queries so stale list views refresh. Use ",[384,2253,769],{}," with a predicate:",[434,2256,2258],{"className":436,"code":2257,"filename":438,"language":439,"meta":440,"style":440},"// Invalidate the specific user AND the users list\nclient.invalidateWhere((key) => key.firstOrNull == 'users');\n\n// More targeted: only the list, not the individual entry\nclient.invalidateWhere((key) => key.length == 1 && key.firstOrNull == 'users');\n\n// Or invalidate the exact key\nclient.invalidate(['users']);\n",[384,2259,2260,2265,2292,2296,2301,2342,2346,2351],{"__ignoreMap":440},[444,2261,2262],{"class":446,"line":447},[444,2263,2264],{"class":560},"// Invalidate the specific user AND the users list\n",[444,2266,2267,2270,2272,2274,2276,2278,2280,2282,2284,2286,2288,2290],{"class":446,"line":503},[444,2268,2269],{"class":454},"client",[444,2271,517],{"class":478},[444,2273,769],{"class":465},[444,2275,772],{"class":454},[444,2277,775],{"class":478},[444,2279,778],{"class":454},[444,2281,517],{"class":478},[444,2283,783],{"class":454},[444,2285,786],{"class":478},[444,2287,789],{"class":539},[444,2289,792],{"class":454},[444,2291,523],{"class":478},[444,2293,2294],{"class":446,"line":526},[444,2295,554],{"emptyLinePlaceholder":553},[444,2297,2298],{"class":446,"line":550},[444,2299,2300],{"class":560},"// More targeted: only the list, not the individual entry\n",[444,2302,2303,2305,2307,2309,2311,2313,2315,2317,2320,2322,2325,2328,2330,2332,2334,2336,2338,2340],{"class":446,"line":557},[444,2304,2269],{"class":454},[444,2306,517],{"class":478},[444,2308,769],{"class":465},[444,2310,772],{"class":454},[444,2312,775],{"class":478},[444,2314,778],{"class":454},[444,2316,517],{"class":478},[444,2318,2319],{"class":454},"length ",[444,2321,786],{"class":478},[444,2323,2324],{"class":2004}," 1",[444,2326,2327],{"class":478}," &&",[444,2329,778],{"class":454},[444,2331,517],{"class":478},[444,2333,783],{"class":454},[444,2335,786],{"class":478},[444,2337,789],{"class":539},[444,2339,792],{"class":454},[444,2341,523],{"class":478},[444,2343,2344],{"class":446,"line":564},[444,2345,554],{"emptyLinePlaceholder":553},[444,2347,2348],{"class":446,"line":592},[444,2349,2350],{"class":560},"// Or invalidate the exact key\n",[444,2352,2353,2355,2357,2360,2363,2365,2368],{"class":446,"line":597},[444,2354,2269],{"class":454},[444,2356,517],{"class":478},[444,2358,2359],{"class":465},"invalidate",[444,2361,2362],{"class":454},"([",[444,2364,540],{"class":539},[444,2366,2367],{"class":454},"])",[444,2369,523],{"class":478},[348,2371,2372,2373,2375,2376,2379],{},"Active ",[384,2374,108],{}," widgets for any matching key receive ",[384,2377,2378],{},"Loading(previousData: data)"," and immediately re-fetch. Because the previous data is carried through, there is no flash of empty content.",[426,2381],{},[429,2383,2385,2386,2388,2389,1959],{"id":2384},"why-restorequerydata-instead-of-setquerydata","Why ",[384,2387,822],{}," Instead of ",[384,2390,637],{},[348,2392,2393],{},"Both methods write data into the cache. The difference is null handling:",[2395,2396,2397,2410],"ul",{},[2223,2398,2399,2402,2403,2406,2407,2409],{},[384,2400,2401],{},"setQueryData\u003CT>(key, data)",": requires a non-null ",[384,2404,2405],{},"T"," value; always produces a ",[384,2408,400],{}," state.",[2223,2411,2412,2415,2416,2418,2419,2422,2423,2425,2426,2429,2430,2432],{},[384,2413,2414],{},"restoreQueryData\u003CT>(key, snapshot)",": accepts ",[384,2417,392],{},"; when ",[384,2420,2421],{},"snapshot"," is ",[384,2424,396],{},", calls ",[384,2427,2428],{},"removeQuery(key)"," instead of writing. This makes rollback safe when the query had no prior data: no orphaned ",[384,2431,400],{}," state is left behind.",[434,2434,2437],{"className":436,"code":2435,"filename":2436,"language":439,"meta":440,"style":440},"// Correct: handles the null case (query had no prior data)\nclient.restoreQueryData\u003CUser>(key, previousUser); // null → removeQuery\n\n// Note: Equivalent only when previousUser is guaranteed non-null\nif (previousUser != null) {\n  client.setQueryData\u003CUser>(key, previousUser);\n}\n","rollback.dart",[384,2438,2439,2444,2468,2472,2477,2490,2511],{"__ignoreMap":440},[444,2440,2441],{"class":446,"line":447},[444,2442,2443],{"class":560},"// Correct: handles the null case (query had no prior data)\n",[444,2445,2446,2448,2450,2452,2454,2456,2458,2460,2462,2465],{"class":446,"line":503},[444,2447,2269],{"class":454},[444,2449,517],{"class":478},[444,2451,822],{"class":465},[444,2453,455],{"class":454},[444,2455,584],{"class":450},[444,2457,644],{"class":454},[444,2459,479],{"class":478},[444,2461,833],{"class":454},[444,2463,2464],{"class":478},";",[444,2466,2467],{"class":560}," // null → removeQuery\n",[444,2469,2470],{"class":446,"line":526},[444,2471,554],{"emptyLinePlaceholder":553},[444,2473,2474],{"class":446,"line":550},[444,2475,2476],{"class":560},"// Note: Equivalent only when previousUser is guaranteed non-null\n",[444,2478,2479,2482,2484,2486,2488],{"class":446,"line":557},[444,2480,2481],{"class":496},"if",[444,2483,617],{"class":454},[444,2485,620],{"class":478},[444,2487,623],{"class":478},[444,2489,626],{"class":454},[444,2491,2492,2495,2497,2499,2501,2503,2505,2507,2509],{"class":446,"line":564},[444,2493,2494],{"class":454},"  client",[444,2496,517],{"class":478},[444,2498,637],{"class":465},[444,2500,455],{"class":454},[444,2502,584],{"class":450},[444,2504,644],{"class":454},[444,2506,479],{"class":478},[444,2508,833],{"class":454},[444,2510,523],{"class":478},[444,2512,2513],{"class":446,"line":592},[444,2514,935],{"class":454},[426,2516],{},[429,2518,133],{"id":2519},"best-practices",[937,2521,2523],{"id":2522},"do","Do",[434,2525,2528],{"className":436,"code":2526,"filename":2527,"language":439,"meta":440,"style":440},"// Always snapshot before mutating\nfinal previousUser = client.getQueryData\u003CUser>(key);\n\n// Apply optimistic update only when data exists\nif (previousUser != null) {\n  client.setQueryData(key, optimisticData);\n}\n\n// Always restore on any error path\n} catch (_) {\n  client.restoreQueryData(key, previousUser);\n}\n","update.dart",[384,2529,2530,2535,2558,2562,2567,2579,2597,2601,2605,2610,2620,2636],{"__ignoreMap":440},[444,2531,2532],{"class":446,"line":447},[444,2533,2534],{"class":560},"// Always snapshot before mutating\n",[444,2536,2537,2540,2542,2544,2546,2548,2550,2552,2554,2556],{"class":446,"line":503},[444,2538,2539],{"class":458},"final",[444,2541,569],{"class":454},[444,2543,512],{"class":478},[444,2545,574],{"class":454},[444,2547,517],{"class":478},[444,2549,579],{"class":465},[444,2551,455],{"class":454},[444,2553,584],{"class":450},[444,2555,587],{"class":454},[444,2557,523],{"class":478},[444,2559,2560],{"class":446,"line":526},[444,2561,554],{"emptyLinePlaceholder":553},[444,2563,2564],{"class":446,"line":550},[444,2565,2566],{"class":560},"// Apply optimistic update only when data exists\n",[444,2568,2569,2571,2573,2575,2577],{"class":446,"line":557},[444,2570,2481],{"class":496},[444,2572,617],{"class":454},[444,2574,620],{"class":478},[444,2576,623],{"class":478},[444,2578,626],{"class":454},[444,2580,2581,2583,2585,2587,2590,2592,2595],{"class":446,"line":564},[444,2582,2494],{"class":454},[444,2584,517],{"class":478},[444,2586,637],{"class":465},[444,2588,2589],{"class":454},"(key",[444,2591,479],{"class":478},[444,2593,2594],{"class":454}," optimisticData)",[444,2596,523],{"class":478},[444,2598,2599],{"class":446,"line":592},[444,2600,935],{"class":454},[444,2602,2603],{"class":446,"line":597},[444,2604,554],{"emptyLinePlaceholder":553},[444,2606,2607],{"class":446,"line":605},[444,2608,2609],{"class":560},"// Always restore on any error path\n",[444,2611,2612,2615,2617],{"class":446,"line":611},[444,2613,2614],{"class":454},"} ",[444,2616,803],{"class":496},[444,2618,2619],{"class":454}," (_) {\n",[444,2621,2622,2624,2626,2628,2630,2632,2634],{"class":446,"line":629},[444,2623,2494],{"class":454},[444,2625,517],{"class":478},[444,2627,822],{"class":465},[444,2629,2589],{"class":454},[444,2631,479],{"class":478},[444,2633,833],{"class":454},[444,2635,523],{"class":478},[444,2637,2638],{"class":446,"line":668},[444,2639,935],{"class":454},[937,2641,2643],{"id":2642},"dont","Don't",[434,2645,2647],{"className":436,"code":2646,"filename":2527,"language":439,"meta":440,"style":440},"// Don't skip the snapshot: you won't be able to roll back\nclient.setQueryData(key, optimisticData);\nawait api.update(data); // if this throws, no rollback possible\n\n// Don't ignore the error: always inform the user\n} catch (_) {} // Bad: Silent failure is worse than no optimistic update\n",[384,2648,2649,2654,2670,2691,2695,2700],{"__ignoreMap":440},[444,2650,2651],{"class":446,"line":447},[444,2652,2653],{"class":560},"// Don't skip the snapshot: you won't be able to roll back\n",[444,2655,2656,2658,2660,2662,2664,2666,2668],{"class":446,"line":503},[444,2657,2269],{"class":454},[444,2659,517],{"class":478},[444,2661,637],{"class":465},[444,2663,2589],{"class":454},[444,2665,479],{"class":478},[444,2667,2594],{"class":454},[444,2669,523],{"class":478},[444,2671,2672,2675,2678,2680,2683,2686,2688],{"class":446,"line":526},[444,2673,2674],{"class":496},"await",[444,2676,2677],{"class":454}," api",[444,2679,517],{"class":478},[444,2681,2682],{"class":465},"update",[444,2684,2685],{"class":454},"(data)",[444,2687,2464],{"class":478},[444,2689,2690],{"class":560}," // if this throws, no rollback possible\n",[444,2692,2693],{"class":446,"line":550},[444,2694,554],{"emptyLinePlaceholder":553},[444,2696,2697],{"class":446,"line":557},[444,2698,2699],{"class":560},"// Don't ignore the error: always inform the user\n",[444,2701,2702,2704,2706,2709],{"class":446,"line":564},[444,2703,2614],{"class":454},[444,2705,803],{"class":496},[444,2707,2708],{"class":454}," (_) {} ",[444,2710,2711],{"class":560},"// Bad: Silent failure is worse than no optimistic update\n",[426,2713],{},[429,2715,2717],{"id":2716},"next-steps","Next Steps",[2395,2719,2720,2727,2742],{},[2223,2721,2722,2726],{},[2723,2724,21],"a",{"href":2725},"../getting-started/quick-start",": List and detail screens without mutations",[2223,2728,2729,2733,2734,2736,2737,2736,2739,2741],{},[2723,2730,2732],{"href":2731},"../api-reference/qora-client","QoraClient API",": ",[384,2735,637],{},", ",[384,2738,579],{},[384,2740,822],{}," reference",[2223,2743,2744,2747],{},[2723,2745,62],{"href":2746},"../core-concepts/query-states",": Understanding the state machine that makes rollback predictable",[2749,2750,2751],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":440,"searchDepth":503,"depth":503,"links":2753},[2754,2757,2758,2759,2761,2765],{"id":431,"depth":503,"text":432,"children":2755},[2756],{"id":939,"depth":526,"text":940},{"id":1049,"depth":503,"text":1050},{"id":2247,"depth":503,"text":2248},{"id":2384,"depth":503,"text":2760},"Why restoreQueryData Instead of setQueryData?",{"id":2519,"depth":503,"text":133,"children":2762},[2763,2764],{"id":2522,"depth":526,"text":2523},{"id":2642,"depth":526,"text":2643},{"id":2716,"depth":503,"text":2717},"Update the UI instantly while mutations are in flight, and roll back safely on failure: with no extra libraries.","md",null,{},{"icon":151},{"title":148,"description":2766},"KVHpsePDOBWVzWuf9qkmucgR1rzBJgY-VPLeW5cy1kA",[2774,2776],{"title":144,"path":145,"stem":146,"description":2775,"icon":85,"children":-1},"Perform write operations (POST, PUT, DELETE) with full lifecycle support: optimistic updates, automatic rollback, retry, and DevTools observability.",{"title":153,"path":154,"stem":155,"description":2777,"icon":156,"children":-1},"Persist query results to disk and restore them on startup: giving your app an instant data layer that works fully offline.",1794040399132]