1

Here is my routeAction where I've the code for creating a user account. I'm using appwrite for this.

export const useCreateUserAccount = routeAction$(
    async (user, { fail }) => {
        try {
            const result = await account.create(
                ID.unique(),
                user.email.toString(),
                user.password.toString(),
                user.name.toString()
            )
            console.log('user account created successfully: ', result)

            return {
                status: true,
                error_message: '',
                error_code: '',
                data: result,
                message: 'user account created successfully'
            };

        } catch (error) {
            console.log('Exception caught: ', error)
            return fail(500, {
                status: false,
                error_message: 'User could not be added',
                error_code: '',
                data: error,
                message: ''
            });
        }

        // return {
        //     status: true,
        //     error_message: '',
        //     error_code: '',
        //     data: result,
        //     message: 'user account created successfully'
        // };
    },
    zod$({
        name: z.string().min(1),
        email: z.string().email(),
        password: z.string().min(8),
    })
);

User account creation is working fine. But, there are 2 issues I'm facing at here -

  1. if I comment out the return statement, which is inside try section & enable the commented return statement(at the end of the function), I'm getting I'm getting error as can't find name result.
  2. How to retrieve all return data in my component. When I'm trying to use the following piece of code to print the data, it's just not working. Basically, in this code, I'm trying to show the result data when I'll get any exception from appwrite.

{ !action.value?.status && <p>{action.value?.data}</p> }

----------Updated Code-----------

After a long struggle of hit & trial, I finally managed to calm down my typescript linter from yelling at me. Here is my updated code. I hope it'll help someone who is new like me to both Qwik & Typescript :D

import { component$, useStore } from '@builder.io/qwik';
import type { DocumentHead } from '@builder.io/qwik-city';
import { Link, routeAction$, zod$, z, Form } from '@builder.io/qwik-city';
import { account } from '~/appwrite.config';
import { ID } from 'appwrite'

export const useCreateUserAccount = routeAction$(
    async (user, { fail }) => {

        type SuccessResponse = {
            status: boolean,
            data: {
                id: string,
                name: string,
                email: string,
                phone: string,
                emailVerification: boolean,
                phoneVerification: boolean,
            },
            message: string
        }

        type ErrorResponse = {
            status: boolean,
            error: {
                message: string,
                code: number,
                type: string,
                version: string
            }
            message: string
        }

        let result

        try {
            result = await account.create(
                ID.unique(),
                user.email.toString(),
                user.password.toString(),
                user.name.toString()
            )
            console.log('user account created successfully: ', result)

        } catch (error: any) {
            console.log('Exception caught: ', error)

            const errorResponse: ErrorResponse = {
                status: false,
                error: {
                    message: error.response.message,
                    code: error.response.code,
                    type: error.response.type,
                    version: error.response.version,
                },
                message: 'Exception caught when creating user account'
            }
            return fail(500, errorResponse);
        }

        const response: SuccessResponse = {
            status: true,
            data: {
                id: result['$id'],
                name: result['name'],
                email: result['email'],
                phone: result['phone'],
                emailVerification: result['emailVerification'],
                phoneVerification: result['phoneVerification'],
            },
            message: 'user account created successfully'
        };

        return response
    },
    zod$({
        name: z.string().min(1),
        email: z.string().email(),
        password: z.string().min(8),
    })
);
Suresh
  • 5,687
  • 12
  • 51
  • 80

2 Answers2

3

First issue: as M.Ryan wrote, the variable need to be declared outside of the try catch block.

Second issue: this routeAction$ example works like a charm and I'm using data

import { component$ } from '@builder.io/qwik';
import { Form, routeAction$, z, zod$ } from '@builder.io/qwik-city';

export const useUserAction = routeAction$(async (user) => {
    return { data: { user } };
}, zod$({ name: z.string() }));

export default component$(() => {
    const action = useUserAction();

    return (
        <Form action={action}>
            <input name='name' />
            <button class='text-black' type='submit'>
                Add user
            </button>
            {JSON.stringify(action.value?.data)}
        </Form>
    );
});
Giorgio Boa
  • 341
  • 4
  • 1
    I saw this specific code in their docs. But, as I'm new to typescript, it was yelling every time whenever I tried to access my specific object property. Eventually, I managed to solve this. I'm sharing my updated code along with the post now. Thanks a lot for your helping hand. :) – Suresh Jun 11 '23 at 18:53
2

About the first issue:

the "result" variable is declared locally (block-scoped ) in the try catch block. therefore, it is not visible outside of this block. you have to declare it locally to the function:

...
async (user, { fail }) => {
            let result;
        try {
             result = await account.create(...
M.Ryan
  • 126
  • 5
  • 2
    After a couple of tries, I also figured out the same thing. I never thought ```try catch``` block behave like this. Anyway, thanks for your prompt reply. – Suresh Jun 11 '23 at 18:50
  • 1
    I've also edited my post with my updated ```routeAction()``` code. Maybe that will give a complete picture of how to deal with such an issue. – Suresh Jun 11 '23 at 19:01