useMoralisQuery - relational example

I have a react-moralis query that looks as such:

    const {
        data: listedNfts,
    } = useMoralisQuery("ItemListed", (query) =>
        query
            .limit(9)
            .descending("tokenId")
            .skip((page - 1) * PAGE_SIZE)
    )

However, Iโ€™d like to filter out Nfts that have fired an ItemBought event, and Iโ€™m wondering how I could do that in the same hook? I can see how to do them with โ€œrawโ€ moralis here

those nfts that have fired an ItemBought event, how do you identify them now?

are they in a different table? is there a column in same table that has that information?

    const {
        data: boughtNfts,
    } = useMoralisQuery("ItemBought", (query) =>
        query
            .limit(9)
            .descending("tokenId")
            .skip((page - 1) * PAGE_SIZE)
    )

They are in a different table, you can get them like this ^

Iโ€™m thinking that you could use a third table, and update/add the rows in that table with a hook like afterSave, and this way you will have all the required data in a single table. that may be easier to query after that

Yep. This worked out great.

I ended up adding a table called ActiveItem where it is modified whenever someone buys, sells, or cancels a listing.

I added the following trigger-based functions:

Moralis.Cloud.afterSave("ItemListed", async (request) => {
    const confirmed = request.object.get("confirmed")
    if (confirmed) {
        const logger = Moralis.Cloud.getLogger()
        const ActiveItem = Moralis.Object.extend("ActiveItem")
        const activeItem = new ActiveItem()
        activeItem.set("address", request.object.get("address"))
        activeItem.set("price", request.object.get("price"))
        activeItem.set("tokenId", request.object.get("tokenId"))
        logger.info(
            `Adding Address: ${request.object.get("address")} TokenId: ${request.object.get(
                "tokenId"
            )}`
        )
        await activeItem.save()
    }
})

Moralis.Cloud.afterSave("ItemCanceled", async (request) => {
    const confirmed = request.object.get("confirmed")
    logger.info(`Marketplace | Object: ${request.object}`)
    if (confirmed) {
        const logger = Moralis.Cloud.getLogger()
        const ActiveItem = Moralis.Object.extend("ActiveItem")
        const query = new Moralis.Query(ActiveItem)
        query.equalTo("address", request.object.get("address"))
        query.equalTo("tokenId", request.object.get("tokenId"))
        logger.info(`Marketplace | Query: ${query}`)
        const canceledItem = await query.first()
        logger.info(`Marketplace | CanceledItem: ${canceledItem}`)
        if (canceledItem) {
            logger.info(`Deleting ${request.object.get("objectId")}`)
            await canceledItem.destroy()
            logger.info(
                `Deleted item with tokenId ${request.object.get(
                    "tokenId"
                )} at address ${request.object.get("address")} since it was canceled. `
            )
        } else {
            logger.info(
                `No item canceled with address: ${request.object.get(
                    "address"
                )} and tokenId: ${request.object.get("tokenId")} found.`
            )
        }
    }
})

Moralis.Cloud.afterSave("ItemBought", async (request) => {
    const confirmed = request.object.get("confirmed")
    logger.info(`Marketplace | Object: ${request.object}`)
    if (confirmed) {
        const logger = Moralis.Cloud.getLogger()
        const ActiveItem = Moralis.Object.extend("ActiveItem")
        const query = new Moralis.Query(ActiveItem)
        query.equalTo("address", request.object.get("address"))
        query.equalTo("tokenId", request.object.get("tokenId"))
        logger.info(`Marketplace | Query: ${query}`)
        const canceledItem = await query.first()
        logger.info(`Marketplace | CanceledItem: ${canceledItem}`)
        if (canceledItem) {
            logger.info(`Deleting ${request.object.get("objectId")}`)
            await canceledItem.destroy()
            logger.info(
                `Deleted item with tokenId ${request.object.get(
                    "tokenId"
                )} at address ${request.object.get(
                    "address"
                )} from ActiveItem table since it was bought.`
            )
        } else {
            logger.info(
                `No item bought with address: ${request.object.get(
                    "address"
                )} and tokenId: ${request.object.get("tokenId")} found`
            )
        }
    }
})

And the database is updating perfectly, and the query is simple with:

    const PAGE_SIZE = 9
    const [page, setPage] = useState(1)
    const { data: listedNfts, isFetching: fetchingListedNfts } = useMoralisQuery(
        "ActiveItem",
        (query) =>
            query
                .limit(PAGE_SIZE)
                .descending("tokenId")
                .skip((page - 1) * PAGE_SIZE)
    )
1 Like