ReactJS
Data objects
Consulta Relacional em React com Parse e Back4App
10 min
consulta relacional em react usando parse introdução neste guia, você realizará consultas relacionais no parse e implementará um componente react usando essas consultas você aprenderá como configurar e consultar dados realistas usando back4app e react pré requisitos para completar este tutorial, você precisará um app react criado e https //www back4app com/docs/react/quickstart se você quiser executar o projeto de exemplo deste guia, deve configurar a https //ant design/ objetivo consultar dados relacionais armazenados no back4app a partir de um app react 1 entendendo a classe parse query qualquer operação de consulta parse usa o parse query parse query tipo de objeto, que ajudará você a recuperar dados específicos do seu banco de dados ao longo do seu app é crucial saber que um parse query parse query só será resolvido após chamar um método de recuperação (como parse query find parse query find ou parse query first parse query first ), então uma consulta pode ser configurada e vários modificadores podem ser encadeados antes de realmente serem chamados para criar um novo parse query parse query , você precisa passar como parâmetro a desejada parse object parse object subclasse, que é a que conterá os resultados da sua consulta um exemplo de consulta pode ser visto abaixo, na qual uma book book subclasse fictícia está sendo consultada 1 // this will create your query 2 let parsequery = new parse query("book"); 3 // the query will resolve only after calling this method 4 let queryresult = await parsequery find(); você pode ler mais sobre a parse query parse query classe https //parseplatform org/parse sdk js/api/master/parse query html 2 salve alguns dados no back4app vamos criar um conjunto de classes, que serão o alvo de nossas consultas neste guia as classes são autor autor , livro livro , editora editora e livraria livraria , na qual livro livro tem uma relação 1\ n com editora editora e n\ n com autor autor , e livraria livraria tem uma relação n\ n com livro livro no console js do parse, é possível executar código javascript diretamente, consultando e atualizando o conteúdo do banco de dados da sua aplicação usando os comandos do sdk js execute o código abaixo a partir do seu console js e insira os dados no back4app aqui está como o console js se parece no seu painel vá em frente e crie as classes com o seguinte conteúdo de exemplo 1 // add objects and create tables 2 // authors 3 const authora = new parse object('author'); 4 authora set('name', 'aaron writer'); 5 await authora save(); 6	 7 const authorb = new parse object('author'); 8 authorb set('name', 'beatrice novelist'); 9 await authorb save(); 10	 11 const authorc = new parse object('author'); 12 authorc set('name', 'casey columnist'); 13 await authorc save(); 14	 15 // publishers 16 const publishera = new parse object('publisher'); 17 publishera set('name', 'acacia publishings'); 18 await publishera save(); 19	 20 const publisherb = new parse object('publisher'); 21 publisherb set('name', 'birch distributions'); 22 await publisherb save(); 23	 24 // books 25 const booka = new parse object('book'); 26 booka set('title', 'a love story'); 27 booka set('publisher', publishera); 28 booka set('publishingdate', new date('05/07/1998')); 29 const bookarelation = booka relation("authors"); 30 bookarelation add(authora); 31 await booka save(); 32	 33 const bookb = new parse object('book'); 34 bookb set('title', 'benevolent elves'); 35 bookb set('publisher', publisherb); 36 bookb set('publishingdate', new date('11/31/2008')); 37 const bookbrelation = bookb relation("authors"); 38 bookbrelation add(authorb); 39 await bookb save(); 40	 41 const bookc = new parse object('book'); 42 bookc set('title', 'can you believe it?'); 43 bookc set('publisher', publisherb); 44 bookc set('publishingdate', new date('08/21/2018')); 45 const bookcrelation = bookc relation("authors"); 46 bookcrelation add(authora); 47 bookcrelation add(authorc); 48 await bookc save(); 49	 50 // bookstore 51 const bookstorea = new parse object('bookstore'); 52 bookstorea set('name', 'books of love'); 53 const bookstorearelation = bookstorea relation("books"); 54 bookstorearelation add(booka); 55 await bookstorea save(); 56	 57 const bookstoreb = new parse object('bookstore'); 58 bookstoreb set('name', 'fantasy books'); 59 const bookstorebrelation = bookstoreb relation("books"); 60 bookstorebrelation add(bookb); 61 await bookstoreb save(); 62	 63 const bookstorec = new parse object('bookstore'); 64 bookstorec set('name', 'general books'); 65 const bookstorecrelation = bookstorec relation("books"); 66 bookstorecrelation add(booka); 67 bookstorecrelation add(bookc); 68 await bookstorec save(); 69	 70 console log('success'); 3 consultar os dados agora que você preencheu todas as classes, podemos realizar algumas consultas relacionais nelas vamos começar filtrando livros livros resultados pelo editor editor , buscando aqueles que pertencem à editora “acacia publishings” (ou “editora a”) usando o método básico parse query equalto parse query equalto 1 // get publishera object 2 const publisheraquery = new parse query('publisher'); 3 publisheraquery equalto('name', 'acacia publishings'); 4 const publishera = await publisheraquery first(); 5	 6 // query books with publishera 7 const bookquery = new parse query('book'); 8 bookquery equalto('publisher', publishera); 9 let queryresults = await bookquery find(); 10	 11 // let's show the results 12 for (let result of queryresults) { 13 // you access `parse objects` attributes by using ` get` 14 console log(result get('title')); 15 }; agora vamos consultar quais livrarias livrarias contêm livros livros com data de publicação maior que 01/01/2010, usando uma consulta interna com o parse query greaterthan parse query greaterthan método e então o parse query matchesquery parse query matchesquery método 1 // create inner book query 2 const bookquery = new parse query('book'); 3 bookquery greaterthan('publishingdate', new date('01/01/2010')); 4	 5 // query bookstore using inner book query 6 const bookstorequery = new parse query('bookstore'); 7 bookstorequery matchesquery('books', bookquery); 8 let queryresults = await bookstorequery find(); 9	 10 // let's show the results 11 for (let result of queryresults) { 12 // you access `parse objects` attributes by using ` get` 13 console log(result get('name')); 14 }; agora vamos criar uma consulta relacional mais complexa, procurando por livraria livraria objetos que tenham pelo menos um livro livro escrito por autor autor “aaron writer” (ou “authora”), usando equalto equalto e matchesquery matchesquery 1 // get authora object 2 const authoraquery = new parse query('author'); 3 authoraquery equalto('name', 'aaron writer'); 4 const authora = await authoraquery first(); 5	 6 // create inner book query 7 const bookquery = new parse query('book'); 8 bookquery equalto('authors', authora); 9	 10 // query bookstore using inner book query 11 const bookstorequery = new parse query('bookstore'); 12 bookstorequery matchesquery('books', bookquery); 13 let queryresults = await bookstorequery find(); 14	 15 // let's show the results 16 for (let result of queryresults) { 17 // you access `parse objects` attributes by using ` get` 18 console log(result get('name')); 19 }; 4 consulta de um componente react vamos agora usar nossas consultas de exemplo dentro de um componente em react, com uma interface simples que possui uma lista mostrando resultados e também botões para chamar as consultas é assim que o código do componente está estruturado, note as doquery doquery funções, contendo o código de exemplo de antes javascript 1 import react, { usestate } from 'react'; 2 import parse from 'parse/dist/parse min js'; 3 import ' /app css'; 4 import { button, divider } from 'antd'; 5 import { closeoutlined, searchoutlined } from '@ant design/icons'; 6	 7 export const queryrelational = () => { 8 // state variable 9 const \[queryresults, setqueryresults] = usestate(); 10	 11 const doquerya = async function () { 12 // get publishera object 13 const publisheraquery = new parse query('publisher'); 14 publisheraquery equalto('name', 'acacia publishings'); 15 const publishera = await publisheraquery first(); 16	 17 // query books with publishera 18 const bookquery = new parse query('book'); 19 bookquery equalto('publisher', publishera); 20	 21 try { 22 let results = await bookquery find(); 23 setqueryresults(results); 24 return true; 25 } catch (error) { 26 // error can be caused by lack of internet connection 27 alert(`error! ${error message}`); 28 return false; 29 } 30 }; 31	 32 const doqueryb = async function () { 33 // create inner book query 34 const bookquery = new parse query('book'); 35 bookquery greaterthan('publishingdate', new date('01/01/2010')); 36	 37 // query bookstore using inner book query 38 const bookstorequery = new parse query('bookstore'); 39 bookstorequery matchesquery('books', bookquery); 40	 41 try { 42 let results = await bookstorequery find(); 43 setqueryresults(results); 44 return true; 45 } catch (error) { 46 // error can be caused by lack of internet connection 47 alert(`error! ${error message}`); 48 return false; 49 } 50 }; 51	 52 const doqueryc = async function () { 53 // get authora object 54 const authoraquery = new parse query('author'); 55 authoraquery equalto('name', 'aaron writer'); 56 const authora = await authoraquery first(); 57	 58 // create inner book query 59 const bookquery = new parse query('book'); 60 bookquery equalto('authors', authora); 61	 62 // query bookstore using inner book query 63 const bookstorequery = new parse query('bookstore'); 64 bookstorequery matchesquery('books', bookquery); 65	 66 try { 67 let results = await bookstorequery find(); 68 setqueryresults(results); 69 return true; 70 } catch (error) { 71 // error can be caused by lack of internet connection 72 alert(`error! ${error message}`); 73 return false; 74 } 75 }; 76	 77 const clearqueryresults = async function () { 78 setqueryresults(undefined); 79 return true; 80 }; 81	 82 return ( 83 \<div> 84 \<div classname="header"> 85 \<img 86 classname="header logo" 87 alt="back4app logo" 88 src={ 89 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png' 90 } 91 /> 92 \<p classname="header text bold">{'react on back4app'}\</p> 93 \<p classname="header text">{'relational queries'}\</p> 94 \</div> 95 \<div classname="container"> 96 \<div classname="flex between"> 97 \<h2 classname="heading">{'query list'}\</h2> 98 \<div classname="flex"> 99 \<button 100 onclick={() => doquerya()} 101 type="primary" 102 classname="heading button" 103 color={'#208aec'} 104 icon={\<searchoutlined />} 105 > 106 query a 107 \</button> 108 \<button 109 onclick={() => doqueryb()} 110 type="primary" 111 classname="heading button" 112 color={'#208aec'} 113 icon={\<searchoutlined />} 114 > 115 query b 116 \</button> 117 \<button 118 onclick={() => doqueryc()} 119 type="primary" 120 classname="heading button" 121 color={'#208aec'} 122 icon={\<searchoutlined />} 123 > 124 query c 125 \</button> 126 \<button 127 onclick={() => clearqueryresults()} 128 type="primary" 129 classname="heading button" 130 color={'#208aec'} 131 icon={\<closeoutlined />} 132 > 133 clear results 134 \</button> 135 \</div> 136 \</div> 137 \<divider /> 138 \<div classname="flex between"> 139 \<div classname="flex child"> 140 {/ query list /} 141 {queryresults !== undefined && 142 queryresults map((result, index) => ( 143 \<div classname="list item" key={`${index}`}> 144 \<p classname="list item title">{`${ 145 result get('name') !== undefined 146 ? result get('name') 147 result get('title') 148 }`}\</p> 149 \</div> 150 ))} 151 {queryresults !== undefined && queryresults length <= 0 ? ( 152 \<p>{'no results here!'}\</p> 153 ) null} 154 \</div> 155 \</div> 156 \</div> 157 \</div> 158 ); 159 }; typescript 1 import react, { usestate, fc, reactelement } from 'react'; 2 import ' /app css'; 3 import { button, divider } from 'antd'; 4 import { closeoutlined, searchoutlined } from '@ant design/icons'; 5 const parse = require('parse/dist/parse min js'); 6	 7 export const queryrelational fc<{}> = () reactelement => { 8 // state variable 9 const \[queryresults, setqueryresults] = usestate\<parse object\[]>(); 10	 11 const doquerya = async function () promise\<boolean> { 12 // get publishera object 13 const publisheraquery parse query = new parse query('publisher'); 14 publisheraquery equalto('name', 'acacia publishings'); 15 const publishera parse object | undefined = await publisheraquery first(); 16	 17 // query books with publishera 18 const bookquery parse query = new parse query('book'); 19 bookquery equalto('publisher', publishera); 20	 21 try { 22 let results parse object\[] = await bookquery find(); 23 setqueryresults(results); 24 return true; 25 } catch (error) { 26 // error can be caused by lack of internet connection 27 alert(`error! ${error message}`); 28 return false; 29 } 30 }; 31	 32 const doqueryb = async function () promise\<boolean> { 33 // create inner book query 34 const bookquery parse query = new parse query('book'); 35 bookquery greaterthan('publishingdate', new date('01/01/2010')); 36	 37 // query bookstore using inner book query 38 const bookstorequery parse query = new parse query('bookstore'); 39 bookstorequery matchesquery('books', bookquery); 40	 41 try { 42 let results parse object\[] = await bookstorequery find(); 43 setqueryresults(results); 44 return true; 45 } catch (error) { 46 // error can be caused by lack of internet connection 47 alert(`error! ${error message}`); 48 return false; 49 } 50 }; 51	 52 const doqueryc = async function () promise\<boolean> { 53 // get authora object 54 const authoraquery parse query = new parse query('author'); 55 authoraquery equalto('name', 'aaron writer'); 56 const authora parse object | undefined = await authoraquery first(); 57	 58 // create inner book query 59 const bookquery parse query = new parse query('book'); 60 bookquery equalto('authors', authora); 61	 62 // query bookstore using inner book query 63 const bookstorequery parse query = new parse query('bookstore'); 64 bookstorequery matchesquery('books', bookquery); 65	 66 try { 67 let results parse object\[] = await bookstorequery find(); 68 setqueryresults(results); 69 return true; 70 } catch (error) { 71 // error can be caused by lack of internet connection 72 alert(`error! ${error message}`); 73 return false; 74 } 75 }; 76	 77 const clearqueryresults = async function () promise\<boolean> { 78 setqueryresults(undefined); 79 return true; 80 }; 81	 82 return ( 83 \<div> 84 \<div classname="header"> 85 \<img 86 classname="header logo" 87 alt="back4app logo" 88 src={ 89 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png' 90 } 91 /> 92 \<p classname="header text bold">{'react on back4app'}\</p> 93 \<p classname="header text">{'relational queries'}\</p> 94 \</div> 95 \<div classname="container"> 96 \<div classname="flex between"> 97 \<h2 classname="heading">{'query list'}\</h2> 98 \<div classname="flex"> 99 \<button 100 onclick={() => doquerya()} 101 type="primary" 102 classname="heading button" 103 color={'#208aec'} 104 icon={\<searchoutlined />} 105 > 106 query a 107 \</button> 108 \<button 109 onclick={() => doqueryb()} 110 type="primary" 111 classname="heading button" 112 color={'#208aec'} 113 icon={\<searchoutlined />} 114 > 115 query b 116 \</button> 117 \<button 118 onclick={() => doqueryc()} 119 type="primary" 120 classname="heading button" 121 color={'#208aec'} 122 icon={\<searchoutlined />} 123 > 124 query c 125 \</button> 126 \<button 127 onclick={() => clearqueryresults()} 128 type="primary" 129 classname="heading button" 130 color={'#208aec'} 131 icon={\<closeoutlined />} 132 > 133 clear results 134 \</button> 135 \</div> 136 \</div> 137 \<divider /> 138 \<div classname="flex between"> 139 \<div classname="flex child"> 140 {/ query list /} 141 {queryresults !== undefined && 142 queryresults map((result parse object, index number) => ( 143 \<div classname="list item" key={`${index}`}> 144 \<p classname="list item title">{`${result get('name') !== undefined ? result get('name') result get('title')}`}\</p> 145 \</div> 146 ))} 147 {queryresults !== undefined && 148 queryresults length <= 0 ? ( 149 \<p>{'no results here!'}\</p> 150 ) null} 151 \</div> 152 \</div> 153 \</div> 154 \</div> 155 ); 156 }; adicione também essas classes ao seu app css app css arquivo para renderizar completamente o layout do componente app css 1 @import ' antd/dist/antd css'; 2	 3 app { 4 text align center; 5 } 6	 7 html { 8 box sizing border box; 9 outline none; 10 overflow auto; 11 } 12	 13 , 14 before, 15 after { 16 margin 0; 17 padding 0; 18 box sizing inherit; 19 } 20	 21 h1, 22 h2, 23 h3, 24 h4, 25 h5, 26 h6 { 27 margin 0; 28 font weight bold; 29 } 30	 31 p { 32 margin 0; 33 } 34	 35 body { 36 margin 0; 37 background color #fff; 38 } 39	 40 container { 41 width 100%; 42 max width 900px; 43 margin auto; 44 padding 20px 0; 45 text align left; 46 } 47	 48 header { 49 align items center; 50 padding 25px 0; 51 background color #208aec; 52 } 53	 54 header logo { 55 height 55px; 56 margin bottom 20px; 57 object fit contain; 58 } 59	 60 header text bold { 61 margin bottom 3px; 62 color rgba(255, 255, 255, 0 9); 63 font size 16px; 64 font weight bold; 65 } 66	 67 header text { 68 color rgba(255, 255, 255, 0 9); 69 font size 15px; 70 } 71	 72 heading { 73 font size 22px; 74 } 75	 76 flex { 77 display flex; 78 } 79	 80 flex between { 81 display flex; 82 justify content space between; 83 } 84	 85 flex child { 86 flex 0 0 45%; 87 } 88	 89 heading button { 90 margin left 12px; 91 } 92	 93 list item { 94 padding bottom 15px; 95 margin bottom 15px; 96 border bottom 1px solid rgba(0,0,0,0 06); 97 text align left; 98 } 99	 100 list item title { 101 color rgba(0,0,0,0 87); 102 font size 17px; 103 } é assim que o componente deve parecer após a renderização e consulta por uma das funções de consulta conclusão no final deste guia, você aprendeu como as consultas relacionais funcionam no parse e como realizá las no back4app a partir de um aplicativo react no próximo guia, você aprenderá como trabalhar com usuários no parse