Query Question (limit)

I populated a table using a moralis query and its returning the data just fine… however if there are multiple results using the same parameter I only want the last returned. I’m creating an inbox so I only want the latest object displayed from a specified user, not all of them. I tried adding aggregate-limit:

.aggregate({limit: 1})

Nothing was returning… Here’s my code:

  const { data } = useMoralisQuery("Messages", query =>
  query
    .equalTo("to", user.get("username"))
);
...
  const products = data.map(item => ({
    username: JSON.stringify(item, ['from']),
    content: JSON.stringify(item, ['content']),
    date: JSON.stringify(item, ['updatedAt'])
   }))

this is the version that works and returns all the results that you pasted here as code?
you can use:

query
    .equalTo("to", user.get("username"))
query.limit(5);

I understand the .limit function… let me rephrase:

You see the username column? You see the 2 messages from the same user ({“from”:“ethershare”})? I’m trying to return only the last object created from the name “ethershare”

how do you make it work without limit, so that it returns only the messages from that {“from”:“ethershare”} username?

Right now adding limit(1) only returns the last single object from the Entire query, thats not what I’m trying to do… this table is supposed to show ALL messages received from ALL users, however if there are multiple messages received from someone (in this case it’s ethershare) I only want to display the latest message…

Right now it’s like an email inbox where it shows literally every message (even if I received 5 in a row from the same person), but I’m trying to replicate for example how SMS/iMessage/Telegram apps only display the last message from each contact

you say that you are not able to select only the messages from a specific contract now?
how is that you choose to add {“from”:“ethershare”} for username and not ethershare or a list of usernames?

That is NOT what I am trying to communicate to you, I’ve been saying the same thing but rewording trying to make my question more clear… I used the word contact not contRact; as in contact-list saved in a phone.

Your second sentence is another issue I was going to work on as well… data.from doesn’t return anything, I tried this earlier:

  const products = data.map(item => ({
    username: data.from,
    content: data.content,
    date: data.updatedAt
   }))

This doesn’t return anything either:

  const products = data.map(item => ({
    username: JSON.parse(JSON.stringify(item, ['from'])),
    content: JSON.parse(JSON.stringify(item, ['content'])),
    date: JSON.parse(JSON.stringify(item, ['updatedAt']))
   }))

So far the code in my original post is the only thing I’ve got to work… if you have advice on that too I’m all ears…

how do you save that data in that table?
I would use something like object.set(“Username”, “ethershare”);

Everything has already been set and saved to the database… this is a Query, I’m not trying to change anything. I just want the table to only show the last message from each user, maybe it’s confusing because I’ve only received messages from ethershare (because I sent it to myself)… But right now the query is returning the entire inbox

is that a string what you save in Username column? like {“from”:“ethershare”} is a string? if yes you can do match on that exact string.

why would I do match? ethershare is literally me, I sent the message to myself… I already used .equalTo

  const { data } = useMoralisQuery("Messages", query =>
  query
    .equalTo("to", user.get("username"))
);

The query returns all of the messages sent to the logged in user

You see how the screenshot I posted shows 2 messages in a row from ethershare? I Don’t want that, if I receive multiple messages from someone I only want the last message from that contact displayed… then they will click and a modal showing the whole convo will pop up. Do you understand? I’m trying to explain a feature thats been on sms/IM applications since the 90’s

@Yomoo please maybe you will understand my question

I think that I understand your question, I don’t know how you added that data in your table in order to answer your question, you want to get latest messages that current user received from x contact, you’ll have to filter by x contact in order to do that, or to be able to identify x contact in those messages.

this is how I populated the table, it’s all strings… and not latest messages plural. I want one row (latest) for each username.

I mean in code how you saved that data in the table, in order to get the latest row you will need to filter by that contact and then to sort by Date and to get only latest row. (in case that you know the contact)

You could also use a beforeSave hook in order to insert in a different table only the latest message from a contact so that you get it faster from there.

But if those are strings, you could try:

const { data } = useMoralisQuery("Messages", query =>
  query
    .equalTo("to", user.get("username"))
  query.qualTo("Username", '{"from":"ethershare"}')
  query.limit(1)
);

only to see if it works

I ran your code… what made you put query in front of the .equalTo and .limit? That gave me errors… I also dont have value for “Username”, that was just the title of the column (to, from, content is all)

this returned the one message but I don't think this logic will work universally... the row without 'from' specified would be showing too in a perfect world


  const { data } = useMoralisQuery("Messages", query =>
  query
    .equalTo("to", user.get("username"))
    .descending('createdAt')
    .equalTo("from", "ethershare")
    .limit(1)
);

  const newMessage = () => {
    const handleClose = () => setShow(false);
    const handleShow = () => setShow(true);
      return(
        <>
            <Button className='newmessage' onClick={handleShow}>New Message</Button>

            <Modal show={show} onHide={handleClose}>
            <Modal.Header closeButton>
                <Modal.Title>New Message</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <Form>
                    <Form.Group className="mb-3" controlId="formBasicEmail">
                        <Form.Label>To:</Form.Label>
                        <Form.Control type="username" placeholder="Enter Username" onChange={ (event) => setMessageTo(event.target.value) } />
                    </Form.Group>
                    <Form.Group>
                        <Form.Label>Message:</Form.Label>
                        <Form.Control as="textarea" rows={7} onChange={ (event) => setMessage(event.target.value) } />
                    </Form.Group>
                </Form>
                {error }
            </Modal.Body>
            <Modal.Footer>
                <Button variant="secondary" onClick={handleClose}>
                Close
                </Button>
                <Button variant="primary" disabled={isSaving}onClick={async () => {await save({to: messageTo, from: user.get("username"), content: message});handleClose();}}>
                Send
                </Button>
            </Modal.Footer>
            </Modal>
    </>
  )}

I was more used with vanilla js syntax and that is why I added query in front of .equalTo.

what you mean by:

this returned the one message but I don’t think this logic will work universally… the row without ‘from’ specified would be showing too in a perfect world

I saw that you have a row where “from” was not set, but I don’t know if it was intentional or not.

Unintentional… I sent to database before I added the from: user.get("username") to save() function

To return that one I queried:

  const { data } = useMoralisQuery("Messages", query =>
  query
    .equalTo("to", user.get("username"))
    .descending('createdAt')
    .equalTo("from", )
    .limit(1)
);

I wonder what (if possible) I could substitute that works for each ‘from’ value

you mean that you would like to do something like a single query to get you latest message for each from value?

I don’t know exactly if it is possible with a single query.

1 Like