0

I am working on a 'typeahead’ type function which will check my Database with the current typed text to provide search suggestions of users using Felgo.

Here is the link for Felgos Firebase documentation

As to not search every entry I am looking to use the startAt and limitTo for a lower data use.

However when applying the startAt my searches only return undefined, I have tried testing this by changing my startAt from a variable to explicit data but this still only returns undefined.

My function is below:

function searchUsers(searchString) {
    db.getValue("public/nameList/", {
        orderByChild: true,
        startAt: searchString,      //searchString is a variable with my .currentText to search.
        limitToFirst: 10,
        }, function(success, key, value) {
               if(success) {
               searchArr = []
               searchArr = value
               console.debug("Read user value for key", key, "from DB:", value)
               }
           })
}

I have also tried by passing my var searchString through JSON.stringify(searchString) and also return undefined!

Removing the startAt: query entirely returns the entire result of nameList as expected, but no matter how I try to implement my startAt it always returns undefined.

A sample of my nameList JSON is:

nameList: {
  "EddieLaw245" : 530343772383,
  "EddieLawrence91" : 530343772385,
  "EdwardL91" : 530343772386,
  "EdwardLaw" : 530343772384,
  "Edwardlawrence91" : 530343772380,
  "JoBrownLondon" : 530343772381,
  "KatiePrescottHair" : 543592635596,
  "Tracey-Sweeting" : 530343772382
}

So with the above example, When I type E it should remove the last 3 entries, and so on.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Ldweller
  • 327
  • 2
  • 16

1 Answers1

1

The problem is that you're specifying orderByChild: true. If we look at the documentation of that:

orderByChild: If present, the queried object will have its properties ordered by values at sub-paths defined by the value of this property. Ordering by child properties makes the filter properties startAt, endAt and equalTo filter by the child property values

It may not be immediately clear from this, but orderByChild allows you to order the results on a property value under each of those nodes. So your code tries to order the child nodes on the value of a property true, which isn't possible (and should actually generate a compile-time error in the library) as the nodes under nameList don't have any child properties of their own. They merely have a key and a value.

What you're looking for is orderByKeys, which orders the child nodes on their keys. So:

db.getValue("public/nameList/", {
    orderByKeys: true,
    startAt: searchString,
    limitToFirst: 10,
}

You'll typically also want to specify an endAt value, to ensure your type-ahead only shows values that start with the search string. If you only allow ASCII values in the keys, the simplest way to do this is:

  startAt: searchString,
  endAt: searchString + "~",

The ~ here is no magic operator, but merely the last ASCII characters. If you want to allow a broader character set, you'll need to use the last character in that character set - for example \uF7FF is the last code point for Unicode.

Update from OP Though I'm certian Franks correct with typical Firebase usage; I suspect due to the Felgo plugin I am using the full solution has a slight adjustment;

db.getValue("public/nameList/", {
    "orderByKey": true,
    "startAt": searchString,
    "endAt": searchString+"~",
    "limitToFirst": 10,
    }, function(success, key, value) {....}
})

Notes on the above - my filters/queries are surrounded by quotation marks "startAt", also instead of orderByKeys, I have used orderByKey

Ldweller
  • 327
  • 2
  • 16
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Hi Frank thanks for the answer! I've edited my code to test and my output remains the same, see below a log of all keypresses (I don't send the function until the 3rd character): `Search String: Edw Error with message: undefined Search String: Edwa Error with message: undefined Search String: Edwar Error with message: undefined Search String: Edward Error with message: undefined Search String: EdwardL Error with message: undefined Search String: EdwardLa Error with message: undefined Search String: EdwardLaw Error with message: undefined` – Ldweller Aug 11 '21 at 15:43
  • Also I initially used `orderByChild` as when simply reading the 'keys' without any filtering or queries it returned only `"nameList"` however `orderByChild` with no filtering/queries return the full JSON of the `nameList`, so I but thanks for the tip! – Ldweller Aug 11 '21 at 15:48
  • You need `orderByKeys`: true` instead of `orderByChild`. Calling `orderByChild: true` is *never* going to work, as `true` is not a valid property name. – Frank van Puffelen Aug 11 '21 at 18:16
  • Hi Frank, I understand that now thanks to your answer - however when adjusting my code with your answer (orderByKeys/ endAt +~ ect) I still return undefined with each search function. – Ldweller Aug 11 '21 at 18:19
  • I don't know qml nor Felgos, so stuck to answering what I do know about, and what certainly was wrong in your code. The only other thing I'd consider is hard-coding the search string, to rule out that you're passing a bad value in. If that doesn't solve it, I hope that somebody with more experience with the other tools can also chime in. – Frank van Puffelen Aug 11 '21 at 18:39
  • Thanks for the help, I have tried hardcoding also to no avail - i'll keep looking but thanks for the advice! – Ldweller Aug 11 '21 at 18:46
  • 1
    Hi Frank, So; I have absolutely no idea why - however, on a whim I tried placing my queries in an object like so: `orderByKeys: true, startAt: { key: searchString }, endAt: { key:searchString + "~" }, limitToFirst: 10` And it has worked? regardless - I've accepted your answer as it certainly put me on the right path, unsure if you want to edit to include the objects or not! Thanks! – Ldweller Aug 22 '21 at 08:59
  • 1
    update frank (again if you wish to edit your answer); adding quotations to my query/filters and changing orderByKeys to "orderByKey:" worked immaculately – Ldweller Aug 24 '21 at 18:49
  • Great to hear @Ldweller You should be able to propose such an edit yourself too, reducing the chances that I make mistakes in it (since I can't actually try it myself). – Frank van Puffelen Aug 24 '21 at 18:57