ReactJS
Data objects
Relationships
15 min
relationships introduction using parse, you can store data objects establishing relations between them to model this behavior, any parseobject parseobject can be used as a value in other parseobject parseobject internally, the parse framework will store the referred to object in just one place, to maintain consistency that can give you extra power when building and running complex queries there are three main relation types one to many one to many , where one object can be related to many other objects; many to many many to many , which can create many complex relations between many objects one to one one to one , establishing direct relations between two objects and only them; there are two ways to create a one to many one to many relation in parse (recomended) the first is using the parse pointers parse pointers in child class, which is the fastest in creation and query time we will use this in this guide the second is using arrays arrays of parse pointers parse pointers in parent class which can lead to slow query times depending on their size because of this performance issue, we will use only pointers examples there are three ways to create a many to many many to many relation in parse (recomended) the first is using parse relations parse relations , which is the fastest in creation and query time we will use this in this guide the second is using arrays arrays of parse pointers parse pointers which can lead to slow query times depending on their size the third is using jointable jointable where the idea from classical database when there is a many to nany relation, we combine every objectid objectid or pointer pointer from both sides together to build a new separate table in which the relationship is tracked in this guide, you will implement a react book registration application that contains the three main kinds of data associations you will learn how to create and query data relations using back4app and react at any time, you can access this project via our github repositories to checkout the styles and complete code javascript example repository typescript example repository prerequisites to complete this tutorial, you will need a react app created and connected to back4app if you want to run this guide’s example project, you should set up the ant design ant design library goal to perform and demonstrate database relations in react using parse in a realistic scenario 1 understanding the book class since in this guide we will be using a book registration application example, you need to first understand how the object relations are laid out in this database the main object class that you’ll be using is the book book class, which will store each book entry in the registration these are the other four object classes publisher publisher book publisher name, one to many relation with book book ; genre genre book genre, one to many relation with book book note that for this example we will consider that a book can only have one genre; author author book author, many to many relation with book book , since a book can have more than one author and an author can have more than one book as well; isdb isdb book isdb identifying number, one to one relation with book book , since this number is unique for each book here is a visual representation of these database tables for simplicity, we will assume that each object class has only a string type name name attribute ( title title for the book book ), apart from any additional relational attribute step 2 creating relations before going into this step we recommend you to clone and run the react app example ( javascript example repository , typescript example repository ) this application has two main screens one responsible for listing the registered books and the other for creating new books in the book registration form, there are direct links to the other related objects and a text input field assigned to the book’s isbd value, which will be used to create the one to one relation let’s take a look at the book creation method that is called when submitting this form javascript 1 const createbook = async function () { 2 try { 3 // these values come from state variables linked to 4 // the screen form fields, retrieving the user choices 5 // as a complete parse object, when applicable; 6 const booktitlevalue = booktitle; 7 const bookisbdvalue = bookisbd; 8 // for example, bookpublisher holds the value from 9 // radiogroup field with its options being every 10 // publisher parse object instance saved on server, which is 11 // queried on screen load via useeffect 12 const bookpublisherobject = bookpublisher; 13 const bookgenreobject = bookgenre; 14 // bookauthors can be an array of parse objects, since the book 15 // may have more than one author 16 const bookauthorsobjects = bookauthors; 17 18 // creates a new parse object instance 19 let book = new parse object('book'); 20 21 // set data to parse object 22 // simple title field 23 book set('title', booktitlevalue); 24 25 // one to one (1 1) 26 // 1 1 relation, need to check for uniqueness of value before creating a new isbd object 27 let isbdquery = new parse query('isbd'); 28 isbdquery equalto('name', bookisbdvalue); 29 let isbdqueryresult = await isbdquery first(); 30 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 31 // if first returns a valid object instance, it means that there 32 // is at least one instance of isbd with the informed value 33 alert( 34 'error! there is already an isbd instance with this value!', 35 ); 36 return false; 37 } else { 38 // create a new isbd object instance to create a one to one relation on saving 39 let isbd = new parse object('isbd'); 40 isbd set('name', bookisbdvalue); 41 isbd = await isbd save(); 42 // set the new object to the new book object isbd field 43 book set('isbd', isbd); 44 } 45 46 // one to many (1\ n) 47 // one to many relations can be set in two ways 48 // add direct object to field (parse will convert to pointer on save) 49 book set('publisher', bookpublisherobject); 50 // or add pointer to field 51 book set('genre', bookgenreobject topointer()); 52 53 // many to many (n\ n) 54 // create a new relation so data can be added 55 let authorsrelation = book relation('authors'); 56 // bookauthorsobjects is an array of parse objects, 57 // you can add to relation by adding the whole array or object by object 58 authorsrelation add(bookauthorsobjects); 59 60 // after setting the values, save it on the server 61 try { 62 await book save(); 63 // success 64 alert('success!'); 65 // navigate back to home screen using react router 66 history push('/'); 67 return true; 68 } catch (error) { 69 // error can be caused by lack of internet connection 70 alert(`error! ${error message}`); 71 return false; 72 } 73 } catch (error) { 74 // error can be caused by lack of value selection 75 alert( 76 'error! make sure to select valid choices in publisher, genre and author fields!', 77 ); 78 return false; 79 } 80 }; typescript 1 const createbook = async function () promise\<boolean> { 2 try { 3 // these values come from state variables linked to 4 // the screen form fields, retrieving the user choices 5 // as a complete parse object, when applicable; 6 const booktitlevalue string = booktitle; 7 const bookisbdvalue string = bookisbd; 8 // for example, bookpublisher holds the value from 9 // radiobutton group field with its options being every 10 // publisher parse object instance saved on server, which is 11 // queried on screen load via useeffect 12 const bookpublisherobject parse object = bookpublisher; 13 const bookgenreobject parse object = bookgenre; 14 // bookauthors can be an array of parse objects, since the book 15 // may have more than one author 16 const bookauthorsobjects \[parse object] = bookauthors; 17 18 // creates a new parse object instance 19 let book parse object = new parse object('book'); 20 21 // set data to parse object 22 // simple title field 23 book set('title', booktitlevalue); 24 25 // one to one (1 1) 26 // 1 1 relation, need to check for uniqueness of value before creating a new isbd object 27 let isbdquery parse query = new parse query('isbd'); 28 isbdquery equalto('name', bookisbdvalue); 29 let isbdqueryresult parse object = await isbdquery first(); 30 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 31 // if first returns a valid object instance, it means that there 32 // is at least one instance of isbd with the informed value 33 alert( 34 'error! there is already an isbd instance with this value!', 35 ); 36 return false; 37 } else { 38 // create a new isbd object instance to create a one to one relation on saving 39 let isbd parse object = new parse object('isbd'); 40 isbd set('name', bookisbdvalue); 41 isbd = await isbd save(); 42 // set the new object to the new book object isbd field 43 book set('isbd', isbd); 44 } 45 46 // one to many (1\ n) 47 // one to many relations can be set in two ways 48 // add direct object to field (parse will convert to pointer on save) 49 book set('publisher', bookpublisherobject); 50 // or add pointer to field 51 book set('genre', bookgenreobject topointer()); 52 53 // many to many (n\ n) 54 // create a new relation so data can be added 55 let authorsrelation = book relation('authors'); 56 // bookauthorsobjects is an array of parse objects, 57 // you can add to relation by adding the whole array or object by object 58 authorsrelation add(bookauthorsobjects); 59 60 // after setting the values, save it on the server 61 try { 62 await book save(); 63 // success 64 alert('success!'); 65 // navigate back to home screen using react router 66 history push('/'); 67 return true; 68 } catch (error) { 69 // error can be caused by lack of internet connection 70 alert(`error! ${error message}`); 71 return false; 72 } 73 } catch (error) { 74 // error can be caused by lack of value selection 75 alert( 76 'error! make sure to select valid choices in publisher, genre and author fields!', 77 ); 78 return false; 79 } 80 }; let’s now look separately at how the three types of associations are done when creating the book book object one to many relation note how the bookpublisherobject bookpublisherobject and bookgenreobject bookgenreobject are set to the new book parse object parse object instance see how simple it is in parse to create a one to many relation you could either assign the target object instance or a pointer to it using the parse object set parse object set method, which takes two arguments the field name and the value to be set parse will create a pointer data type column and a direct link on your dashboard for quick access under the hood many to many relation look at how the bookauthorsobjects bookauthorsobjects are set to the new book parse object parse object instance to create a many to many relation, you first need to create a new parse object relation parse object relation and then add the related objects to it either one by one or by passing an array of parse object parse object using the parse object relation add parse object relation add method parse will create a relation type column and also a relational table on your database parse will also create a link for easy access to this new table in the field column in the dashboard one to one relation see how the bookisbdvalue bookisbdvalue is set to the new book parse objec parse objec t instance creating and saving one to one and one to many relations in parse are similar processes, in which you pass as an argument the parse object parse object instance using the parse object set parse object set method, which takes two arguments the field name and the value to be set the catch here is that, before saving, you need to enforce that there are no isbd isbd objects containing the informed isbd id string value in your database and that there are no book book objects already related to it as well the second part will always be true in this case, since you are creating a new book book object every time enforcing the isbd isbd uniqueness can be achieved by using the following highlighted query javascript 1 let isbdquery = new parse query('isbd'); 2 isbdquery equalto('name', bookisbdvalue); 3 let isbdqueryresult = await isbdquery first(); 4 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 5 // if first returns a valid object instance, it means that there 6 // is at least one instance of isbd with the informed value 7 alert( 8 'error! there is already an isbd instance with this value!', 9 ); 10 return false; 11 } typescript 1 let isbdquery parse query = new parse query('isbd'); 2 isbdquery equalto('name', bookisbdvalue); 3 let isbdqueryresult parse object = await isbdquery first(); 4 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 5 // if first returns a valid object instance, it means that there 6 // is at least one instance of isbd with the informed value 7 alert( 8 'error! there is already an isbd instance with this value!', 9 ); 10 return false; 11 } after successfully saving your objects, parse will create a pointer data type column and a direct link on your dashboard as well 3 querying relations querying related objects is pretty straightforward as much of it is handled by parse take a look at the query function in the book registers list screen and after we will highlight how each relation type is queried javascript 1 const querybooks = async function () { 2 // these values come from state variables linked to 3 // the screen query radiobutton group fields, with its options being every 4 // parse object instance saved on server from the referred class, which is 5 // queried on screen load via useeffect; these variables retrievie the user choices 6 // as a complete parse object; 7 const querypublishervalue = querypublisher; 8 const querygenrevalue = querygenre; 9 const queryauthorvalue = queryauthor; 10 const queryisbdvalue = queryisbd; 11 12 // reading parse objects is done by using parse query 13 const parsequery = new parse query('book'); 14 15 // one to many queries 16 if (querypublishervalue !== '') { 17 parsequery equalto('publisher', querypublishervalue); 18 } 19 if (querygenrevalue !== '') { 20 parsequery equalto('genre', querygenrevalue); 21 } 22 23 // one to one query 24 if (queryisbdvalue !== '') { 25 parsequery equalto('isbd', queryisbdvalue); 26 } 27 28 // many to many query 29 // in this case, we need to retrieve books related to the chosen author 30 if (queryauthorvalue !== '') { 31 parsequery equalto('authors', queryauthorvalue); 32 } 33 34 try { 35 let books = await parsequery find(); 36 // many to many objects retrieval 37 // in this example we need to get every related author parse object 38 // and add it to our query result objects 39 for (let book of books) { 40 // this query is done by creating a relation and querying it 41 let bookauthorsrelation = book relation('authors'); 42 book authorsobjects = await bookauthorsrelation query() find(); 43 } 44 setqueriedbooks(books); 45 return true; 46 } catch (error) { 47 // error can be caused by lack of internet connection 48 alert(`error! ${error message}`); 49 return false; 50 } 51 }; typescript 1 const querybooks = async function () promise\<boolean> { 2 // these values come from state variables linked to 3 // the screen query radiobutton group fields, with its options being every 4 // parse object instance saved on server from the referred class, which is 5 // queried on screen load via useeffect; these variables retrievie the user choices 6 // as a complete parse object; 7 const querypublishervalue parse object = querypublisher; 8 const querygenrevalue parse object = querygenre; 9 const queryauthorvalue parse object = queryauthor; 10 const queryisbdvalue parse object = queryisbd; 11 12 // reading parse objects is done by using parse query 13 const parsequery parse query = new parse query('book'); 14 15 // one to many queries 16 if (querypublishervalue !== '') { 17 parsequery equalto('publisher', querypublishervalue); 18 } 19 if (querygenrevalue !== '') { 20 parsequery equalto('genre', querygenrevalue); 21 } 22 23 // one to one query 24 if (queryisbdvalue !== '') { 25 parsequery equalto('isbd', queryisbdvalue); 26 } 27 28 // many to many query 29 // in this case, we need to retrieve books related to the chosen author 30 if (queryauthorvalue !== '') { 31 parsequery equalto('authors', queryauthorvalue); 32 } 33 34 try { 35 let books \[parse object] = await parsequery find(); 36 // many to many objects retrieval 37 // in this example we need to get every related author parse object 38 // and add it to our query result objects 39 for (let book of books) { 40 // this query is done by creating a relation and querying it 41 let bookauthorsrelation = book relation('authors'); 42 book authorsobjects = await bookauthorsrelation query() find(); 43 } 44 setqueriedbooks(books); 45 return true; 46 } catch (error) { 47 // error can be caused by lack of internet connection 48 alert(`error! ${error message}`); 49 return false; 50 } 51 }; one to many query to query any books related to a specific publisher or genre, you need to perform a parse query equalt parse query equalt o method passing the parse object parse object instance as the parameter after querying, parse will store inside the resulting objects the complete instances of any one to many relational fields to retrieve and show data from these object instances, you can chain the parse object get parse object get method like this bookparseobject get(('publisher') get('name') bookparseobject get(('publisher') get('name') many to many query to query any books related to a specific author, the query will also use only a parse query equalto parse query equalto method however, after querying, parse will not store parse object parse object instances from many to many relational fields, only a reference to the related class name, such as {" type" "relation", "classname" "author"} {" type" "relation", "classname" "author"} to retrieve and show data from these object instances, you need to create a relation and query it again, storing the results in an object array of your own one to one query just as before, to query any books related to a specific isbd, you need to perform a parse query equalto parse query equalto method passing the parse object parse object instance as the parameter after querying, parse will store inside the resulting objects the complete instances of any one to one relational fields, the same way that it is done with one to many relational fields conclusion at the end of this guide, you learned how to create and query relations in parse on react in the next guide, we will show you how to register users