Mise en ligne : dimanche 13 octobre 2024
Pour suivre cet article dans les meilleurs conditions, je vous propose de récupérer le code de démarrage dans ce repo GitHub :
Branche startQueryApi du repo Github
Vous pourrez également comparer votre code avec mon code ici, si vous rencontrez des problèmes :
Branche endQueryApi du repo Github
Pensez bien, également, à lancer Expo, via le development build et non via Expo Go.
Pour iOS :
npm run ios
ou
Pour Android :
npm run android
Pour récupérer nos données depuis watermelonDB, nous utiliserons un useState et un useEffect. Mais, dans les prochains articles, nous verrons qu'il y a une autre manière de récupérer nos données et même que nous pourrons observer leur modification !
Pour le moment, on fait au plus simple, car nous allons nous concentrer sur les query API
Nous utiliserons useState pour afficher nos données dans une FlatList, qui se trouve dans le composant enfant <ListPost /> :
const [posts, setPosts] = useState<Post[]>([]);
<ListPost posts={posts} />
Nous utiliserons un useEffect pour fetch les données, via une fonction fetchPosts, défini dans la page :
useEffect(() => {
fetchPosts();
}, []);
const fetchPosts = async () => {
// fonction dans laquelle nous importerons nos fonctions (avec les query).
const posts = await getPosts();
// On met la data dans notre state
setPosts(posts);
};
Avant de commencer à récupérer nos données, nous allons créer des Pots, via le bouton Créer un post
.
Pour récupérer des données, nous utiliserons la méthode query qui permet de réaliser une requête sql. Par défaut, elle permet de récupérer tous les éléments de la collection sur laquelle nous effectuons la requête.
const posts = await database.get<Post>('posts').query().fetch();
};
Une variante permet de récupérer le nombre d'occurrences que nous récupérons avec la requête.
const count = await database.get<Post('posts').query().fetchCount();
};
Les requêtes via Q
sont équivalentes à ce que nous pourrions réaliser avec du javascript, en terme de performances.
Vous pouvez retrouver le tableau des équivalences, via un lien vers la documentation officielle sur les query API : Equivalences javascript
Nous pouvons spécifier des paramètres à notre requête, comme pour des requêtes sql.
A cet effet, watermelonDB met à notre disposition Q
, que nous devons importer.
import { Q } from '@nozbe/watermelondb';
Pour trier les résultats d'une requête, nous avons sortBy
que nous utiliserons avec asc
ou desc
.
Par exemple :
const posts = await database
.get<Post>('posts')
.query(Q.sortBy('title', Q.asc))
.fetch();
Nous utiliserons Q.where, avec comme paramètres, le nom de la colonne et la comparaison elle-même.
Pour tester si une condition est vrai (ou fausse), nous avons eq
.
Voici un exemple d'utilisation :
const posts = await database
.get<Post>('posts')
.query(Q.where('is_pinned', Q.eq(false)))
.fetch();
Nous pouvons utiliser une syntaxe courte, avec uniquement true ou false à la place de eq(false) ou eq(true).
Ce qui donnerait :
const posts = await database
.get<Post>('posts')
.query(Q.where('is_pinned', false))
.fetch();
Utilisation de gte :
const posts = await database
.get<Post>('posts')
.query(Q.where('likes', Q.gte(50)))
.fetch();
Utilisation de between :
const posts = await database
.get<Post>('posts')
.query(Q.where('likes', Q.between(30, 50)))
.fetch();
C'est l'équivalent des regex en javascript, ce qui nous permet de filtrer un texte en ignorant la casse (case-insensitive).
const posts = await database
.get<Post>('posts')
.query(Q.where('title', Q.like(`%${text}%`)))
.fetch();
Pour gérer les entrées utilisateurs, vous ne devez pas utiliser directement Q.like ou Q.notLike dans vos requêtes, utilisez les couplé à Q.sanitizeLikeString, pour les rendre safe.
const posts = await database
.get<Post>('posts')
.query(Q.where('title', Q.like(`%${Q.sanitizeLikeString(text)}%`)))
.fetch();
A le même effet que Q.like, mais est sensible à la casse.
const posts = await database
.get<Post>('posts')
.query(Q.where('title'.toLowerCase(), Q.includes(text)))
.fetch();
Nous pourrons combiner des requêtes en utilisant Q.and et Q.or.
Par exemple :
const posts = await database
.get<Post>('posts')
.query(Q.or(Q.where('likes', Q.gt(60)), Q.where('is_pinned', true)))
.fetch();
Si nous enchaînons uniquement des and
, nous n'avons pas besoin de le spécifier :
const posts = await database
.get<Post>('posts')
.query(Q.where('likes', Q.gte(60)), Q.where('is_pinned', true))
.fetch();