In this guide, you will perform basic queries in Parse and implement a React component using these queries. You will learn how to set up and query realistic data using Back4App and React.
If you want to run this guide’s example project, you should set up the Ant Design library.
Goal
Query data stored on Back4App from a React application.
1 - Understanding the Parse.Query class
Any Parse query operation uses the Parse.Query object type, which will help you retrieve specific data from your database throughout your app. It is crucial to know that a Parse.Query will only resolve after calling a retrieve method (like Parse.Query.find or Parse.Query.get), so a query can be set up and several modifiers can be chained before actually being called.
To create a new Parse.Query, you need to pass as a parameter the desired Parse.Object subclass, which is the one that will contain your query results. An example query can be seen below, in which a fictional Profile subclass is being queried.
JS
1// This will create your query2let parseQuery =newParse.Query("Profile");3// The query will resolve only after calling this method4let queryResult =await parseQuery.find();
Let’s create a Profile class, which will be the target of our queries in this guide. On Parse JS Console is possible to run JavaScript code directly, querying and updating your application database contents using the JS SDK commands. Run the code below from your JS Console and insert the data on Back4App.
Here is how the JS Console looks like in your dashboard:
Go ahead and create the user Profile class with the following example content:
Now that you have a populated class, we can now perform some basic queries in it. Let’s begin by filtering Profile results by name, which is a string type field, searching for values that contain the name Adam using the Parse.Query.contains method:
JS
1// Create your query2let parseQuery =newParse.Query('Profile');34// `contains` is a basic query method that checks if string field5// contains a specific substring6 parseQuery.contains('name','Adam');78// The query will resolve only after calling this method, retrieving9// an array of `Parse.Objects`10let queryResults =await parseQuery.find();1112// Let's show the results13for(let result of queryResults){14// You access `Parse.Objects` attributes by using `.get`15 console.log(result.get('name'));16};
Let’s now query by the number type field friendCount by using another common query method, Parse.Query.greaterThan. In this case, we want user Profiles in which the friend count is greater than 20.
JS
1// Create your query2let parseQuery =newParse.Query('Profile');34// `greaterThan` is a basic query method that does what it5// says on the tin6 parseQuery.greaterThan('friendCount',20);78// The query will resolve only after calling this method, retrieving9// an array of `Parse.Objects`10let queryResults =await parseQuery.find();1112// Let's show the results13for(let result of queryResults){14// You access `Parse.Objects` attributes by using `.get`15 console.log(`name: ${result.get('name')}, friend count: ${result.get('friendCount')}`);16};
Other recurring query methods are Parse.Query.ascending and Parse.Query.descending, responsible for ordering your queries. This ordering can be done in most data types, so let’s order a query by the date field birthDay by the youngest.
JS
1// Create your query2let parseQuery =newParse.Query('Profile');34// `descending` and `ascending` can and should be chained5// with other query methods to improve your queries6 parseQuery.descending('birthDay');78// The query will resolve only after calling this method, retrieving9// an array of `Parse.Objects`10let queryResults =await parseQuery.find();1112// Let's show the results13for(let result of queryResults){14// You access `Parse.Objects` attributes by using `.get`15 console.log(`name: ${result.get('name')}, birthday: ${result.get('birthDay')}`);16};
As stated here before, you can and should chain query methods to achieve more refined results. Let’s then combine the previous examples in a single query request:
JS
1// Create your query2let parseQuery =newParse.Query('Profile');34 parseQuery.contains('name','Adam');5 parseQuery.greaterThan('friendCount',20);6 parseQuery.descending('birthDay');78// The query will resolve only after calling this method, retrieving9// an array of `Parse.Objects`10let queryResults =await parseQuery.find();1112// Let's show the results13for(let result of queryResults){14// You access `Parse.Objects` attributes by using `.get`15 console.log(`name: ${result.get('name')}, friend count: ${result.get('friendCount')}, birthday: ${result.get('birthDay')}`);16};
4 - Query from a React component
Let’s now use our example queries inside a component in React, with a simple interface having a list showing results and also 4 buttons for calling the queries. This is how the component code is laid out, note the doQuery functions, containing the example code form before.
JavaScript
TypeScript
1import React,{ useState }from'react';2import Parse from'parse/dist/parse.min.js';3import'./App.css';4import{ Button, Divider }from'antd';5import{ CloseOutlined, SearchOutlined }from'@ant-design/icons';67exportconstQueryBasic=()=>{8// State variable9const[queryResults, setQueryResults]=useState();1011constdoQueryByName=asyncfunction(){12// Create our Parse.Query instance so methods can be chained13// Reading parse objects is done by using Parse.Query14const parseQuery =newParse.Query('Profile');1516// `contains` is a basic query method that checks if string field17// contains a specific substring18 parseQuery.contains('name','Adam');1920try{21let profiles =await parseQuery.find();22setQueryResults(profiles);23returntrue;24}catch(error){25// Error can be caused by lack of Internet connection26alert(`Error! ${error.message}`);27returnfalse;28}29};3031constdoQueryByFriendCount=asyncfunction(){32// Create our Parse.Query instance so methods can be chained33// Reading parse objects is done by using Parse.Query34const parseQuery =newParse.Query('Profile');3536// `greaterThan` is a basic query method that does what it37// says on the tin38 parseQuery.greaterThan('friendCount',20);3940try{41let profiles =await parseQuery.find();42setQueryResults(profiles);43returntrue;44}catch(error){45// Error can be caused by lack of Internet connection46alert(`Error! ${error.message}`);47returnfalse;48}49};5051constdoQueryByOrdering=asyncfunction(){52// Create our Parse.Query instance so methods can be chained53// Reading parse objects is done by using Parse.Query54const parseQuery =newParse.Query('Profile');5556// `descending` and `ascending` can and should be chained57// with other query methods to improve your queries58 parseQuery.descending('birthDay');5960try{61let profiles =await parseQuery.find();62setQueryResults(profiles);63returntrue;64}catch(error){65// Error can be caused by lack of Internet connection66alert(`Error! ${error.message}`);67returnfalse;68}69};7071constdoQueryByAll=asyncfunction(){72// Create our Parse.Query instance so methods can be chained73// Reading parse objects is done by using Parse.Query74const parseQuery =newParse.Query('Profile');7576 parseQuery.contains('name','Adam');77 parseQuery.greaterThan('friendCount',20);78 parseQuery.descending('birthDay');7980try{81let profiles =await parseQuery.find();82setQueryResults(profiles);83returntrue;84}catch(error){85// Error can be caused by lack of Internet connection86alert(`Error! ${error.message}`);87returnfalse;88}89};9091constclearQueryResults=asyncfunction(){92setQueryResults(undefined);93returntrue;94};9596return(97<div>98<div className="header">99<img
100 className="header_logo"101 alt="Back4App Logo"102 src={103'https://blog.back4app.com/wp-content/uploads/2019/05/back4app-white-logo-500px.png'104}105/>106<p className="header_text_bold">{'React on Back4App'}</p>107<p className="header_text">{'Basic Queries'}</p>108</div>109<div className="container">110<div className="flex_between">111<h2 className="heading">{'Query List'}</h2>112<div className="flex">113<Button
114 onClick={()=>doQueryByName()}115 type="primary"116 className="heading_button"117 color={'#208AEC'}118 icon={<SearchOutlined />}119>120BYNAME121</Button>122<Button
123 onClick={()=>doQueryByFriendCount()}124 type="primary"125 className="heading_button"126 color={'#208AEC'}127 icon={<SearchOutlined />}128>129BYFRIENDCOUNT130</Button>131<Button
132 onClick={()=>doQueryByOrdering()}133 type="primary"134 className="heading_button"135 color={'#208AEC'}136 icon={<SearchOutlined />}137>138BYORDERING139</Button>140<Button
141 onClick={()=>doQueryByAll()}142 type="primary"143 className="heading_button"144 color={'#208AEC'}145 icon={<SearchOutlined />}146>147BYALL148</Button>149<Button
150 onClick={()=>clearQueryResults()}151 type="primary"152 className="heading_button"153 color={'#208AEC'}154 icon={<CloseOutlined />}155>156CLEAR157</Button>158</div>159</div>160<Divider />161<div className="flex_between">162<div className="flex_child">163{/* Query list */}164{queryResults !==undefined&&165 queryResults.map((profile, index)=>(166<div className="list_item" key={`${index}`}>167<p className="list_item_title">{`${profile.get('name')}`}</p>168<p className="list_item_description">{`Friend count: ${profile.get(169'friendCount'170)}, Birthday: ${profile.get('birthDay')}`}</p>171</div>172))}173{queryResults !==undefined&& queryResults.length <=0?(174<p>{'No results here!'}</p>175):null}176</div>177</div>178</div>179</div>180);181};
Also append these classes to your App.css file to properly render all the interface elements:
This is how the component should look like after rendering and querying by all the query functions:
Conclusion
At the end of this guide, you learned how basic data queries work on Parse and how to perform them on Back4App from a React App. In the next guide, you will explore the Parse.Query full potential using all the methods available on this class.