@@ -29,7 +29,7 @@ import { listTodos } from './ash_rpc';
2929// List todos with field selection
3030const todos = await listTodos ({
3131 fields: [" id" , " title" , " completed" , " priority" ],
32- filter: { status: " active " },
32+ filter: { completed: { eq: false } },
3333 sort: " -priority,+createdAt"
3434});
3535
@@ -88,11 +88,10 @@ Use complex nested structures for detailed data retrieval:
8888// Complex nested field selection
8989const todoWithDetails = await getTodo ({
9090 fields: [
91- " id" , " title" , " description" ,
91+ " id" , " title" , " description" , " tags " ,
9292 {
93- user: [" name" , " email" , " avatarUrl" ],
94- comments: [" id" , " text" , { author: [" name" ] }],
95- tags: [" name" , " color" ]
93+ user: [" id" , " name" , " email" ],
94+ comments: [" id" , " content" , " authorName" ]
9695 }
9796 ],
9897 input: { id: " todo-123" }
@@ -101,34 +100,35 @@ const todoWithDetails = await getTodo({
101100if (todoWithDetails .success ) {
102101 console .log (" Todo:" , todoWithDetails .data .title );
103102 console .log (" Comments:" , todoWithDetails .data .comments .length );
104- todoWithDetails .data .tags .forEach (tag => {
105- console .log (` Tag: ${tag .name } (${tag .color }) ` );
103+ console .log (" Tags:" , todoWithDetails .data .tags ); // Array of strings
104+ todoWithDetails .data .comments .forEach (comment => {
105+ console .log (` Comment by ${comment .authorName }: ${comment .content } ` );
106106 });
107107}
108108```
109109
110- ### Calculations with Arguments
110+ ### Calculated Fields
111111
112- Request calculated fields with custom arguments :
112+ Request calculated fields that are computed by your Ash resource :
113113
114114``` typescript
115- // Calculations with arguments
115+ // Calculated fields
116116const todoWithCalc = await getTodo ({
117117 fields: [
118- " id" , " title" ,
119- {
120- " priorityScore" : {
121- " args" : { " multiplier" : 2 },
122- " fields" : [" score" , " rank" ]
123- }
124- }
118+ " id" ,
119+ " title" ,
120+ " dueDate" ,
121+ " isOverdue" , // Boolean calculation
122+ " daysUntilDue" // Integer calculation
125123 ],
126124 input: { id: " todo-123" }
127125});
128126
129127if (todoWithCalc .success ) {
130- console .log (" Priority score:" , todoWithCalc .data .priorityScore .score );
131- console .log (" Rank:" , todoWithCalc .data .priorityScore .rank );
128+ console .log (" Todo:" , todoWithCalc .data .title );
129+ console .log (" Due date:" , todoWithCalc .data .dueDate );
130+ console .log (" Is overdue:" , todoWithCalc .data .isOverdue );
131+ console .log (" Days until due:" , todoWithCalc .data .daysUntilDue );
132132}
133133```
134134
@@ -145,7 +145,8 @@ const newTodo = await createTodo({
145145 input: {
146146 title: " Learn AshTypescript" ,
147147 priority: " high" ,
148- dueDate: " 2024-01-01"
148+ dueDate: " 2024-01-01" ,
149+ userId: " user-id-123"
149150 }
150151});
151152
@@ -195,7 +196,6 @@ import { destroyTodo } from './ash_rpc';
195196
196197// Delete todo (primary key separate from input)
197198const deletedTodo = await destroyTodo ({
198- fields: [], // Can request fields if the action returns the deleted record
199199 primaryKey: " todo-123" // Primary key as separate parameter
200200});
201201
@@ -206,27 +206,17 @@ if (deletedTodo.success) {
206206}
207207```
208208
209- You can optionally request fields if your destroy action is configured to return the deleted record:
210-
211- ``` typescript
212- const deletedTodo = await destroyTodo ({
213- fields: [" id" , " title" ], // Get the deleted record data
214- primaryKey: " todo-123"
215- });
216-
217- if (deletedTodo .success ) {
218- console .log (" Deleted:" , deletedTodo .data .title );
219- }
220- ```
221-
222209## Error Handling
223210
224211All generated RPC functions return a ` {success: true/false} ` structure instead of throwing exceptions:
225212
226213``` typescript
227214const result = await createTodo ({
228215 fields: [" id" , " title" ],
229- input: { title: " New Todo" }
216+ input: {
217+ title: " New Todo" ,
218+ userId: " user-id-123"
219+ }
230220});
231221
232222if (result .success ) {
@@ -251,7 +241,7 @@ if (result.success) {
251241// Validation errors (e.g., missing required fields)
252242const result = await createTodo ({
253243 fields: [" id" , " title" ],
254- input: {} // Missing required title
244+ input: {} // Missing required title and userId
255245});
256246
257247if (! result .success ) {
@@ -316,7 +306,10 @@ import { createTodo, listTodos } from './ash_rpc';
316306// Add request timeout and custom cache settings
317307const todo = await createTodo ({
318308 fields: [" id" , " title" ],
319- input: { title: " New Todo" },
309+ input: {
310+ title: " New Todo" ,
311+ userId: " user-id-123"
312+ },
320313 fetchOptions: {
321314 signal: AbortSignal .timeout (5000 ), // 5 second timeout
322315 cache: ' no-cache' ,
@@ -441,82 +434,78 @@ import {
441434 buildCSRFHeaders
442435} from ' ./ash_rpc' ;
443436
444- async function todoLifecycle() {
445- const headers = buildCSRFHeaders ();
446-
447- // 1. Create a new todo
448- const createResult = await createTodo ({
449- fields: [" id" , " title" , " createdAt" ],
450- input: {
451- title: " Learn AshTypescript CRUD" ,
452- priority: " high"
453- },
454- headers
455- });
456-
457- if (! createResult .success ) {
458- console .error (" Failed to create:" , createResult .errors );
459- return ;
460- }
437+ const headers = buildCSRFHeaders ();
461438
462- const todoId = createResult .data .id ;
463- console .log (" Created:" , createResult .data );
439+ // 1. Create a new todo
440+ const createResult = await createTodo ({
441+ fields: [" id" , " title" , " createdAt" ],
442+ input: {
443+ title: " Learn AshTypescript CRUD" ,
444+ priority: " high" ,
445+ userId: " user-id-123"
446+ },
447+ headers
448+ });
464449
465- // 2. Read the todo
466- const getResult = await getTodo ({
467- fields: [" id" , " title" , " priority" , { user: [" name" ] }],
468- input: { id: todoId },
469- headers
470- });
450+ if (! createResult .success ) {
451+ console .error (" Failed to create:" , createResult .errors );
452+ return ;
453+ }
471454
472- if (getResult .success ) {
473- console .log (" Retrieved:" , getResult .data );
474- }
455+ const todoId = createResult .data .id ;
456+ console .log (" Created:" , createResult .data );
475457
476- // 3. Update the todo
477- const updateResult = await updateTodo ({
478- fields: [" id" , " title" , " priority" , " updatedAt" ],
479- primaryKey: todoId ,
480- input: {
481- title: " Mastered AshTypescript CRUD" ,
482- priority: " completed"
483- },
484- headers
485- });
458+ // 2. Read the todo
459+ const getResult = await getTodo ({
460+ fields: [" id" , " title" , " priority" , { user: [" name" ] }],
461+ input: { id: todoId },
462+ headers
463+ });
486464
487- if (updateResult .success ) {
488- console .log (" Updated :" , updateResult .data );
489- }
465+ if (getResult .success ) {
466+ console .log (" Retrieved :" , getResult .data );
467+ }
490468
491- // 4. List all todos
492- const listResult = await listTodos ({
493- fields: [" id" , " title" , " priority" ],
494- filter: { priority: " completed" },
495- headers
496- });
469+ // 3. Update the todo
470+ const updateResult = await updateTodo ({
471+ fields: [" id" , " title" , " priority" , " updatedAt" ],
472+ primaryKey: todoId ,
473+ input: {
474+ title: " Mastered AshTypescript CRUD" ,
475+ priority: " completed"
476+ },
477+ headers
478+ });
497479
498- if (listResult .success ) {
499- console .log (" Completed todos :" , listResult .data . length );
500- }
480+ if (updateResult .success ) {
481+ console .log (" Updated :" , updateResult .data );
482+ }
501483
502- // 5. Delete the todo
503- const deleteResult = await destroyTodo ({
504- fields: [" id" , " title" ],
505- primaryKey: todoId ,
506- headers
507- });
484+ // 4. List all completed todos
485+ const listResult = await listTodos ({
486+ fields: [" id" , " title" , " priority " ],
487+ filter: { completed: { eq: true } } ,
488+ headers
489+ });
508490
509- if (deleteResult .success ) {
510- console .log (" Deleted:" , deleteResult .data );
511- }
491+ if (listResult .success ) {
492+ console .log (" Completed todos:" , listResult .data .length );
512493}
513494
514- todoLifecycle ();
495+ // 5. Delete the todo
496+ const deleteResult = await destroyTodo ({
497+ primaryKey: todoId ,
498+ headers
499+ });
500+
501+ if (deleteResult .success ) {
502+ console .log (" Deleted successfully" );
503+ }
515504```
516505
517506## Next Steps
518507
519508- Learn about [ Phoenix Channel-based RPC actions] ( ../topics/phoenix-channels.md ) for real-time communication
520- - Explore [ field selection patterns] ( ../topics/ field-selection.md) for complex queries
521- - Review [ error handling strategies] ( ../topics/ error-handling.md) for production applications
522- - See [ authentication patterns ] ( ../topics/authentication. md) for securing your API calls
509+ - Explore [ field selection patterns] ( field-selection.md ) for complex queries
510+ - Review [ error handling strategies] ( error-handling.md ) for production applications
511+ - Learn about [ custom fetch functions ] ( custom-fetch. md) for adding authentication and request customization
0 commit comments