Make Front End Dropdown list with info.company from import { contacts } from 'wix-crm-backend';

Dear all,

  • Complete newbie here-

After interesting days of learning on the Velo resource pages, and reading the fora here.
I am still a bit stuck and would love for the community to give me a push in the right direction.

What I am trying to do is i assume simple:
Make a drop-down list on a front-end page, showing the Company name of the contacts.
Stored under info.company in the wix-crm-backend. The label should be the company name, the value of either the company name or the _ID.

Now I assume I have understood the concept of working:
A: Make a .jsw that runs on the backend > That calls for this information.
B: Import the .JSW into the front end, and use the called information

A: I have thus ( with help of the Velo resources) made a .jsw, with a Query that calls for all the information in { contacts } from ‘wix-crm-backend’, ordered: .ascending (“info.company”)
Testing it in the Console this works. Here is the Cod

Back end

import { contacts } from ‘wix-crm-backend’ ;

export function QueryContactsFunction ( ) {

return contacts . queryContacts ()
. ascending ( “info.company” )
. find ()
. then (( results ) => {
if ( results . items . length > 0 ) {
const items = results . items ;
return items ;
} else {
// Handle case where no matching items found
}
})
. catch (( error ) => {
console . error ( error );
})

Where I get stuck is what happens on the front end ( I assume).
I think I am not pointing to the correct information, or don’t understand yet how.
here is the code:

Front End.

import { QueryContactsFunction } from ‘backend/GetMemberInfo.jsw’

$w . onReady ( async () => {
$w ( “#ClientSelectDropdown” ). options =
const query = await QueryContactsFunction
. query ( “items” )
. ascending ( “info.company” )
. find ()

**const**  queryItems  =  query . items 

$w ( "#ClientSelectDropdown" ). options  =  prepareContactsForDropdown ( queryItems ,  "info.company" ) 
}) 

function prepareContactsForDropdown ( data , info . company ) {
return data . map ( item => {
return {
label : item [ info . company ],
value : item [ info . company ],
}
})
}

}

Can anyone tell me where my error is? Or what logic I did not understand yet?

Thanks

Hi,

I am interested in what you are doing.

My response, however, is more ‘best practice’ than ‘here is how to fix your code’.

Of course, ‘best practice’ can mean very different things and seems ever elusive, and as we are all continually trying to improve, it seems presumptuous to offer any – then again, you do declare yourself a ‘complete newbie’…

Since you are trying to find “where [your] error is”, I think this might help you isolate what’s going on.

In Front End :
Now, I guess all the Cool-Kids are hooked on monstrous anonymous functions for everything in javaScript. But breaking what you are doing into a discrete called functions is allowed and I believe would help:

$w.onReady(async function () {
     await onReadyCompanyNames ()
});

Then just have the function below that all by itself:

async function onReadyCompanyNames () {
    $w("#ClientSelectDropdown").options = []
    const queryItems = await queryCompanyNames()
    console.log('queryItems below')
    console.dir(queryItems)
    $w("#ClientSelectDropdown").options = await 
 prepareContactsForDropdown(queryItems, "info.company")
}

(personally, I prefix all of the function names I call in onReady() with ‘onReady’, but that’s just me)

Which implies:

async function queryCompanyNames () {
    const query = await QueryContactsFunction
    .query("items")
    .ascending("info.company")
    .find()
    
    const queryItems = query.items
    console.log('queryItems below')
    console.dir(queryItems)
    return queryItems
}

Then you already have the named function prepareContactsForDropdown(). (I am not sure, but this function not being ‘async’ may be an issue, out of habit I ‘await’-ed it’s call above. I think once you start with async-await you have to follow through with all of your calls?..)

(my code may not be perfect, but I hope the point is clear regardless)

Where you have a chunk of code that is really doing a discrete thing, why not just make it a named function… making a function a named function, to my mind, is implicit documentation and proper encapsulation.

Another reason I’ve landed on named onReady-Functions is that every time I am absolutely certain that something will only need to be done onReady(), I end up discovering that that thing needs to be accomplished somewhere else in my code, sometimes with different parameters. (when that occurs I remove the ‘onReady’ prefix, of course)

I’m guessing that I’m still inclined to named functions because javaScript was NOT my first language, but again, that’s just me.

I do like the quick-n-dirty ability to write anonymous functions. I would love to hear, or be pointed to an argument in favor of this seeming fealty to the ubiquitous anonymous function… I’d love to learn… but it is valid code to break things up into named functions and I do think it would help you isolate what is going on to break things into code blocks that can be independently tested…

Regards

  • [NOTE: The call within $w.onReady() should probably be commented out during testing. Personally, I would leave it commented out until it was perfect and create a Kludge-Button whose sole purpose is to run the commented out function until your testing is done.]