Hi,
I want to enhance the generated RW Scaffolds (that are basically forms) and add ability to select an option for related data. ex. if User had a Favorite Movie assigned to the account that is Many to one relationship, but instead of displaying user.favoriteMoveId that RW would generate I want to display a list of all movies with default option pointing to currently selected one if it’s present.
If not I want the field to be a SelectField type with all possible ‘Movies’ as options.
The other way to phrase this question would be: how do I run multiple queries inside a cell and wait for all of them to finish before rendering the component?
I want to know what is the proper way (in RW) to do it:
- should I create a new query inside EditXXXCell.tsx to fetch all the “movies” so they can be displayed?
- should I create a new cell that will display “movies” as Selection field with options?
- should the data for select field be fetched inside the form?
- Maybe it would be better to create a new component for that purpose?
I managed to do it with option 1 but only partially see below (please note that code is adapted to the example mentioned above, I am not making movie db):
This would be an additional GraphQL query in EditUserCell
export const QUERY_MOVIES = gql`
query FindAllMovies {
movies {
id
title
}
}
`;
And I will run it on Success:
export const Success = ({ exercise }: CellSuccessProps<EditUserById>) => {
const findMovies = useQuery(QUERY_MOVIES, {
onCompleted: (data) => {
toast.success('Movies fetched');
moviesData = data.movies;
},
});
...
}
The SelectField
in the Form component:
<SelectField
name="favoriteMovie"
defaultValue={props.user?.favoriteMovie?.id}
className="rw-input"
errorClassName="rw-input rw-input-error"
placeholder="Select a Favorite Movie"
>
{props.favoriteMovie?.map((favMovie) => {
return (
<option
key={favMovie?.id}
value={favMovie?.id}
>
{favMovie?.title}
</option>
);
})}
</SelectField>
Now there are 2 problems with this:
- When I click edit from the scaffold data is fetched and displayed but item selected is not the item user has assigned (using ID as value).
- When edit page is refreshed all data is lost, although the toast shows that data was fetched it’s not assigned to the options and SelectField is empty.
After re-checking the docs it seems I should create a Cell that will fetch data and render the component to fix no. 2. No. 1 should be fixable with SelectField component but…
when trying to wrap SelectField
into a concrete instance for this example (Movie List) I receive an error from react-hook-form
:
Cannot read properties of null (reading 'formState')
return (
<SelectField
name="movieSelect"
defaultValue={'id-of-the-movie'}
>
{movies.map((movie: Movie) => {
return (
<option
key={movie.id}
value={movie.id}
>
{movie.title}
</option>
);
})}
</SelectField>
);
};
Should I wrap storybook in some FormProvider ? Why cannot I use the RW components in Storybook on their own?