Objects
Storing Data in a Moralis Server.
Moralis.Object
Storing data on Moralis is built around Moralis.Object
. Each Moralis.Object
contains key-value pairs of JSON-compatible data. This data is schemaless, which means that you don’t need to specify ahead of time what keys exist on each Moralis.Object
. You simply set whatever key-value pairs you want, and our back-end will store them.
For example, let’s say you’re building an NFT game where the characters are monsters. A single Moralis.Object
could contain:
strength: 1024, ownerName: "Aegon", canFly: true
Keys must be alphanumeric strings. Values can be strings, numbers, booleans, or even arrays and dictionaries - anything that can be JSON-encoded.
Each Moralis.Object
is an instance of a specific subclass with a class name that you can use to distinguish different sorts of data. For example, we could call the object a LegendaryMonster
.
We recommend that you NameYourClassesLikeThis and nameYourKeysLikeThis, just to keep your code looking pretty.
Moralis.Object.extend()
To create a new subclass, use the Moralis.Object.extend
method. Any Moralis.Query
will return instances of the new class for any Moralis.Object
with the same classname. If you’re familiar with Backbone.Model
, then you already know how to use Moralis.Object
. It’s designed to be created and modified in the same ways.
You can add additional methods and properties to your subclasses of Moralis.Object
.
To create a single instance of any Moralis Object class, you can also use the Moralis.Object
constructor directly. new Moralis.Object(className)
will create a single Moralis Object with that class name.
If you’re already using ES6 in your codebase. You can subclass Moralis.Object
with the extends
keyword:
However, when using extends
, the SDK is not automatically aware of your subclass. If you want objects returned from queries to use your subclass of Moralis.Object
, you will need to register the subclass, similar to what we do on other platforms.
Similarly, you can use extends
with Moralis.User
.
In addition to queries, logIn
and signUp
will return the subclass CustomUser
.
CustomUser.logIn
and CustomUser.signUp
will return the subclass CustomUser
.
Save Objects
myObject.save()
Let’s say you want to save the Monster
described above to the Moralis Cloud. The interface is similar to a Backbone.Model
, including the save
method:
After this code runs, you will probably be wondering if anything really happened. To make sure the data was saved, you can look at the "Data Browser" in your "Moralis Dashboard". You should see something like this:
There are two things to note here:
You didn’t have to configure or set up a new class called
Monster
before running this code.Your Moralis app lazily creates this class for you when it first encounters it.
There are also a few fields you don’t need to specify that are provided as a convenience. objectId
is a unique identifier for each saved object. createdAt
and updatedAt
represent the time that each object was created and last modified in the cloud. Each of these fields is filled in by Moralis, so they don’t exist on a Moralis.Object
until a save operation has been completed.
If you prefer, you can set attributes directly in your call to save
instead.
By default, the classes you create will have no permissions set - meaning that anyone can write data into the class and read data from the class. Please see Security Docs about securing your classes and adding permissions.
By default the classes you create will have no permissions set meaning that anyone can write data into the class and read data from the class. Please see Security Docs about securing your classes and adding permissions.
SAVING NESTED OBJECTS
You may add a Moralis.Object
as the value of a property in another Moralis.Object
. By default, when you call save()
on the parent object, all nested objects will be created and/or saved as well in a batch operation. This feature makes it really easy to manage relational data as you don’t have to take care of creating the objects in any specific order.
In some scenarios, you may want to prevent this default chain save. For example, when saving a monster’s profile that has an owner property pointing to an account owned by another user to which you don’t have write access. In this case, setting the option cascadeSave
to false
may be useful:
CLOUD CODE CONTEXT
You may pass a context
dictionary that is accessible in cloud code beforeSave
and afterSave
triggers for that Moralis.Object
. This is useful if you want to condition certain operations in cloud code triggers on ephemeral information that should not be saved with the Moralis.Object
in the database. The context is ephemeral in the sense that it vanishes after the cloud code triggers for that particular Moralis.Object
as it has been executed. For example:
The context is then accessible in cloud code:
Retrieve Objects
myObject.get()
Saving data to the cloud is fun, but it’s even more fun to get that data out again.
If the Moralis.Object
has been uploaded to the server, you can use the objectId
to retrieve it using a Moralis.Query
:
To get the values out of the Moralis.Object
, use the get
method:
Alternatively, the attributes
property of the Moralis.Object
can be treated as a JavaScript object, and even destructured.
The four special reserved values are provided as properties and cannot be retrieved using the ‘get’ method nor modified with the ‘set’ method:
myObject.fetch()
If you need to refresh an object you already have with the latest data currently in the Moralis Cloud, you can call the fetch
method like so:
myObject.isDataAvailable()
If you need to check if an object has been fetched, you can call the isDataAvailable()
method:
Update Objects
myObject.set()
Updating an object is simple. Just set some new data on it and call the save method. For example:
Moralis automatically figures out which data has changed so only “dirty” fields will be sent to the Moralis Cloud. You don’t need to worry about squashing data that you didn’t intend to update.
myObject.increment()
COUNTERS
The above example contains a common use case. The strength field is a counter that we’ll need to continually update with the monster's latest energy. Using the above method works but it’s cumbersome and can lead to problems if you have multiple clients trying to update the same counter.
To help with storing counter-type data, Moralis provides methods that automatically increment (or decrement) any number field. So, the same update can be rewritten as:
You can also increment by any amount by passing in a second argument to increment
. When no amount is specified, 1 is used by default.
myObject.addUnique()
ARRAYS
To help with storing array data, there are three operations that can be used to automatically change an array associated with a given key:
add
append the given object to the end of an array field.addUnique
add the given object only if it isn’t already contained in an array field. The position of the insert is not guaranteed.remove
remove all instances of the given object from an array field.
Note that it is not currently possible to automatically add and remove items from an array in the same save. You will have to call save
in between every different kind of array operation.
Destroy Objects
myObject.destroy()
To delete an object from the cloud:
myObject.unset()
You can delete a single field from an object with the unset
method:
Please note that the use of object.set(null) to remove a field from an object is not recommended and will result in unexpected functionality.
Relational Data
Objects may have relationships with other objects. For example, in a blogging application, a Post
object may have many Comment
objects. Moralis supports all kinds of relationships:
One-to-one
One-to-many
Many-to-many.
One-to-One AND One-to-Many
One-to-one and one-to-many relationships are modelled by saving a Moralis.Object
as a value in the other object.
For example, each Comment
in a blogging app might correspond to one Post
.
To create a new Post
with a single Comment
, you could write:
Internally, Moralis will store the referred-to object in just one place, to maintain consistency. You can also link objects using just their objectId
's like so:
By default, when fetching an object, related Moralis.Object
's are not fetched. These objects’ values cannot be retrieved until they have been fetched like so:
Many-To-Many
Many-to-many relationships are modelled using Moralis.Relation
. This works similar to storing an array of Moralis.Object
's in a key, except that you don’t need to fetch all of the objects in a relation at once. In addition, this allows Moralis.Relation
to scale to many more objects than the array of Moralis.Object
approach.
For example, a User
may have many Posts
that she might like. In this case, you can store the set of Posts
that a User
likes using relation
. In order to add a Post
to the “likes” list of the User
, you can do:
const relation = myObject.relation()
You can remove a post from a Moralis.Relation
:
relation.remove()
You can call add
and remove
multiple times before calling save:
You can also pass in an array of Moralis.Object
to add
and remove
:
relation.add()
By default, the list of objects in this relation are not downloaded. You can get a list of the posts that a user likes by using the Moralis.Query
returned by query
. The code looks like:
relation.query()
If you only want a subset of the posts, you can add extra constraints to the Moralis.Query
returned by query
like this:
For more details on Moralis.Query
, please look at the Queries portion of this guide. A Moralis.Relation
behaves similar to an array of Moralis.Object
for querying purposes, so any query you can do on an array of objects, you can do on a Moralis.Relation
.
Data Types
So far we’ve used values with type String
, Number
, and Moralis.Object
. Moralis also supports Date
s and null
. You can nest JSON Object
s and JSON Array
s to store more structured data within a single Moralis.Object
. Overall, the following types are allowed for each field in your object:
String =>
String
Number =>
Number
Bool =>
bool
Array =>
JSON Array
Object =>
JSON Object
Date =>
Date
File =>
Moralis.File
Pointer => other
Moralis.Object
Relation =>
Moralis.Relation
Null =>
null
Some examples:
We do not recommend storing large pieces of binary data like images or documents on Moralis.Object
. We recommend you use Moralis.File
to store images, documents, and other types of files. You can do so by instantiating a Moralis.File
object and setting it on a field. See Files for more details.
For more information about how Moralis handles data, check out our documentation on Data.
Tutorial
Legacy UI could be present in these videos, some things might be slightly different
Last updated