Service error: _field.ui.val(...).change is not a function

Version 5.0.36, non reproductible en 5.0.30.

Log JS

Le script à l’adresse « https://dev.name.epide.fr/resource?row_id=_CONSTRAINTS_NamJeune&d=responsive5_ThemeAdmin&_=5_0_36_20210408154939 » a été chargé alors que son type MIME (« ») n’est pas un type MIME JavaScript valide.

Impossible de charger certaines pages utilisant du javascript.

Quel navigateur utilisez vous ?

Il y a effectivement un pb de MIME type vide sur la pseudo-ressource des contraintes front mais, sur Chrome (89), Edge (89) et sur Firefox (87) (les 3 sous Windows 10), ça n’empêche visiblement pas les contraintes front de la demo de se charger et de s’exécuter correctement dans les formulaires sur une 5.0.36.

Aucun message d’erreur ou de warning à propos du MIME type vide non plus dans la console des 3 navigateurs en question

Le pb de MIME type vide sur la pseudo ressource des contraintes est corrigé, cette anomalie était déjà présente en 4.0 donc c’est pas récent. Ce sera poussé dans le 5.0.37 (qui sera poussée au plus tard demain soir)

Du coup, et sachant que je n’ai pas constaté de pb sur les contraintes de la démo avant cette correction, je me dit que votre pb n’est pas lié à ce pb de MIME type mais peut être à un cas particulier. Dans le debugger du navigateur essayez de cerner plus précisément la contrainte exacte qui induit cette erreur

Il n’y a pas grand chose dans les debugger sachant que la méthode affichée n’est pas présente dans notre code.

l’initCreate/update sont bien déclenchés, la ressource javascript est bien chargée aussi. Dans le doute j’ai essayé en virant le JS mais toujours la même chose.

On est sur les dernière versions de chrome/firefox. Ca ne concerne qu’un objet et ceux qui en hérite. J’essaie de trouver la spécificité qui pourrait causer le problème.

EDIT : On ne reproduit pas le problème sur le template editor de l’objet.
EDIT 2: A priori une contrainte pose problème. J’ai supprimé les 77 contraintes et il n’y a plus le problème. Je soupçonne un script Rhino.

La version 5.0.37 a été poussée hier soir, elle corrige le pb de MIME type. SI vous upgradez vous n’aurez plus ce pb de MIME type sur la pseudo ressource Javascript des contraintes front.

Par contre Rhino est le moteur de script Java coté serveur, rien à voir avec le JS qui s’exécute coté navigateur, vous devez parler d’une ressource Javascript.

L’erreur qui remonte est une erreur d’exécution de contrainte, pour investiguer ce genre de choses il faut en général désactiver les contraintes (en leur mettant un ordre négatif) puis les réactiver une par une jusqu’à trouver celle qui pose pb

Merci pour l’astuce de l’ordre négatif.

Dans l’éditeur de template les contraintes ne sont pas executée (car sinon elles généraient l’edition du template).

J’ai souvenir d’avoir eu dans le passé des comportements bizarres des contraintes en utilisant l’objet juste après être passé dans l’éditeur de template (dans la même session), un clear cache partiel de l’objet + un F5 navigateur ou un clear cache global résolvait le pb, je ne sais pas si c’est toujours d’actualité…

Les contraintes sont compilées en fichier JS pour le front, et interprétée via RHINO en back.

Vous pouvez regarder le code généré directement = ouvrir le fichier via la console (dans les log vous voyez normalement le script faire des traces) et mettre un point d’arrêt dans le navigateur au niveau du _field.ui.val().change() en question.
:
https://dev.name.epide.fr/resource?row_id=CONSTRAINTS_NamJeune

On dirait que votre contrainte s’applique mal sur le champ :

  • val() retourne la valeur du champ et non pas le champ, donc c’est normal que change n’existe pas
  • il devrait y avoir qq chose comme _field.ui.val("value").change() pour chainer les méthodes

Je pense que votre champ n’a pas de valeur, du genre null/undefined et pas “” par exemple.

J’ai commencé par ratisser large :

  • J’ai supprimé les 3 dernières pages de contraintes sans amélioration.
  • J’ai donc fait l’inverse et supprimé uniquement la première page et toujours pas d’amélioration.
  • En laissant les 2 premières contraintes toujours pareil : ce sont des impacts simple avec des expressions de type |VALUE:nomDuChamp]

C’est peut être lié à un type particulier d’attribut ou un cas particulier d’usage qui fait que la valeur passée au val est nulle. C’est pour cela qu’il faut essayer de trouver la contrainte ou l’impact qui pose pb, sinon c’est impossible à investiguer.

Peut être un nom d’attribut mal “orthographié” (les noms d’attributs sont case-sensitive) ou un nom d’attribut qui n’existe pas ?

Oui cette syntaxe doit retourner vide et pas “” dans certains cas.

Elle est substituée par " + obj.getFieldValue("nomDuChamp") + " si c’est un champ textuel, ou sans quote si c’est un booléen ou un nombre.

Ce qui est bizarre c’est qu’on n’a rien changé à ce niveau depuis des lustres.

On peut renforcer le code généré pour tester le cas “vide”, mais ça cache quand même un problème sur vos données sur un champ non textuel (boolean null et pas true/false…).

J’ai laissé une contrainte avec l’expression ![VALUE:namJenDettes] et desactivé l’impact qui settait une valeur à null et ça fonctionnait.
J’ai changé le null dans l’impact par une chaine vide et ça fonctionne … Y’a forcement quelquechose qui à changé entre la version 30 et la 36 parce que c’est des choses qu’on a pas touché depuis un moment non plus. Et on a potentiellement ce genre de cas sur d’autres objets.

A première vue le seul commit qui pourrait avoir un lien c’est le 56ab9534a5aeb2940327f49c66f4a9967d5e01f9 du 01/04 (poussé dans la révision 5.0.35). Ca portait sur un pb de valeur d’attribut dans le cas d’un attribut énuméré multiple pour lequel une valeur null n’était pas traitée comme une valeur undefined et ça remontait une erreur dans certain cas. Peut être que cette modif n’était pas la bonne chose à faire…

On parle d’attributs énuméré multiple dans votre cas ?

Ici le champ de l’expression est un booléen et le champs ciblé par le null est un double

Effectivement le commit en question porte aussi sur le type boolean. On va regarder ça de plus pret.

Nous n’avons pas de contrainte de test qui valorise un attribut avec null, c’est sans doute pour cela que ce cas nous a échappé.

Quand on utilise un boolean qui est nullable, il faut forcer la valeur à être un booléen en doublant l’opérateur “not” pour etre sur d’avoir un booléen et pas null, par exemple :

!![VALUE:mybool]

null retourne bien false

Le front ne sait pas dire qu’un boolean “null” est “false” tout seul.
Dans vos anciens cas le booléen n’était jamais null, mais il l’est dans certains objets.

On va renforcer le code pour ce cas particulier d’un booléen null dans une contrainte et le forcer à false dans le val().

nous avons passé le js au debug et trouvé ceci :

Dans ce morceau de code

                    if (_expr69()) {
                        _expr = _expr57();
                        _field = _getField("namJenAnneeCfg");
                        if (_field && _expr !== undefined) {
                            app.debug("- VAL " + _field.name + ": value=" + _expr);
                            if (engine) {
                                if (_field.ui.val() != _expr)
                                    _field.ui.val(_expr).change();
                            }
                        }
                    }

_expr est a null

_field.ui.val(_expr) retourne un string vide ce qui explique l’erreur mais si un set _expr avec un string vide, on récupère une objet avec une méthode change

Attention, le cas d’un boolean non renseigné existe, il ne faut pas le forcer à FALSE (cas des radio button ou des select à 3 états = vide, TRUE ou FALSE)

La modif qui a été fait c’est de dire undefined ou null => chaine vide (avant le cas null n’était pas géré comme undefined et ça posait pb dans certain cas)

ERRATUM : il ne faut surtout pas forcer à “false” un “null” dans le val Simplicité = car ça veut dire autre chose en terme UX = champ non saisie

C’est bien votre contrainte qui est mal écrite et doit gérer le cas null | true | false.
Un booléen a hélas 3 valeurs.

Par contre on va quand même renforcer le code Simplicité pour éviter cette erreur = mettre chaine vide et pas null.

  1. Par défaut le champs est true ou false dan la UI pour tous nos booléens donc on est pas sur un cas ou le booléen est null.
  2. Le problème se produit quelque soit l’objet et ne posait pas problème jusque là (jeu de donnée intact)
  3. Quand l’impact est desactivé, l’expression de la contraine est vérifié quand meme, je me trompe ?

Merci de ne pas retourner la régression que vous avez introduis contre nous. Si la contrainte est mal écrite merci de nous montrer la doc ou c’est explicitement indiqué. Par ailleurs, il me semble que vous aviez fait un audit de notre code. Vous aviez eu le temps de regarder notre code java en détail, par conséquent j’imagine que vous aviez du jeter un oeil à ces contraintes qui sont présentes depuis l’été dernier et je n’ai pas vu de remarque concernant ces contraintes/impacts.

Erratum : il y’a bien des champs booléen vides par défaut…