Evolutions sur les formulaires
Fix #193
-
useFormNode
peut désormais être appelé avec une définition d'entité à la place d'un noeud existant. Vous n'êtes donc plus obligés d'utiliser un store externe global, ou de faire lebuildNode
vous même dans le composant -
useFormActions
:-
Prend une nouvelle méthode
init(init?: () => Promise<EntityToType<E0>>)
, qui sera appelée à la place deload
au premier rendu s'il n'y pas deload
à appeler. Elle effectue unset
des données retournées par la méthode en paramètre sur leformNode
(et non unreplace
sur lestoreNode
commeload
), puis écrase les données du noeud source par les données du formulaire (avec unreplace
cette fois-ci).Elle permettra de faire des initialisations de données pour la création sans utiliser
load
(ou un effet externe) quand on a besoin d'un appel serveur et de s'assurer que le valeur dehasChanged
du formulaire sera toujours calculée à partir des données initiales. Les données complèteront celles déjà définies dansuseFormNode
(d'où leset
), etinit
pourra être appelé sans paramètre si on veut juste reset le noeud source.Idéalement, tout formulaire utilisé en création devrait appeler
init
, ce qui ne correspond malheureusement pas forcément à tous les formulaires sansload
(il peut être défini dans unuseLoad
séparé par exemple, et ici on ne voudra pas du tout reset le noeud source). -
Prend deux nouvelles méthodes
create
etupdate
, mutuellement exclusives avecsave
, qui seront appelées paractions.save()
selon si on a desparams
(pourupdate
) ou non (pourcreate
).update
sera appelée avec lesparams
puis avec le contenu du formulaire, pour correspondre aux API PUT classiques. Pour le reste, elles sont identiques àsave
. -
On ajoute
on("init")
,.on("create")
eton("update")
, pour faire comme les autres méthodes -
On autorise les fonctions de sauvegarde (donc
create
,update
etsave
) à retourner une primitive, en plus devoid
ou le type du noeud. -
Les différents
on
seront appelés avec la valeur retournée par la fonction correspondante (pourinit
,load
,save
,create
etupdate
). Cela permettra par exemple de faireon("create", id => router.to(x => x(id)))
si votre service de création renvoie un ID. -
On appelle aussi
on("error")
pourload
, et il sera appelé avec le nom du service en erreur, ainsi que l'erreur elle-même. -
On expose
actions.params
, pour pouvoir l'utiliser dans le rendu par exemple (pour distinguer le cas de création)
-
La documentation a évidemment été mise à jour, et le starter kit utilise également ces nouvelles fonctionnalités, si vous voulez un exemple 🙂
Les petits breaking changes à noter :
- Les stores (source et de formulaire) sont désormais entièrement vidés en cas d'erreur pendant le chargement.
params()
n'accepte plus de surcharge (qui n'était pas documentée d'ailleurs) qui prend plus d'un seul paramètre. Il faut explicitement passer un array dans ce cas.- Le type de
FormActions
a évolué pour inclure aussi les types de retours decreate
,update
etsave
, ce qui peut poser quelques soucis si vous l'avez utilisé en props à certains endroits.
ProblemDetails
Focus accepte désormais nativement des réponses en erreur sous le format ProblemDetails
, et utilisera les champs detail
ou title
en plus de errors
pour y récupérer le ou les messages d'erreurs à afficher à l'utilisateur.
On supporte désormais des paires clés/valeurs dans errors
(au lieu d'une simple liste plate). Chaque message sera préfixé par sa clé quand il sera ajouté au messageStore
, ce qui s'interfacera à priori nativement avec les retours en erreurs de vos APIs de validation côté serveur.
Le seul breaking change la dessus concerne ce qui sera renvoyé à un catch
d'un appel d'API :
- avant, on renvoyait la réponse, avec
$status
et$parsedErrors
avec les errors lues du retour serveur. - maintenant, on renvoie toujours la réponse, avec
status
s'il n'y était pas (status
fait partie de la specProblemDetails
), et$messages
, qui contient la liste des messages ajoutés dans lemessageStore
.
C'est presque la même chose qu'avant donc 😁