FAQ
Pour récupérer le projectId au niveau d'un resolver graphql, vous pouvez accéder à l'objet context reçu en paramÚtre. Le context contient le process courant et le champ projectId.
const { projectId } = context.process;Pour gérer une action de transition conditionnelle dans les vues, vous devez modifier le gestionnaire de transition.
Par exemple, si vous souhaitez que votre vue vue1 vous redirige vers vue3 selon une condition, ou vers vue2 par défaut, modifiez le gestionnaire de l'action next dans le dossier views/vue1/transitions/next.mjs :
import { Entities } from '@fasstech/oip-core';
import { getCustomerMaritalStatus, MaritalStatusEnum } from '@fasstech/oip-core/entities';
import { prop } from 'ramda';
import { transitionRouter as router } from '@fasstech/oip-core/process';
import { actionIds, viewIds } from '../../ids.mjs';
router.declare(viewIds.VUE1, actionIds.VUE1_NEXT, async ({ sessionId, process }) => {
const ProjectEntity = await Entities('Project').get({ id: prop('projectId', process) });
const CustomerEntity = await Entities('Customer').get(ProjectEntity);
const MaritalStatus = getCustomerMaritalStatus(CustomerEntity);
if(MaritalStatus === MaritalStatusEnum.SINGLE) return { viewId: viewIds.VUE3 }
return { viewId: viewIds.VUE2 };
});
export default router;
Explication du code :
- Importations nécessaires :
- Entities est importé pour récupérer les entités du projet.
- getCustomerMaritalStatus et MaritalStatusEnum sont importés pour déterminer le statut marital du client.
- transitionRouter (aliasé en router) permet de déclarer des transitions conditionnelles pour différentes vues.
- actionIds et viewIds contiennent les identifiants des actions et des vues, respectivement, pour le processus en cours.
- Déclaration de la transition conditionnelle : La méthode router.declare() est utilisée pour déclarer une transition conditionnelle. Elle prend trois arguments :
- L'identifiant de la vue actuelle (viewIds.VUE1)
- L'identifiant de l'action de transition (actionIds.VUE1_NEXT)
- Une fonction asynchrone qui renvoie l'identifiant de la vue suivante en fonction de conditions.
- Logique de transition :
- On récupÚre d'abord l'entité Project en utilisant son projectId pour identifier le bon projet.
- Ensuite, on récupÚre l'entité Customer associée à ce projet.
- AprÚs cela, on détermine le statut marital du client en utilisant la fonction getCustomerMaritalStatus
- En fonction du statut marital, la transition renvoie l'identifiant de la vue appropriée ( viewIds.VUE3 ou viewIds.VUE2).
Grùce à cette approche, vous pouvez avoir une granularité fine dans la maniÚre dont les utilisateurs naviguent à travers le processus, en fonction de leurs informations ou de toute autre condition que vous pourriez vouloir introduire. C'est une façon puissante d'assurer que les utilisateurs vivent une expérience qui est spécifique à leurs besoins.
AprÚs édition du layer GraphQL d'un fichier de configuration d'une vue, il se peut que parfois la commande yarn build:views échoue alors que votre fichier de configuration vous semble correcte. La sortie du script vous indiquant des erreurs liées au schema GraphQL.
Pas de panique, dans certains cas il vous suffit de supprimer les fichiers et dossiers générés relatif à votre vue pour forcer le build et corriger ces erreurs :
- le fichier schema.graphql Ă la racine du projet
- le dossier views/[my-view]/server/graphql/type
- le dossier views/[my-view]/client/graphql
- les hooks générés dans le dossier views/[my-view]/client/hooks
AprÚs suppression des ces fichiers / dossiers, relancez la commande du build des vues. Si la commande continue d'échouer, c'est certainement que le fichier de configuration de votre vue contient une ou des erreurs. N'hésitez pas à lire et à analyser les erreurs indiquées en sortie.
Arguments de type natif
Au niveau du fichier de configuration d'une vue, les arguments doivent ĂȘtre dĂ©clarĂ© de cette maniĂšre :
...
graphql:
queries:
# une query de type Project
- type: Project
# déclaration des arguments
query:
# argument de type string
foo: String
# argument de type string array
baz: '[String]'
# les champs attendus retournés par la query
fields:
id: String
externalId: String
name: String
# le nom du resolver de la query
resolver: getProjectUne fois le fichier de configuration de la vue édité, redémarrer le server puis lancer un build des vues :
$> yarn server:dev
$> yarn build:viewsEnsuite, dans le composant de la vue relative, utiliser le hook de la query généré de cette maniÚre pour passer les arguments :
...
const {
getProject,
isLoaded: isLoadedGetHome
} = useGetProjectQuery({
foo: 'hello world!',
baz: ['abc', 'def']
});Le resolver de la query, ici getProject, reçoit alors en 1er argument les arguments passé à la query :
import { Entities } from '@fasstech/oip-core';
import {
getProjectId,
getProjectExternalId,
getProjectName
} from '@fasstech/oip-core/entities';
export const getProject = async (args, context) => {
const { projectId } = context.process;
const project = await Entities('Project').get({ id: projectId });
// args
const { foo, baz } = args;
return {
id: getProjectId(project),
externalId: getProjectExternalId(project),
name: getProjectName(project)
};
};
export default getProject;Arguments typés
Pour passer des arguments typés à une query graphQL il est d'abord nécessaire de déclarer un InputType qui correspond au type des arguments souhaités.
Ajouter le fichier type de l'input dans server/graphql/type/, exemple :
// fichier FooInputType.mjs
import { gql } from 'apollo-server-express';
const FooInputType = {
typeDefs: gql`
input Foo {
message: String
isSomething: Boolean
}
`
};
export default FooInputType;Importez ce fichier dans server/graphql/schema.mjs et charger son schema :
import FooInputType from './type/FooInputType.mjs';
...
const schema = async () => {
const viewSchemas = await loaderSchema();
const schemaTypes = [
...viewSchemas,
GlobalType,
DatesType,
MutationType,
PaginationType,
ProcessType,
QueryType,
SubscriptionType,
UserType,
UserSessionType,
ResponseType,
ProcessObjectInput,
TaskType,
// ajout de l'input Foo au schema graphQL
FooInputType
];Dans le fichier de configuration de la vue, les arguments doivent ĂȘtre dĂ©clarĂ© de cette maniĂšre :
...
graphql:
queries:
# une query de type Project
- type: Project
# déclaration des arguments
query:
# input Foo
foo: Foo
# liste d'input Foo
list: '[Foo]'
# les champs attendus retournés par la query
fields:
id: String
externalId: String
name: String
# le nom du resolver de la query
resolver: getProjectPensez ensuite à générer les vues pour mettre à jour le schema graphQL :
$> yarn server:dev
$> yarn build:viewsEnsuite, dans le composant de la vue relative, utilisez le hook de la query généré de cette maniÚre pour passer les arguments :
...
const {
getProject,
isLoaded: isLoadedGetHome
} = useGetProjectQuery({
foo: {
message: 'hello world!',
isSomething: true
},
list: [
{
message: 'apple',
isSomething: true
},
{
message: 'banana',
isSomething: false
}
],
});Enfin, le resolver de la query reçoit alors en 1er argument les arguments passé à la query :
import { Entities } from '@fasstech/oip-core';
import {
getProjectId,
getProjectExternalId,
getProjectName
} from '@fasstech/oip-core/entities';
export const getProject = async (args, context) => {
const { projectId } = context.process;
const project = await Entities('Project').get({ id: projectId });
// args
const { foo, list } = args;
return {
id: getProjectId(project),
externalId: getProjectExternalId(project),
name: getProjectName(project)
};
};
export default getProject;Ce chapitre vous enseigne comment accéder à une erreur dans la réponse d'un hook généré d'une query GraphQL d'une vue. Par exemple, une erreur catch ou un résultat inatendu qui nécessite le retour d'une erreur depuis le resolver relatif à la query.
- vous devez tout d'abord gérer la possibilité du retour d'une erreur au niveau du type GraphQL de la réponse de votre query depuis le fichier de configuration de votre vue. Par exemple avec l'ajout des fields ok et error :
myView:
...
graphql:
queries:
- type: Project
fields:
id: String
externalId: String
name: String
- type: ProjectResponse
fields: # expected fields from the response
ok: Boolean!
error: String
project: Project
resolver: getProject- puis ne pas oublier de re-générer les vues
yarn build:views- enfin au niveau du resolver vous devez résoudre les fields attendus en réponse en fonction si il y a une erreur ou pas, par exemple :
import { Entities } from '@fasstech/oip-core';
import { getProjectId, getProjectExternalId, getProjectName } from '@fasstech/oip-core/entities';
export const getProject = async (args, context) => {
try {
const { projectId } = context.process;
const project = await Entities('Project').get({ id: projectId });
// throwing error
// throw new Error('OIP test error');
// unexpected result
const result = myLogic();
if (!result) {
return {
ok: false,
error: 'Unexpected result'
}
}
return {
ok: true,
project: {
id: getProjectId(project),
externalId: getProjectExternalId(project),
name: getProjectName(project)
}
}
} catch (err) {
return {
ok: false,
error: err.message
}
}
};
export default getProject;De cette maniÚre, dans la data retournée du hook généré relatif à la query dans votre vue, les fields ok et error sont définis en fonction si une erreur existe ou non.
D'abord installer le middleware suivant dans votre project
Puis dans le fichier routes.mjs :
Comment corrigé une erreur du type :
Commencez par installer core-js : yarn add core-js regenerator-runtime et supprimer (si vous l'avez) @babel/polyfill : yarn remove @babel/polyfill
Ensuite Il vous suffit de rajouter la configuration du polyfill dans votre config webpack.common.js ainsi qu'un fichier /app/polyfills.js :
module.exports = {
// Where webpack looks to start building the bundle
entry: {
polyfills: './app/polyfills', // ceci
index: path.resolve(__dirname, 'app', 'index.js'),
},
}Et supprimer tout les fallbacks que vous pouvez avoir du type:
resolve: {
...
fallback: {
...
fs: false
}
}
Si le hot reload de React ne fonctionne plus
aprÚs ces modifications, il est nécessaire de suivre les étapes suivantes :
Supprimer les dépendances (si présentes) @pmmmwh/react-refresh-webpack-plugin, react-refresh et react-hot-loader.
Supprimer leurs configurations associées (si elles existent) :
- webpack.dev.js : Supprimer tout ce qui est dans module(si un configuration babel-loader utilisant react-refresh a été mise) et la ligne new ReactRefreshWebpackPlugin() dans les plugins.
- .babel.rc : dans les plugins, supprimer "react-hot-loader/babel"